环境:OpenCV4.5.1 + VS2019
需先下载好相关文件(人脸检测用到的库文件,包括Tensorflow模型以及配置文件)如图:
若找不到该文件可点击此处进行下载
quickdemo.cpp
#include
#include
//#include
#include "quickopencv.h"
using namespace std;
using namespace cv;
void QuickDemo::face_detection_demo() {
//加载权重文件
string root_dir = "F:/BaiduNetdiskDownload/opencv/sources/samples/dnn/face_detector/";
//读出一个网络文件(读取深度学习Tensorflow模型以及配置文件)
//pb文件就是他的模型;pbtxt是配置文件
dnn::Net net = dnn::readNetFromTensorflow(root_dir + "opencv_face_detector_uint8.pb", root_dir + "opencv_face_detector.pbtxt");
VideoCapture capture(0);//加载视频
//VideoCapture capture("E:/2021.9.26备份/图片/Camera Roll/人脸素材.mp4");//加载视频
Mat frame; //定义一个二值化的 frame
while (true) {
capture.read(frame);
flip(frame, frame, 1); // 1 左右翻转 y对称 (镜像)
if (frame.empty()) //如果读入失败
{
break; //若视频为空,则跳出操作
}
//读模型
Mat blob = dnn::blobFromImage(frame, 1.0, Size(300, 300), Scalar(104, 177, 123), false, false);//对图像进行预处理
net.setInput(blob);//准备数据(blob就是 NCHW n多少个 c通道数 h高度 w宽度
//获取数据
Mat probs = net.forward();//获取推理后的数据(完成推理)
Mat detectionMat(probs.size[2], probs.size[3], CV_32F, probs.ptr());//构建Mat图像
/*
输出:(得出的blob)
第一个维度:有多少张图像,每张图有个编号;
维度二:image对应第几批次第几张图;
维度三:有多少个框
维度四:每个框有7个值,有7列
*/
//解析结果
for (int i = 0; i < detectionMat.rows; i++) {
float con = detectionMat.at(i, 2);
if (con > 0.5) { //大于0.5就是人脸
//获取矩形坐标(第3,4,5,6参数)
int x1 = static_cast(detectionMat.at(i, 3) * frame.cols);
int y1 = static_cast(detectionMat.at(i, 4) * frame.rows);
int x2 = static_cast(detectionMat.at(i, 5) * frame.cols);
int y2 = static_cast(detectionMat.at(i, 6) * frame.rows);
Rect box(x1, y1, x2 - x1, y2 - y1);
rectangle(frame, box, Scalar(0, 0, 255), 2, 8, 0);
}
}
imshow("人脸检测演示", frame);
int c = waitKey(1); //等待10ms(1s = 1000ms),做视频处理都是1
if (c == 27) { //按 esc 退出应用程序
break;
}
}
}
quickopencv.h
#pragma once
#include
using namespace cv;
class QuickDemo {
public:
void face_detection_demo(); //030.案例:实时人脸检测
};
源.cpp
#include
#include
#include "quickopencv.h"
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
//const char* imagename = "E:\\2021.9.26备份\\图片\\Camera Roll\\001.jpg"; //此处为你自己的图片路径
const char* imagename = "E:/2021.9.26备份/图片/Camera Roll/007.jpg"; //此处为你自己的图片路径
//从文件中读入图像
Mat img = imread(imagename, 1); //彩色
//Mat img = imread(imagename, IMREAD_GRAYSCALE); //黑白
//如果读入图像失败
if (img.empty())
{
fprintf(stderr, "Can not load image %s\n", imagename);
return -1;
}
//创建一个新窗口,参数1为名称,参数2代表一个自由的比例
namedWindow("image", WINDOW_FREERATIO); //可调整显示图片的窗口大小
//显示图像
imshow("image", img);//(名称,对象)
QuickDemo pd;//创建类对象
pd.mouse_drawing_demo(img);
waitKey(); //此函数等待按键,按键盘任意键就返回
//括号中参数为延时时间,单位ms
destroyAllWindows();//销毁前面创建的显示窗口
return 0;
}
部分参考了另一位小伙伴的笔记