gpt4 book ai didi

c++ - 由于捕获缓冲区,OpenCV VideoCapture 滞后

转载 作者:IT老高 更新时间:2023-10-28 22:10:08 45 4
gpt4 key购买 nike

我正在通过提供 mjpeg 流的网络摄像头捕捉视频。我在工作线程中进行了视频捕获。我这样开始捕获:

const std::string videoStreamAddress = "http://192.168.1.173:80/live/0/mjpeg.jpg?x.mjpeg";
qDebug() << "start";
cap.open(videoStreamAddress);
qDebug() << "really started";
cap.set(CV_CAP_PROP_FRAME_WIDTH, 720);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 576);

摄像头以 20fps 的速度输入视频流。但如果我像这样以 20fps 的速度阅读:

if (!cap.isOpened()) return;

Mat frame;
cap >> frame; // get a new frame from camera
mutex.lock();

m_imageFrame = frame;
mutex.unlock();

然后会有 3 秒以上的延迟。原因是捕获的视频首先存储在缓冲区中。当我第一次启动相机时,缓冲区被累积但我没有读取帧。所以如果我从缓冲区读取它总是给我旧帧。我现在唯一的解决方案是以 30fps 的速度读取缓冲区,这样它会快速清理缓冲区并且不会出现更严重的延迟。

是否有任何其他可能的解决方案,以便我可以在每次启动相机时手动清洁/冲洗缓冲区?

最佳答案

OpenCV 解决方案

根据this源,您可以设置 cv::VideoCapture 对象的缓冲区大小。

cv::VideoCapture cap;
cap.set(CV_CAP_PROP_BUFFERSIZE, 3); // internal buffer will now store only 3 frames

// rest of your code...

但是有一个重要的限制:

CV_CAP_PROP_BUFFERSIZE Amount of frames stored in internal buffer memory (note: only supported by DC1394 v 2.x backend currently)

评论更新。在较新版本的 OpenCV (3.4+) 中,限制似乎消失了,代码使用范围枚举:

cv::VideoCapture cap;
cap.set(cv::CAP_PROP_BUFFERSIZE, 3);

解决方法 1

如果解决方案不起作用,请查看 this post这解释了如何解决这个问题。

简而言之:查询一帧所需的时间是衡量的;如果它太低,则意味着该帧是从缓冲区中读取的并且可以被丢弃。继续查询帧,直到测量的时间超过某个限制。发生这种情况时,缓冲区为空并且返回的帧是最新的。

(链接帖子上的答案显示:从缓冲区返回帧大约需要返回最新帧的时间的 1/8。当然,您的里程可能会有所不同!)


解决方法 2

一个不同的解决方案,灵感来自 this post,是创建第三个线程,高速连续抓取帧以保持缓冲区为空。此线程应使用 cv::VideoCapture.grab()以避免开销。

您可以使用简单的自旋锁在真正的工作线程和第三个线程之间同步阅读帧。

关于c++ - 由于捕获缓冲区,OpenCV VideoCapture 滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30032063/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com