OPENCV 不能同时读取 2 个视频帧

Posted

技术标签:

【中文标题】OPENCV 不能同时读取 2 个视频帧【英文标题】:OPENCV cannot read 2 video frames simultaneously 【发布时间】:2013-07-13 05:58:58 【问题描述】:

我已经写了这段代码

while (true)

    cv::Mat frame1,frame2,dst,temp;
    if (!input_video.read(frame1))
    
        fprintf(stderr, "Video has Finished .\n");
        getchar();
        return -1;
    
    if (!input_video.read(frame2))
    
        fprintf(stderr, "Video has Finished .\n");
        getchar();
        return -1;
    
    cv::cvtColor(frame1,frame1,CV_RGB2GRAY) ;
    cv::cvtColor(frame2,frame2,CV_RGB2GRAY) ;
    cv::subtract(frame2,frame1,dst);
    cv::imshow("F1",frame1);
    cv::imshow("F2",frame2);
    cv::imshow("dst",dst);
    cv::waitKey();
       

当我正在阅读视频(不是来自相机,而是来自我的硬盘的视频)时,frame1,frame2 是相同的!!!

我不知道为什么“读取”方法会为 frame2 返回相同的帧?所以减去的图像总是一张空的图片!!!

我应该为同时读取连续帧做一些特别的事情吗? 例如,每次我想阅读另一个框架时,使用这条线来到达那个框架:

      input_video.set(CV_CAP_PROP_POS_FRAMES,current_frame+1);

如果是这样,还有其他方法不这样做吗?!

谢谢

【问题讨论】:

***.com/q/11469281/2065121 是的,我已经读过,但答案对我不起作用!我的意思是在这段代码中结果总是为零(即使是关键帧!!!)似乎 frame1,frame2 总是相同的...... 【参考方案1】:

函数input_video.read() 不会在您每次调用它时创建新对象,而是返回一个指向cv::VideoCapture 内部缓冲区的指针。对于这种情况,如果将第一帧复制到 cv::Mat 对象,问题就解决了:

while (true)

    cv::Mat frame,frame1,frame2,dst,temp;
    if (!input_video.read(frame))
    
        fprintf(stderr, "Video has Finished .\n");
        getchar();
        return -1;
    
    frame.assignTo(frame1);
    if (!input_video.read(frame))
    
        fprintf(stderr, "Video has Finished .\n");
        getchar();
        return -1;
    
    frame.assignTo(frame2);
    cv::cvtColor(frame1,frame1,CV_RGB2GRAY) ;
    cv::cvtColor(frame2,frame2,CV_RGB2GRAY) ;
    cv::subtract(frame2,frame1,dst);
    cv::imshow("F1",frame1);
    cv::imshow("F2",frame2);
    cv::imshow("dst",dst);
    cv::waitKey();
       

【讨论】:

你错过放一个frame.assignTo(frame2);在我们读取 frame2 之后在您的代码中?,因为我们在视频帧中循环,在下一次迭代中可能会发生我们读取 frame2 而不是 frame1 ?! 我更改了它,但不是因为这个原因,因为在下一行中,'cv::cvtColor(frame2,frame2,CV_RGB2GRAY)' 修改了 'frame2' 的内容。 +1 & 接受答案,你的意思是每次我读一帧我都应该对其进行一些计算,然后再读另一个,所以这使得“读取”方法可以读取另一个框架? 不,方法 cv::VideoCapture::read() 每次调用时都会抓取下一帧,但它不会为每一帧创建新的 cv::Mat 并且只写入新帧内容进入 cv::VideoCapture 的内部缓冲区并将指针传递给您,因此每次调用 read() 方法时内容都会发生变化,您也不应该修改或释放它们。实际上,在您的代码中,frame1 和 frame2 具有指向 cv::VideoCapture 内部缓冲区的相同地址,因此您可以看到两个帧彼此相似。

以上是关于OPENCV 不能同时读取 2 个视频帧的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV利用Flask+Python+OpenCV实现摄像头读取图像帧网页视频流

使用 Opencv 加速从摄像头读取视频帧

使用 OpenCV 将视频帧读取到指定的指针(C++)

从两个视频源读取帧不同步 |开放式CV

Python之OpenCV读取视频抽帧保存

matlab与opencv读取同一帧视频时会得到不同的像素值