由于本人能力有限,请大家指正,谢谢,原文看http://blog.csdn.net/caiye917015406/article/details/8372876,其中在原文中有很多链接,翻译的时候没有黏贴。
一、简介
在计算机视觉和生物识别领域,人脸识别是一个热点。这项技术已经被研究了25年,现在广泛应用在安全、机器人、人机交互、数码相机、游戏盒和娱乐。
人脸识别通常包括两个阶段
1.人脸检测 首先通过搜索图片找到人脸区域,然后通过对这些区域的处理可以更容易的进行识别。
2. 人脸识别 通过检索数据库的人脸,来进行匹配确定具体的人
自从2002年以来,人脸检测已经具有较为可靠的识别特性,比如利用OpenCv的人脸检测库,对清晰正面脸的识别精确度可达到90%-95%。通常来说,对于有一定遮挡和有角度的人脸检测是比较苦难的。在这种情况下,需要3D头部姿态估计来辅助识别。当然,对于品质不好的图像、人脸分辨率不一致、有遮挡和戴眼镜的图像来说,人脸检测同样是比较困难的。
相比人脸检测二样,人脸识别具有较小的准确率,一般在30%到70%之间。自从九十年代以来,人脸识别一直是一个重要的研究领域,不过目前还远没有达到可靠地要求,每年都要大量的技术别发明例如本页的最上面的技术((Alternatives to Eigenfaces such as 3D face recognition or recognition from video))
接下来,我将介绍如何利用 Eigenfaces(或者叫做“主成分分析”orPCA),相比于一些常用的方法(asNeural Networks orFisher Faces.)来说,这种方法是一种简单和常用的二位人脸识别。
你可以通过阅读Face Recognition With Eigenface (这篇文章可以在 Face Recognition With Eigenface (April 2007), 或者mathematical algorithm.中找到)来学习Eigenfaces的理论。
首先我将先介绍如何通过命令行进行人脸识别,更多详细的参见theServo Magazine tutorial and source-code(May 2007).
在介绍完如何通过命令行进行人脸识别后,我将介绍如何拓展到到实时的检测中。
二、如何利用OpenCV的人脸识别库来进行人脸检测
正如前面介绍的,人脸识别的第一步是人脸检测。在OpenCv中,利用级联(also known as the Viola-Jones method)的人脸检测可以很容易的在一张图片中检测一个全脸。
在OpenCV中,级联检测是一个有效的人脸检测方法,但是如果直接用这个功能还是有些烦人的,因此我们这里用最简单的方法,既使用包装好的函数。
// 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)
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).
}
现在,当你想在一幅图片中检测人脸的话,你可以简单的调用上面的函数。同时,你还需要指定相应的人脸分类器,让OpenCV根据分类器来检测人脸。对于OpenCv来说,除了正面脸的人脸分类器之外,还有侧脸、眼睛、鼻子、嘴、全身等的分类器,你可以根据自己的需要来使用任何一个分类器。甚至你可以创建自己的分类器如车或特定的人。所以,正面脸的检测只是其中的一种,我们在文中讨论的也只是正面脸的检测和和识别。
对于正面脸的检测,你可以选择OpenCv提供的任一种级联分类器(在data\haarcascades\" 文件中)
•"haarcascade_frontalface_default.xml"
•"haarcascade_frontalface_alt.xml"
•"haarcascade_frontalface_alt2.xml"
•"haarcascade_frontalface_alt_tree.xml"
根据你环境的不同,每一种级联器得到的效果可能有细小的差别,所以,如果想得到最好的检测效果,你可以综合这几种分类器得到的结果。在这里有一些眼睛、头、嘴和鼻子的级联分类器in the downloads section ofModesto's page..
因此,你可以再人脸检测程序中做以下修改
// Haar Cascade file, used for Face Detection.
char *faceCascadeFilename = "haarcascade_frontalface_alt.xml";
// Load the HaarCascade classifier for face detection.
CvHaarClassifierCascade* faceCascade;
faceCascade = (CvHaarClassifierCascade*)cvLoad(faceCascadeFilename, 0, 0, 0);
if( !faceCascade ) {
printf("Couldnt load Face detector '%s'\n", faceCascadeFilename);
exit(1);
}
// Grab the next frame from the camera.
IplImage *inputImg = cvQueryFrame(camera);
// Perform face detection on the input image, using the given Haar classifier
CvRect faceRect = detectFaceInImage(inputImg, faceCascade);
// Make sure a valid face was detected.
if (faceRect.width > 0) {
printf("Detected a face at (%d,%d)!\n", faceRect.x, faceRect.y);
}
.... Use 'faceRect' and 'inputImg' ....
// Free the Face Detector resources when the program is finished
cvReleaseHaarClassifierCascade( &cascade );
三、如何处理局部图像的人脸识别
既然现在能进行人脸检测,我们就可以对检测的人脸图像进行人脸识别。当然,如果想简单的从一张图像中直接的进行人脸识别,那么你的准确率可能低于10%。
对你提供的需要进行识别的图像,进行图像的标准预处理是十分重要的。大多数的识别算法对图像的亮度十分敏感,所以如果用在黑暗中的人脸图片作为样本,有可能在明亮的图像中的识别效果不好。这种现象被称为“光照量依赖”,当然还有许多其他的因素,例如人脸应该在图像中的一个特定的位置(如眼睛在同一个的像素坐标),一致的大小,旋转角度、发型、感情和光照的位置等。由于以上因素的影响,在人脸识别前进行好的预处理滤波器显得尤为重要。另外,还需要将人脸区域外的像素去掉,比如用一个椭圆来标注人脸区域。对于头发和图像背景信息是不需要的,它们的变化比较大。
为了简单起见,这里介绍的人脸识别系统是基于灰度图的特征脸方法。因此,在接下来我将介绍如何简单的进行图像的灰度变化、利用直方图均衡(Histogram Equalization)来标准化亮度和对比你的脸部图像。为了得到更好的结果,你可以使用彩色人脸识别(在HSV上实现理想化的直方图拟合或者选取一个彩色空间代替RGB),或者采用边缘增强、轮廓检测或者行为检测等多种预处理方法。另外,这段代码实现了图像大小的标准化,它有可能改变人脸的高宽比。你可以通过阅读我的一篇文章HERE,实现保持长宽比的图像大小标准化。
在下面这幅图像中,展示了预处理的几个阶段。
以下有一些实现图像灰度变化、标准化图像的维度,然后利用直方图均衡化来实现一致的亮度和对比度。
// Either convert the image to greyscale, or use the existing greyscale image.
IplImage *imageGrey;
if (imageSrc->nChannels == 3) {
imageGrey = cvCreateImage( cvGetSize(imageSrc), IPL_DEPTH_8U, 1 );
// Convert from RGB (actually it is BGR) to Greyscale.
cvCvtColor( imageSrc, imageGrey, CV_BGR2GRAY );
}
else {
// Just use the input image, since it is already Greyscale.
imageGrey = imageSrc;
}
// Resize the image to be a consistent size, even if the aspect ratio changes.
IplImage *imageProcessed;
imageProcessed = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
// Make the image a fixed size.
// CV_INTER_CUBIC or CV_INTER_LINEAR is good for enlarging, and
// CV_INTER_AREA is good for shrinking / decimation, but bad at enlarging.
cvResize(imageGrey, imageProcessed, CV_INTER_LINEAR);
// Give the image a standard brightness and contrast.
cvEqualizeHist(imageProcessed, imageProcessed);
..... Use 'imageProcessed' for Face Recognition ....
if (imageGrey)
cvReleaseImage(&imageGrey);
if (imageProcessed)
cvReleaseImage(&imageProcessed);
四 利用Eigenfaces(特征脸法)实现人脸识别
现在已经有了预处理的图像,我们接下来就可以进行PCA的人脸识别了。在OpenCV中,可以通过调用”cvEigenDecomposite()”函数,实现PCV的人脸识别,当然,它需要一些样本图像来知道如何识别每一个人。
因此,如果想识别某个人,你需要收集一组专业的人脸图像。例如,如果你想识别班级的10个人,那么需要对每个人收集20张照片,也就说需要200张100*100的专业人脸图像。
对于PCV的理论解释,在Servo Magzine杂志中有两篇论文详细的介绍,在这里,我也尝试的去介绍一些。
利用PCA将200张训练图像转化为一系列的“特征脸“,这些特征脸代表了这些图像中的主要差别。主要为以下几步
1. 通过计算每个像素点平均值获得“平均脸图像“。
2. 通过平均脸图像可以计算得到本证脸图像。第一个本征脸图像记录最主要的差异,第二个本征脸图像记录的第二主要的差异,依次类推可以得到50张本征脸图像,它们代表了训练图像中大部分差异。
在上面的例子中,我们可以看到三幅图像分别是平均脸图像、第一张本征脸图像和最后一张本征脸图像,它们是从四个人的30张图像中产生的。注意到,平均脸图像展示了一个人脸的平滑结构,第一张本征脸图像展示了脸中一些重要特征,最后一张本征脸主要是图像的噪声。在下面的图像中展示了32张本征脸。