首页 文章

OpenCV - RTSP流损坏的宏块

提问于
浏览
0

我有一个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 回答

  • 1

    事实证明,由于在_1567485内进行了昂贵的功能调用,视频输入速度变慢的原因非常严重:

    Mat H = findHomography( obj, scene, CV_RANSAC, 3, mask );
    

    我已将 CV_RANSAC 参数更改为 0 ,因此该行现在看起来像:

    Mat H = findHomography(obj,scene,0,0,mask);

    注:第四个参数也更改为 0 ,因为它是使用 CV_RANSAC 时的阈值,更多信息可以在文档here中找到 .

    对于其他任何发现这一点的人也要注意Zaw Lin的答案,因为它也有助于消除视频输入中的腐败问题 .

  • 0

    尝试使用单独的线程进行捕获和处理 . 我之前也遇到过这个问题,一旦我将它们分成两个线程,它就会消失 . (我直接使用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;
    }
    

相关问题