一、简介
在计算机视觉和生物识别领域,人脸识别是一个热点。这项技术已经被研究了25年,现在广泛应用在安全、机器人、人机交互、数码相机、游戏盒和娱乐。
人脸识别通常包括两个阶段
1.人脸检测 首先通过搜索图片找到人脸区域,然后通过对这些区域的处理可以更容易的进行识别。
2. 人脸识别 通过检索数据库的人脸,来进行匹配确定具体的人
自从2002年以来,人脸检测已经具有较为可靠的识别特性,比如利用OpenCv的人脸检测库,对清晰正面脸的识别精确度可达到90%-95%。通常来说,对于有一定遮挡和有角度的人脸检测是比较苦难的。在这种情况下,需要3D头部姿态估计来辅助识别。当然,对于品质不好的图像、人脸分辨率不一致、有遮挡和戴眼镜的图像来说,人脸检测同样是比较困难的。
相比人脸检测二样,人脸识别具有较小的准确率,一般在30%到70%之间。自从九十年代以来,人脸识别一直是一个重要的研究领域,不过目前还远没有达到可靠地要求,每年都要大量的技术别发明例如本页的最上面的技术((Alternatives to Eigenfaces such as 3D face recognition or recognition from video))
接下来,我将介绍如何利用 Eigenfaces(或者叫做“主成分分析”orPCA),相比于一些常用的方法(神经网路、Fishetr Face)来说,这种方法是一种简单和常用的二位人脸识别。
你可以通过阅读Face Recognition With Eigenface (这篇文章可以在 Servo Magazine (April 2007), 或者mathematical algorithm.中找到)来学习Eigenfaces的理论。
首先我将先介绍如何通过命令行进行人脸识别,更多详细的参见Servo Magazine tutorial and source-code (May 2007).
在介绍完如何通过命令行进行人脸识别后,我将介绍如何拓展到到实时的检测中。
二、如何利用OpenCV的人脸识别库来进行人脸检测
正如前面介绍的,人脸识别的第一步是人脸检测。在OpenCv中,利用级联(also known as the Viola-Jones method)的人脸检测可以很容易的在一张图片中检测一个全脸。
在OpenCV中,级联检测是一个有效的人脸检测方法,但是如果直接用这个功能还是有些烦人的,因此我们这里用最简单的方法,既使用包装好的函数。
[cpp]
// Perform face detection on the input image, using the given Haar Cascade.
// Returns a rectangle for the detected region in the given image.
CvRect detectFaceInImage(IplImage *inputImg, CvHaarClassifierCascade* cascade)
{
// Smallest face size.
CvSize minFeatureSize = cvSize(20, 20);
// Only search for 1 face.
int flags = CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH;
// How detailed should the search be.
float search_scale_factor = 1.1f;
IplImage *detectImg;
IplImage *greyImg = 0;
CvMemStorage* storage;
CvRect rc;
double t;
CvSeq* rects;
CvSize size;
int i, ms, nFaces;
storage = cvCreateMemStorage(0);
cvClearMemStorage( storage );
// If the image is color, use a greyscale copy of the image.
detectImg = (IplImage*)inputImg;
if (inputImg->nChannels > 1) {
size = cvSize(inputImg->width, inputImg->height);
greyImg = cvCreateImage(size, IPL_DEPTH_8U, 1 );
cvCvtColor( inputImg, greyImg, CV_BGR2GRAY );
detectImg = greyImg; // Use the greyscale image.
}
// Detect all the faces in the greyscale image.
t = (double)cvGetTickCount();
rects = cvHaarDetectObjects( detectImg, cascade, storage,
search_scale_factor, 3, flags, minFeatureSize);
t = (double)cvGetTickCount() - t;
ms = cvRound( t / ((double)cvGetTickFrequency() * 1000.0) );
nFaces = rects->total;
printf("Face Detection took %d ms and found %d objects\n", ms, nFaces);
// Get the first detected face (the biggest).
if (nFaces > 0) www.zzzyk.com
rc = *(CvRect*)cvGetSeqElem( rects, 0 );
else
rc = cvRect(-1,-1,-1,-1); // Couldn't find the face.
if (greyImg)
cvReleaseImage( &greyImg );
cvReleaseMemStorage( &storage );
//cvReleaseHaarClassifierCascade( &cascade );
return rc; // Return the biggest face found, or (-1,-1,-1,-1).
}