我正在编写一个使用QTimer触发对opencv videoCapture的调用以读取视频帧的代码。我通常会阅读大量视频,所以想知道是否还有其他方法可以加快这一过程。

这是我使用QTimer的代码的快照:

timer = new  QTimer();
timer->setTimerType(Qt::PreciseTimer);
connect(timer, SIGNAL(timeout()), this, SLOT(read_shape_params()));

//in a loop stop timer and setup the next video stream then start

void next(){

  timer->stop();

   stream = new video_stream_reader();
   stream->setColorGray(grayImage);
   stream->set_begin_end(begin_at,end_at);
   stream->open(video_base_path+video_path);

   timer->start(0);
}

void shape_param_finder::read_shape_params(){
   Mat frame;
   frame = stream->read_frame();
}

Mat video_stream_reader::read_frame(){
   Mat frame;
   bool bSuccess = capture->read(frame);
   return frame;

}

最佳答案

它与QTimer无关。但
timer->start(0);
是一个问题。
您输入的视频中,摄像机的frame per second表示生成帧的时间段。例如,25fps意味着您将在每个时间段获得一个新帧,在这种情况下为40ms

简短答案:
如果没有适当的硬件同步,请将计时器超时设置为1000 / expected fps

长答案:

具有timeout = 0的计时器将尽可能快地调度read_shape_params。这意味着性能瓶颈最终是capture->read(frame);,假设代码的其他部分(显示等)可以正常工作。

关于capture->read(frame),有3种情况:

  • 该时间段需要花费更多的时间来解决:您无法执行任何操作。会很慢。
  • 确实是同一时间。这是最好的地方。这也是极不可能的。
  • 该时间段的分辨率花费的时间更少:应该不错吧?错误。您多次读取同一张图像。这意味着您最多只能浪费cpu资源。在最坏的情况下,从您的 Angular 来看,情况开始像情况1一样。那个怎么样?假设展示一个框架需要30毫秒(阅读和展示,我假设您是线性完成的)。
    Read 1 : 30 ms, frame 1
    Read 2 : 30 ms, frame 1 // wasted read, the other party has not updated the frame yet
    Read 3 : 30 ms, frame 2 // your second frame has 60 ms latency, not 40 ms
    Read 4 : 30 ms, frame 3 // frame 3 has 120 ms latency, sweet spot.
    Read 5 : 30 ms, frame 3 // wasted read
    Read 6 : 30 ms, frame 4 // frame 3 has 120 ms latency, sweet spot.
    

  • 如果最重要的是您继续显示要排队的项目,并且显示缓慢,则您感觉到的fps会降低。
  • 您需要确定基准的执行时间video_stream_reader::read_frame可以肯定。
  • 您还需要基准测试哪个代码来显示
    图片。我怀疑那里存在瓶颈。
  • 07-24 09:44
    查看更多