清空opencv里面VideoCapture采集图像的缓冲区

用opencv采集视频的时候, 一般使用VideoCapture这个类来完成采集工作。我的摄像头fps默认是30, 由于我们的fpga还没有完全完成, 检测部分还是arm的cpu来做的, 所以一次人脸识别大概需要90ms左右, 也就是一秒只能处理10帧图像。这就是问题的来源, 我需要每次处理的帧都是最新采集到的帧(实时效果), 偏偏VideoCapture没有清空缓冲区这个操作, 只能等待你把缓冲区的数去读走, VideoCapture才会放入最新的帧。我在网上搜索了下, 有说设置fps的, 也有说设置缓冲区大小的(仅限某些支持的设备), 最终找到一个靠谱的办法, 有人提议新开一个线程专门负责一直读取缓冲区的数据, 从而能保持主线程人脸识别的时候始终能够获取到最新采集的帧。

#include <iostream>
#include <thread>
#include <opencv2/opencv.hpp>

void clean_buffer(cv::VideoCapture *invc)
{
if (invc == nullptr) {
std::cerr << "nullptr." << std::endl;
exit(-1);
}

while (true) {
// 通过高速连续抓取帧来保持VideoCapture的缓冲区为空
invc->grab();
std::cout << "clean the buffer." << std::endl;
}
}

int main(int argc, char *argv[])
{
cv::VideoCapture camera(0), *vc_pointer;
if (!camera.isOpened()) {
std::cerr << "open camera failed." << std::endl;
exit(-1);
}

vc_pointer = &camera;
std::thread th(clean_buffer, vc_pointer);
while (true) {
cv::Mat frame;
camera >> frame;
if (frame.empty()) {
std::cerr << "get frame from camera failed." << std::endl;
return -1;
}
// TODO 在这里添加你的代码
// face_recognize();
}

return 0;
}