OpenCV FFMPEG RTSP 相机馈送错误
Posted
技术标签:
【中文标题】OpenCV FFMPEG RTSP 相机馈送错误【英文标题】:OpenCV FFMPEG RTSP Camera Feed Errors 【发布时间】:2020-09-24 13:55:02 【问题描述】:从 rtsp 相机源中保存帧时,我会随机收到这些错误。错误发生在不同的时间,通常在保存 100-200 张图像之后,并且错误本身并不总是完全相同。它们会导致错误发生时保存的图像失真到完全灰色或包含失真像素。
#Frame_142 - [hevc @ 0c3bf800] The cu_qp_delta 29 is outside the valid range [-26, 25].
#Frame_406 - [hevc @ 0b6bdb80] Could not find ref with POC 41
我尝试在 python 和 c++ 中实现代码,结果相同。还尝试另存为 .png 而不是 .jpg。使用 imshow 显示相机时 rtsp 提要工作正常,该问题仅在尝试保存帧时出现。据我所知,这些错误与 ffmpeg 有关,但谷歌对这些类型的错误没有太大帮助。
#include <iostream>
#include <opencv2\opencv.hpp>
#include <chrono>
#include <thread>
using namespace std;
using namespace cv;
int main()
VideoCapture cap("rtsp://admin:admin@192.168.88.97/media/video1");
if (!cap.isOpened())
return -1;
for (int i = 0; i < 500; i++)
Mat frame;
cap >> frame;
imwrite("C:\\Users\\Documents\\Dev\\c++\\OpenCVExample\\frames\\frame" + std::to_string(i) + ".png", frame);
cout << i << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(10));
return 0;
【问题讨论】:
在写成if(frame.data)
之前尝试检查框架是否有效。这可能与问题无关,但也是一个缺失点。检查here
【参考方案1】:
OpenCV 和 RTSP 流有点棘手。这通常发生在无法足够快地读取流的帧时。在这种情况下(某处)接收 RTSP 帧的缓冲区将被填充得比清空快;当缓冲区已满时,它将被刷新并从最近的帧重新开始填充。这将破坏流解码,直到下一个keyframe。
我的建议是删除sleep
,即使 10 毫秒非常小。由于这还不够 (:P),唯一的解决方案是实现一个线程不断地从 cv::VideoCapture
读取帧,并在主线程忙于保存前一帧时丢弃抓取的帧。
一个简单的实现可能是:
#include <opencv2/opencv.hpp>
#include <thread>
class VideoSourceHandler
public:
// Video file or IP camera
VideoSourceHandler( const std::string & source ) :
mCapture( source ),
mRun( false )
// USB camera
VideoSourceHandler( int webcamID ) :
mCapture( webcamID ),
mRun( false )
// start and stopCapture can be squashed into C'tor and D'tor if you want RTTI
void startCapture()
mRun = true;
mLoopThread = std::thread( &VideoSourceHandler::threadLoop, this );
void stopCapture()
mRun = false;
mLoopThread.join();
cv::Mat getFrame()
std::this_thread::yield(); // Be nice
const std::lock_guard<std::mutex> lock( mMutex );
return mCurrentFrame;
private:
void threadLoop()
while( mRun )
// Sleep if you want to "control" FPS
const std::lock_guard<std::mutex> lock( mMutex );
mCapture >> mCurrentFrame;
std::this_thread::yield(); // Be nice
cv::VideoCapture mCapture;
std::thread mLoopThread;
std::mutex mMutex;
bool mRun;
cv::Mat mCurrentFrame;
;
int main()
VideoSourceHandler vsh( 0 );
vsh.startCapture();
while( true )
cv::Mat frame = vsh.getFrame();
if( frame.empty() )
continue;
cv::imshow( "Test", frame );
char key = cv::waitKey( 1 );
if( key == 'q' || key == 27 )
break;
vsh.stopCapture();
return 0;
【讨论】:
这个答案让我改变了来自解决问题的相机的帧速率。将帧速率从 25 fps 降至 10fps 后,错误停止出现。谢谢!【参考方案2】:将视频压缩更改为 H.264
为我解决了这个问题。
【讨论】:
以上是关于OpenCV FFMPEG RTSP 相机馈送错误的主要内容,如果未能解决你的问题,请参考以下文章