本篇博文中的代码实际参考https://blog.csdn.net/zuidao3105/article/details/79346591,opencv版本为2.4.9
在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。使用已经训练好的XML格式的分类器进行人脸检测。在OpenCV的安装目录下的data文件夹里可以看到下图所示的内容
笔记:
文件夹的名字“haarcascades”、“hogcascades”和“lbpcascades”分别表示通过“haar”、“hog”和“lbp”三种不同的特征而训练出的分类器。
"haar"特征主要用于人脸检测,
“hog”特征主要用于行人检测,
“lbp”特征主要用于人脸识别
“eye”特征主要用于眼睛的检测识别。
实现人脸检测主要依赖于detectMultiScale()函数,下面简单说一下函数参数的含义,先看函数原型:
CV_WRAP virtual 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() );
CV_WRAP virtual void detectMultiScale( const Mat& image,
CV_OUT vector<Rect>& objects,
vector<int>& rejectLevels,
vector<double>& levelWeights,
double scaleFactor=1.1,
int minNeighbors=3, int flags=0,
Size minSize=Size(),
Size maxSize=Size(),
bool outputRejectLevels=false );
参数1:image--待检测图片,灰度图;
参数2:objects--被检测物体的矩形框向量组,也就是保存被检测出的人脸位置坐标序列;
参数3、参数4:rejectLevels-、levelWeight 和人脸得分有关,本篇先只做第一个重载的说明并且给出demo,详情请参考https://blog.csdn.net/u011783201/article/details/52160629
参数5:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
参数6:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上;如果想要提高检测人脸的正确率,设置大一些
参数7:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,
如果设置为 CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域; 决定是缩放分类器来检测,还是缩放图像
参数意义:用户指定是否要查找所有人脸(默认)或只查找最大人脸
参数8、9:minSize和maxSize用来限制得到的目标区域的范围,即人脸的最大最小尺寸
注意: 这个函数的参数对检测的影响是很大的
检测图片中的人脸代码:
#include "opencv2/opencv.hpp"
//#include <opencv2/calib3d/calib3d.hpp>
#include <QDebug>
using namespace cv;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Mat image, image_gray; //定义两个Mat变量,用于存储每一帧的图像
image = imread("../imgs/c.jpg");
imshow("原图", image);
cvtColor(image, image_gray, CV_BGR2GRAY);//转为灰度图
equalizeHist(image_gray, image_gray);//直方图均衡化,增加对比度方便处理
CascadeClassifier eye_Classifier; //载入分类器
CascadeClassifier face_cascade; //载入分类器
//加载分类训练器,OpenCv官方文档提供的xml文档,可以直接调用
//xml文档路径 opencvPath/data/haarcascades
if (!eye_Classifier.load("../haarcascade_eye_tree_eyeglasses.xml")) //需要将xml文档放在自己指定的路径下
{
qDebug() << "Load haarcascade_eye.xml failed!" << endl;
return 0;
}
if (!face_cascade.load("../haarcascade_frontalface_default.xml"))
{
qDebug() << "Load haarcascade_frontalface_alt failed!" << endl;
return 0;
}
//vector 是个类模板 需要提供明确的模板实参 vector<Rect>则是个确定的类 模板的实例化
vector<Rect> eyeRect;
vector<Rect> faceRect;
//检测关于眼睛部位位置
eye_Classifier.detectMultiScale(image_gray, eyeRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(40, 40));
for (size_t eyeIdx = 0; eyeIdx < eyeRect.size(); eyeIdx++)
{
rectangle(image, eyeRect[eyeIdx], Scalar(0, 0, 255)); //用矩形画出检测到的位置
}
//检测关于脸部位置
face_cascade.detectMultiScale(image_gray, faceRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(40, 40));
qDebug() << "faces number:"<< faceRect.size();
for (size_t i = 0; i < faceRect.size(); i++)
{
rectangle(image, faceRect[i], Scalar(0, 0, 255)); //用矩形画出检测到的位置
}
imshow("人脸识别图", image); //显示当前帧
return a.exec();
}