openCV的人脸识别主要通过Haar分类器实现,当然,这是在已有训练数据的基础上。openCV安装在 opencv/opencv/sources/data/haarcascades_cuda(或haarcascades)中存在预先训练好的物体检测器(xml格式),包括正脸、侧脸、眼睛、微笑、上半身、下半身、全身等。
openCV的的Haar分类器是一个监督分类器,首先对图像进行直方图均衡化并归一化到同样大小,然后标记里面是否包含要监测的物体。它首先由Paul Viola和Michael Jones设计,称为Viola Jones检测器。Viola Jones分类器在级联的每个节点中使用AdaBoost来学习一个高检测率低拒绝率的多层树分类器。它使用了以下一些新的特征:
1. 使用类Haar输入特征:对矩形图像区域的和或者差进行阈值化。
2. 积分图像技术加速了矩形区域的45°旋转的值的计算,用来加速类Haar输入特征的计算。
3. 使用统计boosting来创建两类问题(人脸和非人脸)的分类器节点(高通过率,低拒绝率)
4. 把弱分类器节点组成筛选式级联。即,第一组分类器最优,能通过包含物体的图像区域,同时允许一些不包含物体通过的图像通过;第二组分 类器次优分类器,也是有较低的拒绝率;以此类推。也就是说,对于每个boosting分类器,只要有人脸都能检测到,同时拒绝一小部分非人脸, 并将其传给下一个分类器,是为低拒绝率。以此类推,最后一个分类器将几乎所有的非人脸都拒绝掉,只剩下人脸区域。只要图像区域通过了整 个级联,则认为里面有物体。
此技术虽然适用于人脸检测,但不限于人脸检测,还可用于其他物体的检测,如汽车、飞机等的正面、侧面、后面检测。在检测时,先导入训练好的参数文件,其中haarcascade_frontalface_alt2.xml对正面脸的识别效果较好,haarcascade_profileface.xml对侧脸的检测效果较好。当然,如果要达到更高的分类精度,可以收集更多的数据进行训练,这是后话。
以下代码基本实现了正脸、眼睛、微笑、侧脸的识别,若要添加其他功能,可以自行调整。
// faceDetector.h
// This is just the face, eye, smile, profile detector from OpenCV's samples/c directory
//
/* *************** License:**************************
Jul. 18, 2016
Author: Liuph
Right to use this code in any way you want without warranty, support or any guarantee of it working.
OTHER OPENCV SITES:
* The source code is on sourceforge at:
http://sourceforge.net/projects/opencvlibrary/
* The OpenCV wiki page (As of Oct 1, 2008 this is down for changing over servers, but should come back):
http://opencvlibrary.sourceforge.net/
* An active user group is at:
http://tech.groups.yahoo.com/group/OpenCV/
* The minutes of weekly OpenCV development meetings are at:
http://pr.willowgarage.com/wiki/OpenCV
************************************************** */
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#include <iostream>
using namespace std;
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;
static CvHaarClassifierCascade* nested_cascade = 0;
static CvHaarClassifierCascade* smile_cascade = 0;
static CvHaarClassifierCascade* profile = 0;
int use_nested_cascade = 0;
void detect_and_draw( IplImage* image );
/* The path that stores the trained