实践|OpenCV4.2使用DNN进行人脸检测二(视频篇)
- 2020 年 4 月 8 日
- 筆記
前言
前一篇《实践|OpenCV4.2使用DNN进行人脸检测一(图片篇)》我们已经实现了人脸检测的主要方法,这一篇我们来看看加载视频中实时检测效果,检测来说其实也都是一样的,主要就是把播放的视频每帧通过检测去进行处理,代码我会直接贴出来,这里主要是想说的核心点,Debug和Relese的运行效果差异之大
程序代码
程序代码我们还是上个项目的基础上,新建了一个main.cpp的文件,把原来的mainpic的main入口改了个名,这样程序启动时就会启动这个新的main.cpp的程序了。

main.cpp代码
#include<opencv2/opencv.hpp> #include<iostream> #include <direct.h> #include "dnnfacedetect.h" using namespace std; using namespace cv; dnnfacedetect fdetect; void detectface(Mat frame); int main(int argc, char* argv) { //获取程序目录 char filepath[256]; _getcwd(filepath, sizeof(filepath)); cout << filepath << endl; //定义模型文件 string ModelBinary = (string)filepath + "/opencv_face_detector_uint8.pb"; string ModelDesc = (string)filepath + "/opencv_face_detector.pbtxt"; //视频文件 string videodesc = (string)filepath + "/test.mp4"; cout << ModelBinary << endl; cout << ModelDesc << endl; int startfps = 0; int detectfps = 3; //初始化 fdetect = dnnfacedetect(ModelBinary, ModelDesc); if (!fdetect.initdnnNet()) { cout << "初始化DNN人脸检测失败!" << endl; return -1; } //加载视频 Mat frame; VideoCapture video; video.open(videodesc); if (!video.isOpened()) { cout << "视频加载失败!" << endl; return -1; } try { //读取图像每一帧 while (video.read(frame)) { if (startfps % detectfps == 0) { double t = (double)getTickCount(); //旋转90度 rotate(frame, frame, 0); //缩放图片 resize(frame, frame, cv::Size(0, 0), 0.6, 0.6); //人脸检测 detectface(frame); imshow("src", frame); t = ((double)getTickCount() - t) / getTickFrequency(); cout << "执行时间(秒): " << t << endl; } startfps++; char c = waitKey(1); if (c == 27) { break; } } cout << "检测完成" << endl; } catch (const std::exception & ex) { cout << ex.what() << endl; } video.release(); waitKey(0); return 0; } void detectface(Mat frame) { if (!frame.empty()) { vector<Mat> dst = fdetect.detect(frame); if (!dst.empty()) { for (int i = 0; i < dst.size(); i++) { string title = "detectface" + i; imshow(title, dst[i]); } } } }
运行效果

从上面的动图可以看到,我们每一帧处理的都需要0.6秒左右,右边的实际视频效果差距太大了,如果这样来看,简直就是没法用。
后来在网上找了找答案,发现一篇文章说到在OpenCV中Debug和Release的效果能差10倍。
看到这个后感觉有点太夸张了,到底有没有效果我们也应该去验证一下,于是在属性管理器中我们又增加了一个OpenCV_Release的属性

配置和Debug基本一样,只不过在链接器里的文件原来是opencv_world420d.lib改为opencv_world420.lib


然后代码我们一点没动,只不过把生成方法从Debug改为了Release

再看效果

可以看到处理的时间在0.1秒左右,那个速度也可以说直接提升了很多倍了,不过比起直接播放视频还是慢了些,不过这倒是不影响,真正生产环境中,我们可以考虑几帧处理一次,然后外部调用的时候还是实时播放,通过线程,协程等方式进行回调处理即可。
代码里面我有处理了加了个参数,实现的是每三帧处理一次,显示画面,整个播放能看到有一点小卡,不过速度跟原视频明显差距没有那么大了,最后就放上视频的整个运行效果看一下。
视频效果
重要的事说三遍
Release比Debug的速度快N倍。
Release比Debug的速度快N倍。
Release比Debug的速度快N倍。