我想通過OpenCV將視頻圖像疊加到傳入的網絡攝像頭流上。作爲第一步,我試圖將傳入的視頻從網絡攝像頭/dev/video0
流式傳輸到/dev/video1
(v4l2loopback)的虛擬視頻設備。不幸的是,我無法將網絡攝像頭流轉發到v4l2loopback設備。無法將網絡攝像頭視頻路由到Linux上的虛擬視頻設備(通過OpenCV)
我發現這個帖子:How to write/pipe to a virtual webcam created by V4L2loopback module?,但那裏的鏈接並沒有真正幫助我。
從網絡攝像頭獲取並觀看流可以很好地與OpenCV頁面中的一些小演示代碼一起使用。以及來自v4l2loopback頁面的示例代碼,例如,播放靜態視頻文件到/dev/video1
效果很好。我可以看視頻當我連接VLC /dev/video1
我已經讀過,必須通過常規Linux驅動程序命令(打開,ioctl,寫等)來控制v4l2loopback設備。所以OpenCV中沒有包裝類來寫入回送設備。我的攝像頭以640x480流媒體和MJPG。有趣的是,我可以通過VLC連接到回送設備,當按下播放按鈕時,我可以看到正確的分辨率,編解碼器和FPS。進度條上的時間計數器也開始運行。但屏幕仍然是黑色的(帶有VLC標誌)。
什麼我大致做的是這個(BTW:代碼可能無法編譯...不想在這裏雜亂的一切...讓我知道,如果你需要更多的細節):
int main (int argc, char **argv) {
cv::VideoCapture cap;
struct v4l2_format vid_format;
size_t framesize = 640 * 480 * 3; // 3 Bytes per pixel
__u8 *buffer = null;
int fd = null;
cap.open ("/dev/video0");
fd = open ("/dev/video1", O_RDWR);
memset (&vid_format, 0, sizeof(vid_format));
vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
vid_format.fmt.pix.width = cap.get(CV_CAP_PROP_FRAME_WIDTH);
vid_format.fmt.pix.height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
vid_format.fmt.pix.pixelformat = { 'M', 'J', 'P', 'G' };
vid_format.fmt.pix.sizeimage = framesize;
vid_format.fmt.pix.field = V4L2_FIELD_NONE;
vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
ioctl (fd, VIDIOC_S_FMT, &vid_format);
buffer = (__u8*) malloc (sizeof(__u8) *framesize);
memset (buffer, 0, framesize);
for(;;) {
cv::Mat frame;
cap >> frame;
write (fd, &frame.data, framesize);
}
}
如果有人能夠給我一個提示,我需要如何轉換wecam數據才能被VLC接受,那將會非常棒。
我不是完全熟悉V4L2,但是當將像素格式設置爲MJPEG時,您應該編寫MJPEG編碼幀而不是原始BGR像素數據? –
確實這是一個很好的問題。我也不是很熟悉所有這些(相當混亂)pixelformat,colorspace等東西。我試圖深入一點,但這個人殺了我:https://wiki.videolan.org/YUV/ – Bernd