gpt4 book ai didi

c++ - 使用 OpenCV 显示流有时会收到一个空帧并卡住

转载 作者:太空宇宙 更新时间:2023-11-03 22:36:37 24 4
gpt4 key购买 nike

我尝试使用 OpenCV (C++) 从 IP 摄像机读取和显示视频流。有时应用程序会卡住几秒钟,然后报告收到一个空帧。我正在寻找一种可能性来删除空帧并以视频不会卡住几秒钟的方式读取下一帧。

我使用下面的简单示例代码并尝试在出现空帧时重新读取下一帧。视频开始正​​常运行,但一段时间后它卡住了几秒钟。我在 VLC 媒体播放器中打开流,它运行流畅。我尝试了不同的方式来读取下一帧:例如 cap.read(frame);而不是 cap >> frame;我还尝试更改 waitKey 中的延迟,但结果始终相同。我不想使用 tcp(在流地址末尾插入 ?tcp),因为在最终应用程序中我不能容忍大的延迟。

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main(){

string filename = "rtsp://[myStreamIP]:554/stream.mjpeg"
VideoCapture cap(filename);

if(!cap.isOpened()){
return 1;
}

int frameNumber = 0;
while(cap.isOpened()){

Mat frame;
cap >> frame;
frameNumber++;

while (frame.empty()){
cout << "empty frame" << "-";
cap >> frame;

}

cout << frameNumber << "-";
imshow( "Frame", frame );
waitKey(1);

}

cap.release();
destroyAllWindows();
return 0;
}

我得到的输出看起来像这样:

1-2-...-123-[几秒钟过去了,没有任何反应,视频卡住]-空帧-124-125-...

当我必须多次尝试重新读取帧时,我会理解一定的延迟(仍然小得多),但我不明白为什么延迟出现在输出中第一次“空帧”之前。

最佳答案

我认为在循环中查找空帧不是一个好习惯,我宁愿使用 if else 语句,但我认为这不是问题所在:

Mat frame;
while(cap.isOpened()){

cap >> frame;
frameNumber++;

if(frame.empty()){
cout << "empty frame" << "-";
continue;
}

cout << frameNumber << "-";
imshow( "Frame", frame );
waitKey(1);
}

并在 while 循环外声明你的 Mat frame,这样你就可以重用相同的内存空间。

编辑:
在阅读 opencv doc 时您可以看到读取调用是对 grab() 和 retrieve() 的组合调用。其中 retrieve() 是“慢”函数,它在 cv::Mat 中写入你的图片,而 grab() 只是抓取下一张图片并返回一个 bool 值,如果有图片或没有。也许这样的事情可行:

Mat frame;
while(cap.isOpened()){

if(!cap.grab()){
cout << "empty frame" << "-";
continue;
}

frame = cap.retrieve();
frameNumber++;

cout << frameNumber << "-";
imshow( "Frame", frame );
waitKey(1);
}

关于c++ - 使用 OpenCV 显示流有时会收到一个空帧并卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57767336/

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