OpenCV を介して着信 Web カメラ ストリームにビデオ オーバーレイを配置したいと考えています。最初のステップとして、受信ビデオを Web カメラから(v4l2loopback)/dev/video0
の仮想ビデオ デバイスにストリーミングしようとしています。/dev/video1
残念ながら、ウェブカメラ ストリームを v4l2loopback デバイスに転送できません。
このスレッドを見つけました: V4L2loopback モジュールによって作成された仮想 Web カメラに書き込み/パイプする方法は? しかし、そこにあるリンクは本当に役に立ちませんでした。
Web カメラからのストリームの取得と視聴は、OpenCV ページの小さなデモ コードでうまく機能します。v4l2loopback ページのサンプル コードと同様に、たとえば静的なビデオ ファイルを再生して/dev/video1
うまく動作します。VLCを接続するとビデオを見ることができます/dev/video1
v4l2loopback デバイスは、通常の Linux ドライバー コマンド (open、ioctl、write など) で制御する必要があることを既に読みました。そのため、ループバック デバイスに書き込むための OpenCV 内からのラッパー クラスはありません。私のウェブカメラは 640x480 で MJPG としてストリーミングします。興味深いのは、VLC を使用してループバック デバイスに接続できることです。再生を押すと、正しい解像度、コーデック、および FPS が表示されます。プログレスバーのタイムカウンターも動き始めます。ただし、画面は黒いままです (VLC ロゴ付き)。
私が大まかにやっていることはこれです(ところで:コードはコンパイルされないかもしれません...ここですべてを混乱させたくありませんでした...詳細が必要な場合はお知らせください):
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 );
}
}
VLC で受け入れられるようにするために wecam データを変換する方法を誰かが教えてくれたら、本当に素晴らしいことです。