前言
本文使用的测试资源说明:
opencv版本:opencv 4.6.0
人脸检测算法
Haar特征分类器
Haar特征分类器是一个XML文件,描述了人体各个部位的Haar特征值。包括:人脸、眼睛、鼻子、嘴等。
opencv 4.6.0自带的Haar特征分类器,包括:
人脸检测模型
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
- 注:识别人体其它部位,只需替换对应的xml分类器即可。
detectMultiScale函数
/********************************************************************************
image:待检测图片,一般为灰度图像加快检测速度
objects:被检测物体的矩形框向量组
scaleFactor:表示在前后两次相继的扫描中,搜索窗口的比例系数。
默认为1.1,即每次搜索窗口依次扩大10%
minNeighbors:表示构成检测目标的相邻矩形的最小个数(默认为3)。
如果组成检测目标的小矩形的个数和小于min_neighbors-1都会被排除。
如果min_neighbors为0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上
flags:默认值0。如果设置为CV_HAAR_DO_CANNY_PRUNING,
那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,
因此这些区域通常不会是人脸所在区域
minSize:用来限制得到的目标区域的范围
maxSize:用来限制得到的目标区域的范围
********************************************************************************/
void detectMultiScale(
const Mat& image,
CV_OUT vector<Rect>& objects,
double scaleFactor = 1.1,
int minNeighbors = 3,
int flags = 0,
Size minSize = Size(),
Size maxSize = Size()
);
原彩色图片测试
int test_func_1() {
Mat img = imread("test_face/group1.jpg");
imshow("test", img);
//建立级联分类器
CascadeClassifier cascade;
//加载人脸检测器
cascade.load("test_face/haarcascade_frontalface_alt2.xml");
//人脸检测
vector<Rect> faces;
cascade.detectMultiScale(img,faces,1.1,3,0,Size(30,30));
//显示人脸框
if (faces.size()) {
cout << "人脸数量:" << faces.size() << endl;
for (size_t i = 0; i < faces.size(); i++) {
rectangle(img,faces[i], Scalar(0,0,255),3,8,0);
}
}
else {
cout << "未检测到人脸" << endl;
}
imshow("test_2", img);
waitKey(0);
return 0;
}
测试结果
彩色图片转灰度后测试
先转成灰度图片,再送检测,以提升检测速度。
int test_func_2() {
//建立级联分类器
CascadeClassifier cascade;
//加载人脸检测器
cascade.load("test_face/haarcascade_frontalface_alt2.xml");
//读取图片
Mat srcImg = imread("test_face/group1.jpg");
imshow("test", srcImg);
//生成灰度图
Mat grayImg;
grayImg.create(srcImg.size(),srcImg.type());
cvtColor(srcImg,grayImg,COLOR_BGR2GRAY);
//人脸检测
vector<Rect> faces;
cascade.detectMultiScale(grayImg, faces, 1.1, 3, 0);
//显示人脸框
if (faces.size()) {
cout << "人脸数量:" << faces.size() << endl;
for (size_t i = 0; i < faces.size(); i++) {
rectangle(srcImg, faces[i], Scalar(0, 0, 255), 3, 8, 0);
}
}
else {
cout << "未检测到人脸" << endl;
}
imshow("test_2", srcImg);
waitKey(0);
return 0;
}