qtimer 和 opencv 运行 慢
qtimer and opencv running slow
我正在编写一个代码,该代码使用 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 资源。在最坏的情况下,从您的角度来看,事情开始表现得像案例 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
可以肯定。
- 您还需要对负责显示的代码进行基准测试
图片。我怀疑那里有瓶颈。
我正在编写一个代码,该代码使用 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 资源。在最坏的情况下,从您的角度来看,事情开始表现得像案例 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
可以肯定。 - 您还需要对负责显示的代码进行基准测试 图片。我怀疑那里有瓶颈。