OpenCV的 - RTSP流损坏宏 [英] OpenCV - RTSP stream corrupted macroblock

查看:4282
本文介绍了OpenCV的 - RTSP流损坏宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Android程序,它通过RTSP流视频的Wowza媒体服务器,我的OpenCV的程序然后得到这个RTSP饲料加工。

问题是视频源几乎立即被破坏,下面的错误输出:

  [H264 @ 0x1f05320]无效的水平preFIX
[H264 @ 0x1f05320]错误而解码MB 5
[H264 @ 0x1dfb940]无效的水平preFIX
[H264 @ 0x1dfb940]错误而解码MB 6 1
[H264 @ 0x1dfbde0]损坏的宏块7 5(total_coeff = -1)
[H264 @ 0x1dfbde0]错误而解码MB 7 5
[H264 @ 0x1dfafe0]损坏的宏块7 6(total_coeff = -1)
 ...

我曾尝试加入?TCP 来这消除腐败帧,但给我留下呈现饲料没用了大量滞后的网址的结尾(这是一个实时应用程序)。

我有我用来测试流不同的程序和RTSP饲料(使用OpenCV的为好),它只能在该程序正常,当我尝试使用相同的饲料在一个单独的程序,计算ORB功能饲料被破坏得面目全非。我得到的视频,像这样:

  CV ::垫灰色;
  CvCapture * img_scene = cvCaptureFromFile(RTSP://193.61.148.73:1935 / SERG / android_test); //?TCP
  而(1){//创建直播infinte循环
    CV ::垫图像= cvQueryFrame(img_scene);
    cvtColor(图像,灰度,CV_BGR2GRAY);

该方案还处于 ffmeg 使用 TCP流精选项。

编辑:

捕获线程:

 垫captureThread(){
  如果(captureOpen == FALSE){
    img_scene = cvCaptureFromFile(RTSP://193.61.148.73:1935 / SERG / android_test TCP);
  }
  而(1){
    图像= cvQueryFrame(img_scene);
    cvtColor(图像,灰度,CV_BGR2GRAY);
    返回灰色;
  }

}

加工螺纹:

 垫processingThread(太灰,垫img_object){
  //计算关键点和描述符
  //匹配关键点和描述符
  //画好比赛
  //单应借鉴
    返回imgMatches;
}

主要的:

  INT主(INT ARGC,CHAR *的argv []){
  img_object = imread(的argv [1],CV_LOAD_IMAGE_GRAYSCALE);
  而(1){
    线程T1(captureThread);
    t1.join();
    captureOpen =真;
    线程T2(processingThread,灰色,img_object);
    t2.join();
    imshow(输出,imgMatches);
    键= cvWaitKey(5);
    如果(CHAR(键)== 27){
      打破;
    }
  }
  返回0;
}


解决方案

尝试使用单独的线程进行捕捉和处理。我也遇到过这个问题,它在很大程度上走了一次,我让他们分成两个线程。 (我是直接使用ffmpeg的,但它应该是相似的)。你可以看到,这确实是通过把睡眠()函数中你提到正在OpenCV的程序的情况。您应该立即看到腐败现象开始发生。

所以,每当有消费网络馈送延迟,这类腐败现象似乎更加频繁。此外,如果你的cpu太慢处理流时,就会出现这种情况也是如此。如果直接使用ffmpeg的,这是可能的,因为他们在做的运动检测时,影响尤其是结果抛弃那些损坏的帧。

修改

好吧,这只是伪code,但一般它应该是这样的。

 布尔imgready = FALSE;
垫sharedmat;
互斥MTX;垫captureThread(){
  如果(captureOpen == FALSE){
    img_scene = cvCaptureFromFile(RTSP://193.61.148.73:1935 / SERG / android_test TCP);
  }
  而(1){    mtx.lock();
    sharedmat = cvQueryFrame(img_scene);
    imgready = TRUE;
    mtx.unlock();  }}无效processFunction(太IM)
{
  //做什么
}无效processingThread(){
  而(1)
  {
    如果(imgready)
    {
      mtx.lock();
      垫localmat = sharedmat.clone();
      processFunction(localmat);
      imgready = FALSE;      mtx.unlock();
    }其他
      睡眠(1000); //睡眠1毫秒
  }
}
INT主(INT ARGC,CHAR *的argv []){  线程T1(captureThread);
  线程T2(processingThread);  t1.join();
  t2.join();  返回0;
}

I have a android program that streams video via RTSP to a Wowza media server, my OpenCV program then gets this RTSP feed to process.

The problem is the video feed almost immediately gets corrupted and the following errors are output:

[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)
 ...

I have tried adding ?tcp to the end of the URL which removes the corrupt frames but leaves me with a large amount of lag that renders the feed useless (it's a real time application).

I have a different program that I use to test the stream and the RTSP feed works fine in that program (using OpenCV as well), it's only when I try to use the same feed in a separate program that computes ORB features that the feed gets corrupted beyond recognition. I'm getting the video like so:

  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);

The program also streams fine in ffmeg using the tcpoption.

EDIT:

capture thread:

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;
  }

}

Processing thread:

Mat processingThread(Mat gray, Mat img_object) {
  //calculate keypoint and descriptors
  //match keypoints and descriptors
  //draw good matches
  //draw homography
    return imgMatches;
}

main:

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;
}

解决方案

try using separate threads for capturing and processing. I have also encountered this problem before and it largely went away once I have separated them into two threads. (I was using ffmpeg directly but it should be similar). You can see that this is really the case by putting a sleep() function in the opencv program you mentioned was working. You should immediately see the corruption starts to happen.

So whenever there is a delay in consuming the network feed, these kind of corruption seems to be much more frequent. Also if your cpu is too slow to process the stream, it will happen as well. If you are using ffmpeg directly, it's possible to discard those corrupted frames since they affect the results especially when doing motion detection.

Edit

Ok this is just pseudo code but generally it should look like this.

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;
}

这篇关于OpenCV的 - RTSP流损坏宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆