【问题标题】:OPENCV cannot read 2 video frames simultaneouslyOPENCV 不能同时读取 2 个视频帧
【发布时间】: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);

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

谢谢

【问题讨论】:

  • 是的,我已经读过,但答案对我不起作用!我的意思是在这段代码中结果总是为零(即使是关键帧!!!)似乎 frame1,frame2 总是相同的......

标签: opencv image-processing computer-vision


【解决方案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 内部缓冲区的相同地址,因此您可以看到两个帧彼此相似。
猜你喜欢
  • 1970-01-01
  • 2013-11-08
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 2016-02-13
相关资源
最近更新 更多