我一直在用C ++编写来自OpenCV的管道视频。我尝试在从OpenCV处理到命名管道之后管理图像,最终目标是使用带有VLC或NodeJS服务器的Web服务器重新发布流。
我遇到的问题是OpenCV的输出似乎没有正确处理。视频总是有伪影,即使它应该是原始视频。
int main(int argc, char** argv)
{
VideoCapture camera(argv[1]);
float fps = 15;
// VLC raw video
printf("Run command:\n\ncat /tmp/myfifo | cvlc --demux=rawvideo --rawvid-fps=%4.2f --rawvid-width=%.0f --rawvid-height=%.0f --rawvid-chroma=RV24 - --sout \"#transcode{vcodec=h264,vb=200,fps=30,width=320,height=240}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=:8081/stream.flv}\""
,fps
,camera.get(CV_CAP_PROP_FRAME_WIDTH)
,camera.get(CV_CAP_PROP_FRAME_HEIGHT)
);
// ffplay raw video
printf("Run command:\n\ncat /tmp/myfifo | ffplay -f rawvideo -pixel_format bgr24 -video_size %.0fx%.0f -framerate %4.2f -i pipe:"
,camera.get(CV_CAP_PROP_FRAME_WIDTH)
,camera.get(CV_CAP_PROP_FRAME_HEIGHT)
,fps
);
int fd;
int status;
char const * myFIFO = "/tmp/myfifo";
if ((status = mkfifo(myFIFO, 0666)) < 0) {
// printf("Fifo mkfifo error: %s\n", strerror(errno));
// exit(EXIT_FAILURE);
} else {
cout << "Made a named pipe at: " << myFIFO << endl;
}
cout << "\n\nHit any key to continue after running one of the previously listed commands..." << endl;
cin.get();
if ((fd = open(myFIFO,O_WRONLY|O_NONBLOCK)) < 0) {
printf("Fifo open error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
while (true)
{
if (waitKey(1) > 0)
{
break;
}
Mat colorImage;
camera >> colorImage;
// method: named pipe as matrix writes data to the named pipe, but image has glitch
size_t bytes = colorImage.total() * colorImage.elemSize();
if (write(fd, colorImage.data, bytes) < 0) {
printf("Error in write: %s \n", strerror(errno));
}
}
close(fd);
exit(EXIT_SUCCESS);
}
答案 0 :(得分:3)
如果您从O_NONBLOCK
电话中移除open()
,它在我的网站上运行良好。
此外,而不是使用:
cat /tmp/myfifo | ffplay .... -i pipe:
你可以简单地使用:
ffplay ... -i /tmp/myfifo
答案 1 :(得分:0)
#include <io.h>
#include <fcntl.h>
.....
_setmode(_fileno(stdout), _O_BINARY);
.....
cv::cvtColor(frame, frame, CV_BGR2RGBA);
for (int i = 0; i < frame.rows; ++i) {
uchar* ptr = frame.data + i * 4 * frame.cols;
for (int j = 0; j < frame.cols * 4; ++j) {
std::cout.write((const char*)(ptr + j), 1);
}
}
your.exe | ffplay -an -f rawvideo -vcodec rawvideo -pixel_format bgr32 -video_size 640x480 -i -