我有一个Android程序,通过RTSP将视频流传输到Wowza媒体服务器,我的OpenCV程序然后获取此RTSP源进行处理 .
问题是视频源几乎立即被破坏,并输出以下错误:
[h264 @ 0x1f05320] Invalid level prefix
[h264 @ 0x1f05320] error while decoding MB 5 5
[h264 @ 0x1dfb940] Invalid level prefix
[h264 @ 0x1dfb940] error while decoding MB 6 1
[h264 @ 0x1dfbde0] corrupted macroblock 7 5 (total_coeff=-1)
[h264 @ 0x1dfbde0] error while decoding MB 7 5
[h264 @ 0x1dfafe0] corrupted macroblock 7 6 (total_coeff=-1)
...
我已经尝试将 ?tcp
添加到URL的末尾,这会删除损坏的帧,但会留下大量的延迟,导致Feed无用(这是一个实时应用程序) .
我有一个不同的程序,我用来测试流,RTSP提供在该程序中正常工作(也使用OpenCV),只有当我尝试在单独的程序中使用相同的feed来计算Feed获取的ORB功能时腐败无法辨认 . 我得到的视频是这样的:
cv::Mat gray;
CvCapture* img_scene = cvCaptureFromFile("rtsp://193.61.148.73:1935/serg/android_test"); //?tcp
while(1) { //Create infinte loop for live streaming
cv::Mat image = cvQueryFrame(img_scene);
cvtColor(image, gray, CV_BGR2GRAY);
该程序还使用 tcp
选项在 ffmeg
中正常流 .
编辑:
捕获线程:
Mat captureThread() {
if(captureOpen == false){
img_scene = cvCaptureFromFile("rtsp://193.61.148.73:1935/serg/android_test?tcp");
}
while(1) {
image = cvQueryFrame(img_scene);
cvtColor(image, gray, CV_BGR2GRAY);
return gray;
}
}
处理线程:
Mat processingThread(Mat gray, Mat img_object) {
//calculate keypoint and descriptors
//match keypoints and descriptors
//draw good matches
//draw homography
return imgMatches;
}
主要:
int main(int argc, char *argv[]) {
img_object = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
while(1) {
thread t1(captureThread);
t1.join();
captureOpen = true;
thread t2(processingThread, gray, img_object);
t2.join();
imshow("Output", imgMatches);
key = cvWaitKey(5);
if (char(key) == 27) {
break;
}
}
return 0;
}
2 回答
事实证明,由于在_1567485内进行了昂贵的功能调用,视频输入速度变慢的原因非常严重:
我已将
CV_RANSAC
参数更改为0
,因此该行现在看起来像:Mat H = findHomography(obj,scene,0,0,mask);
注:第四个参数也更改为
0
,因为它是使用CV_RANSAC
时的阈值,更多信息可以在文档here中找到 .对于其他任何发现这一点的人也要注意Zaw Lin的答案,因为它也有助于消除视频输入中的腐败问题 .
尝试使用单独的线程进行捕获和处理 . 我之前也遇到过这个问题,一旦我将它们分成两个线程,它就会消失 . (我直接使用ffmpeg,但它应该类似) . 您可以通过在您提到的opencv程序中使用sleep()函数来实现这种情况 . 您应该立即看到腐败开始发生 .
因此,每当消耗网络订阅源出现延迟时,这种类型的损坏似乎要频繁得多 . 此外,如果你的cpu太慢而无法处理流,它也会发生 . 如果直接使用ffmpeg,则可以丢弃那些损坏的帧,因为它们会影响结果,尤其是在进行运动检测时 .
编辑
好的,这只是伪代码,但通常它应该是这样的 .