我正在通过网络摄像头捕获视频,该网络摄像头提供了一个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);
Run Code Online (Sandbox Code Playgroud)
摄像机以20fps的速度输入流.但是,如果我像这样以20fps读取:
if (!cap.isOpened()) return;
Mat frame;
cap >> frame; // get a new frame from camera
mutex.lock();
m_imageFrame = frame;
mutex.unlock();
Run Code Online (Sandbox Code Playgroud)
然后有3秒多的延迟.原因是捕获的视频首先存储在缓冲区中.当我第一次启动摄像机时,缓冲区被累积但我没有读出帧.所以如果我从缓冲区读取它总是给我旧帧.我现在唯一的解决方案是以30fps的速度读取缓冲区,这样它就可以快速清理缓冲区并且没有更严重的延迟.
有没有其他可能的解决方案,以便每次启动相机时我都可以手动清理/刷新缓冲区?
Maa*_*lis 27
根据此源,您可以设置cv::VideoCapture对象的缓冲区大小.
cv::VideoCapture cap;
cap.set(CV_CAP_PROP_BUFFERSIZE, 3); // internal buffer will now store only 3 frames
// rest of your code...
Run Code Online (Sandbox Code Playgroud)
但是有一个重要的限制:
CV_CAP_PROP_BUFFERSIZE存储在内部缓冲存储器中的帧数(注意:目前仅支持DC1394 v 2.x后端)
如果解决方案不起作用,请查看此帖子,解释如何解决问题.
简而言之:测量查询框架所需的时间; 如果它太低,则表示从缓冲区读取帧并可以丢弃.继续查询帧,直到测量的时间超过一定限度.发生这种情况时,缓冲区为空,返回的帧是最新的.
(链接帖子上的答案显示:从缓冲区返回一个帧大约需要返回最新帧的1/8.当然,你的里程可能会有所不同!)
受这篇文章启发的另一个解决方案是创建第三个线程,以高速连续抓取帧以保持缓冲区为空.这个线程应该使用cv::VideoCapture.grab()以避免开销.
您可以使用简单的自旋锁来同步实际工作线程和第三个线程之间的读取帧.
伙计们,这是非常愚蠢和讨厌的解决方案,但是由于某些原因,被接受的答案并没有帮助我。(python中的代码,但本质很清楚)
# vcap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
data = np.zeros((1140, 2560))
image = plt.imshow(data)
while True:
vcap = cv2.VideoCapture("rtsp://admin:@192.168.3.231")
ret, frame = vcap.read()
image.set_data(frame)
plt.pause(0.5) # any other consuming operation
vcap.release()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38814 次 |
| 最近记录: |