用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) { 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; } }
return 0; }
|