(资料图)
再初次接触机器视觉的小伙伴应该都会遇到这种情况,明明摄像头输出的画面是 30 fps 的,但对每一帧图像进行畸变矫正或者是一些图像处理后,视频帧数降低到了不到 10 fps!还伴随出现丢帧或者是播放缓慢,内存占用越来越多。
最近想到了一种利用线程池去并行处理视频流的方法,该方法在处理耗时高于视频帧产生间隔时,能有效提高最终视频输出的帧率。本文会用伪代码来描述整个方法的框架,不提供实际的代码。
基本思路就是将读取、计算和消费三部分分离到不同的线程中,读取视频流的图像为单独一条线程,图像处理的计算在线程池中进行,最后使用结果的部分也是单独一条线程。
下面开始介绍完整的流程细节,先定义一些基本的接口和类型:
首先就是读取图像线程的部分,该线程负责读取一帧视频图像,然后创建一个图像处理任务提交到线程池中,图像处理完成后,把结果塞到优先队列里。
消费结果的线程逻辑会稍微复杂一点,因为线程池中执行任务的顺序是不确定,我们需要用条件变量来控制输出顺序。
## 总结
整个框架的思路其实挺简单的,但实际实现的时候需要注意的细节会比较多,这里举例两个:
1. 多线程的安全问题,用 C/C++ 实现的时候,要尽可能避免图像数据的拷贝,又要保证线程池任务执行和最后读取结果的时候图像数据是有效的;
2. 最终使用结果图像的部分,由于是并行处理多帧图像,最终得到图像的频率是不稳定的,有可能一瞬间就读读到 N 幅图像,这时候就需要根据需求来修改代码了,例如我最终的图像是要实时显示出来,那就要加上合适的延迟再播放下一帧,不如画面就会出现卡顿一下下,然后瞬间播放好几帧的情况;