0

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 データを変換する方法を誰かが教えてくれたら、本当に素晴らしいことです。

4

1 に答える 1