我有一个Android程序,通过RTSP将视频流式传输到Wowza媒体服务器,我的OpenCV程序然后获取此RTSP源进行处理。
问题是视频Feed几乎立即被破坏,并输出以下错误:
[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
,这会删除损坏的框架但会留下大量延迟,导致Feed无用(这是实时应用程序)。
我有一个不同的程序用于测试流,RTSP提要在该程序中运行正常(也使用OpenCV),只有当我尝试在单独的程序中使用相同的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);
该程序还使用ffmeg
选项在tcp
中正常流式传输。
编辑:
捕获线程:
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;
}
答案 0 :(得分:1)
尝试使用单独的线程进行捕获和处理。我之前也遇到过这个问题,一旦我将它们分成两个线程,它就会消失。 (我直接使用ffmpeg,但它应该类似)。您可以通过在您提到的opencv程序中使用sleep()函数来实现这种情况。您应该立即看到腐败开始发生。
因此,每当消费网络订阅源出现延迟时,这种类型的损坏似乎要频繁得多。此外,如果你的cpu太慢而无法处理流,它也会发生。如果直接使用ffmpeg,则可以丢弃那些损坏的帧,因为它们会影响结果,特别是在进行运动检测时。
好的,这只是伪代码,但通常看起来应该是这样。
bool imgready=false;
Mat sharedmat;
mutex mtx;
Mat captureThread() {
if(captureOpen == false){
img_scene = cvCaptureFromFile("rtsp://193.61.148.73:1935/serg/android_test?tcp");
}
while(1) {
mtx.lock();
sharedmat = cvQueryFrame(img_scene);
imgready=true;
mtx.unlock();
}
}
void processFunction(Mat im)
{
//do whatever
}
void processingThread() {
while(1)
{
if(imgready)
{
mtx.lock();
Mat localmat=sharedmat.clone();
processFunction(localmat);
imgready=false;
mtx.unlock();
}else
sleep(1000);//sleep 1 millisecond
}
}
int main(int argc, char *argv[]) {
thread t1(captureThread);
thread t2(processingThread);
t1.join();
t2.join();
return 0;
}
答案 1 :(得分:0)
事实证明,由于findHomography
内的一个昂贵的函数调用,导致视频输入速度变慢的原因非常严重:
Mat H = findHomography( obj, scene, CV_RANSAC, 3, mask );
我已将CV_RANSAC
参数更改为0
,因此该行现在如下所示:
Mat H = findHomography(obj,scene,0,0,mask);
N.B。第四个参数也更改为0
,因为它是使用CV_RANSAC
时的阈值,更多信息可以在文档here中找到。
对于其他任何发现这一点的人也要注意Zaw Lin的答案,因为它也有助于消除视频输入中的腐败问题。