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