级联分类器是将若干个分类器进行连接,从而构成一种多项式级的强分类器。级联分类器使用前要先进行训练,怎么训练呢?用目标的特征值去训练,对于人脸来说,通常使用Haar特征进行训练。
Haar特征是由M.Oren,C.Papageorgious等人在论文“Pedestrian detection using wavelet templates”中首次提出的,后续经过改进与发展,C.H.Messom和A.L.Barczak提出了积分直方加速Harr特征的计算方法,R.Lienhart,J.Maydt等人提出了Haar特征的多个模板种类,后逐步形成OpenCV中的Haar分类器。Haar特征也称Haar-like特征,是一种简单且高效的图像特征,其基于矩形区域相似的强度差异Haar小波。Haar特征的特点为:高类的可变性;低类的可变性;而向局部的强度差异;多尺度不变性;计算效率高。
OpenCV提供了用于检测目标物体的级联分类器类CascadeClassfier,其检测函数的原型及参数意义如下:
void detectMultiScale( InputArray image,CV_OUT std::vector<Rect>& objects,double scaleFactor = 1.1,int minNeighbors = 3, int flags = 0,Size minSize =Size(),Size maxSize = Size() );
image:当然是输入图像了,要求是8位无符号图像,即灰度图。
objects:输出向量容器(保存检测到的物体矩阵)
scaleFactor:每张图像缩小的尽寸比例
minNeighbors:每个候选矩阵应包含的像素领域
flags:表示此参数模型是否更新标志位;
minSize :表示最小的目标检测尺寸;
maxSize:表示最大的目标检测尺寸;
利用Haar特征训练的级联分类器对人脸进行检测的代码如下:
代码中用到的根据Haar特征训练出的级联分类器初始化数据xml文件下载链接如下:
链接:https://pan.baidu.com/s/1HJ_E1Oq2bVENnIQ40YoRYg
提取码:5t7i
//OpenCV版本3.0.0
//exe文件运行前,请把初始化XML文件放入相关工程文件下
//该程序现在不能识别戴上眼镜的脸部,因为对脸部区域的确认是能过是否有眼睛进一步确认的
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
CascadeClassifier face_cascade, eyes_cascade;
String window_name = "Face Detection";
void detectFaces(Mat frame) {
std::vector<Rect> faces;
Mat frame_gray;
// 灰度变换
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
// 直方图均衡
equalizeHist(frame_gray, frame_gray);
// 多尺度人脸检测
face_cascade.detectMultiScale(frame_gray, faces,
1.1, 3,0|CASCADE_SCALE_IMAGE, Size(30, 30));
// 人脸检测结果判定
for(size_t i = 0; i < faces.size(); i++)
{
// 检测到人脸中心
Point center(faces[i].x + faces[i].width/2,
faces[i].y + faces[i].height/2);
Mat face = frame_gray(faces[i]);
std::vector<Rect> eyes;
// 在人脸区域检测人眼
eyes_cascade.detectMultiScale(face, eyes, 1.1, 2,
0 |CASCADE_SCALE_IMAGE, Size(30, 30) );
if(eyes.size() > 0)
// 绘制人脸
ellipse(frame, center, Size(faces[i].width/2,
faces[i].height/2),
0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
}
imshow( window_name, frame );
}
int main()
{
// 摄像头读取
VideoCapture cap(0);
Mat frame;
// 初始化haar级联人脸分类器XML
face_cascade.load("haarcascade_frontalface_alt.xml");
// 初始化haar级联人眼分类器XML
eyes_cascade.load("haarcascade_eye_tree_eyeglasses.xml");
while(cap.read(frame))
{
// 人脸检测
detectFaces(frame);
//等待30ms,如果有按键按下,则返回按值值,即非0值,如果30ms没有按键按下,则返回-1值
if( waitKey(30) >= 0)
break;
}
return 0;
}
运行结果如下图所示:
补充说明一下:
//exe文件运行前,请把初始化XML文件放入相关工程文件下
//该程序现在不能识别戴上眼镜的脸部,因为对脸部区域的确认是能过是否有眼睛进一步确认的