初始突发后,OpenCV网络(IP)相机帧每秒慢

时间:2012-07-04 18:05:29

标签: c++ opencv ubuntu-12.04 ip-camera

编辑:升级到OpenCV 2.4.2和FFMPEG 0.11.1似乎已经解决了所有错误和连接问题,但它仍然没有解决帧速率的降低。

我在Ubuntu 12.04中使用默认的OpenCV包,我相信它是2.3.1。我正在连接一台流式传输MJPEG的Foscam FI8910W。我已经看到人们说过最好的方法是使用opencv + libjpeg + curl it is faster than the gstreamer solution。但是,我可以偶尔(50%的时间)从OpenCV连接到摄像机,因为它是构建并获得视频流。此流以大约30 fps开始大约1秒,但随后减慢到5-10 fps。我正在进行的项目需要6个摄像头,最好以15-30 fps的速度运行(速度越快越好)。

以下是我的问题:

  1. 这是一个在2.4.2中修复的问题,我应该这样做 升级?
  2. 如果没有,任何想法为什么我得到一个短暂的爆发然后它 慢下来?
  3. 最好的解决方案仍然是使用curl + libjpeg?
  4. 我看到很多人说解决方案已经发布,但是 很少有实际链接到解决方案的帖子。拥有所有的实际 在一个地方提到的解决方案(卷曲和gstreamer)将是 根据{{​​3}}非常方便。
  5. 这是我的代码:

      VideoCapture cap;
      cap.open("http://10.10.1.10/videostream.asf?user=test&pwd=1234&resolution=32");
      Mat frame;
      cap >> frame;
      wr.open("test.avi", CV_FOURCC('P','I','M','1'), 29.92, frame.size(), true);
      if(!wr.isOpened())
      {
        cout << "Video writer open failed" << endl;
        return(-1);
      }
      Mat dst = Mat::zeros(frame.rows + HEADER_HEIGHT, frame.cols, CV_8UC3);
      Mat roi(dst, Rect(0, HEADER_HEIGHT-1, frame.cols, frame.rows));
      Mat head(dst, Rect(0,0,frame.cols, HEADER_HEIGHT));
      Mat zhead = Mat::zeros(head.rows, head.cols, CV_8UC3);
      namedWindow("test", 1);
      time_t tnow;
      tm *tS;
      double t1 = (double)getTickCount();
      double t2;
      for(int i = 0; i>-1 ; i++) // infinite loop
      {
        cap >> frame;
        if(!frame.data)
          break;
        tnow = time(0);
        tS = localtime(&tnow);
        frame.copyTo(roi);
        std::ostringstream L1, L2;
        L1 << tS->tm_year+1900 << " " << coutPrep << tS->tm_mon+1 << " ";
        L1 << coutPrep << tS->tm_mday << " ";
        L1 << coutPrep << tS->tm_hour;
        L1 << ":" << coutPrep << tS->tm_min << ":" << coutPrep << tS->tm_sec;
        actValueStr = L1.str();
        zhead.copyTo(head);
        putText(dst, actValueStr, Point(0,HEADER_HEIGHT/2), fontFace, fontScale, Scalar(0,255,0), fontThickness, 8);
        L2 << "Frame: " << i;
        t2 = (double)getTickCount();
        L2 << "  " << (t2 - t1)/getTickFrequency()*1000. << " ms";
        t1 = (double)getTickCount();
        actValueStr = L2.str();
        putText(dst, actValueStr, Point(0,HEADER_HEIGHT), fontFace, fontScale, Scalar(0,255,0), fontThickness, 8);
        imshow("test", dst);
        wr << dst; // write frame to file
        cout << "Frame: " << i << endl;
        if(waitKey(30) >= 0)
          break;
      }
    

    以下是正确运行时列出的错误:

    Opening 10.10.1.10
    Using network protocols without global network initialization. Please use avformat_network_init(), this will become mandatory later.
    Using network protocols without global network initialization. Please use avformat_network_init(), this will become mandatory later.
    [asf @ 0x701de0] max_analyze_duration reached
    [asf @ 0x701de0] Estimating duration from bitrate, this may be inaccurate
    [asf @ 0x701de0] ignoring invalid packet_obj_size (21084 656 21720 21740)
    [asf @ 0x701de0] freeing incomplete packet size 21720, new 21696
    [asf @ 0x701de0] ff asf bad header 0  at:1029744
    [asf @ 0x701de0] ff asf skip 678 (unknown stream)
    [asf @ 0x701de0] ff asf bad header 45  at:1030589
    [asf @ 0x701de0] packet_obj_size invalid
    [asf @ 0x701de0] ff asf bad header 29  at:1049378
    [asf @ 0x701de0] packet_obj_size invalid
    [asf @ 0x701de0] freeing incomplete packet size 21820, new 21684
    [asf @ 0x701de0] freeing incomplete packet size 21684, new 21836
    Using network protocols without global network initialization. Please use avformat_network_init(), this will become mandatory later.
    Using network protocols without global network initialization. Please use avformat_network_init(), this will become mandatory later.
    [asf @ 0x701de0] Estimating duration from bitrate, this may be inaccurate
    Successfully opened network camera
    [swscaler @ 0x8cf400] No accelerated colorspace conversion found from yuv422p to bgr24.
    Output #0, avi, to 'test.avi':
    Stream #0.0: Video: mpeg1video (hq), yuv420p, 640x480, q=2-31, 19660 kb/s, 90k tbn, 29.97 tbc
    [swscaler @ 0x9d25c0] No accelerated colorspace conversion found from yuv422p to bgr24.
    Frame: 0
    [swscaler @ 0xa89f20] No accelerated colorspace conversion found from yuv422p to bgr24.
    Frame: 1
    [swscaler @ 0x7f7840] No accelerated colorspace conversion found from yuv422p to bgr24.
    Frame: 2
    [swscaler @ 0xb9e6c0] No accelerated colorspace conversion found from yuv422p to bgr24.
    Frame: 3
    

    有时它会在第一个Estimating duration from bitrate语句

    之后挂起

2 个答案:

答案 0 :(得分:0)

您是否尝试删除写入磁盘的代码?当磁盘缓冲区填满时,我发现USB摄像头的性能问题非常相似。首先是很好的帧率,然后它会急剧下降。

如果这是问题,另一个选择是将您的压缩编解码器更改为压缩程度更高的东西。

答案 1 :(得分:0)

快速初始FPS会变为慢速FPS,这表明相机正在增加曝光时间以补偿光线不足的拍摄对象。相机正在分析前几帧,然后相应地调整曝光时间。

实际的FPS似乎是两件事的组合:

  1. 硬件限制(定义最大FPS)
  2. 所需的曝光时间(定义最小FPS)
  3. 硬件可能具有传输X FPS所需的带宽,但光线不足的情况可能需要一个减慢实际FPS的曝光时间。例如,如果每帧需要暴露0.1秒,禁食的FPS将为10。

    要测试此功能,请使用相机指向光线不足的拍摄对象测量FPS,然后将相机与相机指向光线充足的拍摄对象进行比较。务必夸大照明条件,并让相机几秒钟检测到所需的曝光。