Qtimer and opencv are slow

I am writing code that uses QTimer to call opencv videoCapture calls to read video frames. I usually read large chunks of video, so I wonder if there is another way to speed things up.

here's a snapshot of my code that uses 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;

}

      

+3


source to share


1 answer


It has nothing to do with QTimer. But

timer->start(0);

- the problem. On your video, you enter the camera, there is frame per second

, which means the period for the frame. For example, 25fps means you'll get a new frame every time, 40ms

in this case.

Short answer: Without proper hardware timing, set the timer timeout to 1000 / expected fps

.

Long answer:



Timer s timeout = 0

will schedule read_shape_params

as fast as possible. this means that the performance bottleneck will end up being capture->read(frame);

, assuming another piece of code (display, etc.) works just fine.

There are 3 cases about capture->read(frame)

:

  • It takes longer to resolve this time period: there is nothing you can do. It will be slow.
  • The same time. It's a sweet spot. This is also unlikely.
  • It takes less time to resolve this time period: should it be good? Wrong. You are reading the same image multiple times. This means, at best, you are wasting CPU resources. In the worst case, everything starts to behave like in case 1 from your point of view. How so? Let's say it takes 30ms to represent a frame (read and show, I assume you are doing this linearly).

    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.
    
          

If, in addition, you are storing the queue position for display and the display is slow, your perceived fps will be lower.

  • You need to check the lead time video_stream_reader::read_frame

    .
  • You also need to check what code the image will display. I suspect there is a bottleneck there.
+1


source







All Articles