基于C++&Opencv的PCA(主成分分析法)特征脸人脸检测、人脸识别超详细教程(一)

前言:博主现在也只是大三狗,之前帮同学做了人脸识别的小软件,帮他在某项目中结题。经过十天左右的码码历程,终于在网上代码+自己捣鼓将这个小小小小小项目码了出来。所以就以分享这个小小小软件的历程,对做这类项目的同学一点帮助。此博文可能不能做到一次性更新完,但是我尽量做到有空的时候来更新一下。
声明:由于暂时本科大三,学历、资历暂时有限,在以下文章可能会引用网上各大前辈的一些内容,但是我尽量做到在引用前咨询原创前辈,并做出相关超链接。如果有前辈发现这个内容有部分侵犯您版权,希望前辈可以联系我,我定将很快的删除,并做出道歉,谢谢~

近30年,随概率、神经网络等理论、算法的快速发展,计算机性能不断提高,人脸识别越来越流行,但是又不得不承认这个也是非常困难的话题。所以此文仅介绍比较简单的算法。

此系列文章内容:人脸检测=》人脸预处理=》人脸训练=》人脸识别

零、Opencv安装

Opencv安装过程详见
OpenCV 开发环境的搭建(Win8.1 + VS2013 + OpenCV 2.4.8)
http://www.hiclk.com/2015/03/24/opencv248vs2013/

一、人脸检测

由于Opencv中文首页及Opencv的示例代码中都提到了Haar特征检测器,故此项目中亦采用这种比较常见的人脸检测方法。

关于Haar特征的Adaboost级联人脸检测分类器的详细介绍,请参考雨石前辈的详细介绍
http://blog.csdn.net/stdcoutzyx/article/details/34842233
相信根据上文的学习,读者也对Haar特征的级联分类器有了比较清晰的认识,我们就只来关注此级联分类器的使用。
贴上Haar特征检测的C++实现代码。

<此代码来源于网上,注释为我添加,暂未找到原创作者,若侵犯你的权益,请联系我,我将速更换>

此函数输入IplImage基本数据结构和Haar级联分类器,输出检测到人脸边缘的CvRect矩形框,若未检测到人脸,则返回{-1,-1,-1,-1}

CvRect detectFaceInImage(constIplImage*inputImg,constCvHaarClassifierCascade*cascade)//传入图像与级联分类器指针

{

    const CvSize minFeatureSize = cvSize(20, 20);//定义核大小

    const int flags = CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH;	// 定义非重复检测

    const float search_scale_factor = 1.1f;//定义搜索比例

    IplImage *detectImg;

    IplImage *greyImg = 0;

    CvMemStorage* storage;

    CvRect rc;

    double t;

    CvSeq* rects;

    int i;

    storage = cvCreateMemStorage(0);

    cvClearMemStorage(storage);

    detectImg = (IplImage*)inputImg;

    if (inputImg->nChannels > 1)//是否为灰度图像

    {

        greyImg = cvCreateImage(cvSize(inputImg->width, inputImg->height), IPL_DEPTH_8U, 1);//创建单通道灰度图像

        cvCvtColor(inputImg, greyImg, CV_BGR2GRAY);//颜色转化

        detectImg = greyImg;

    }

    t = (double)cvGetTickCount();//得到系统启动所经历毫秒数

    rects = cvHaarDetectObjects(detectImg, (CvHaarClassifierCascade*)cascade, storage,

        search_scale_factor, 3, flags, minFeatureSize);//检测图像中的目标(人脸)

    t = (double)cvGetTickCount() - t;//得到计算总耗时

    // 得到检测的最大人脸

    if (rects->total > 0) {

        rc = *(CvRect*)cvGetSeqElem(rects, 0);

    }

    else

        rc = cvRect(-1, -1, -1, -1);	// Couldn't find the face.

    if (greyImg)

        cvReleaseImage(&greyImg);

    cvReleaseMemStorage(&storage);

    return rc;// 返回寻找到最大脸的矩形边缘坐标

}

函数调用函数如下:

void Recognition()

{

    frame = cvQueryFrame(cam);//从摄像头获取一帧图像IplImage结构图像

    CvHaarClassifierCascade* faceCascade;//定义级联分类器

    CvRect faceRect;//定义矩形区域结构

    faceCascade =cvLoadHaarClassifierCascade(faceCascadeFilename,cvSize(20,20));
      //从文件中装载训练好的级联分类器 const char *faceCascadeFilename = "haarcascade_frontalface_alt.xml";此文件

百度可得到

    faceRect = detectFaceInImage(frame, faceCascade);//执行上面函数,返回矩形结构

    cvRectangle(frame, cvPoint(faceRect.x, faceRect.y), cvPoint(faceRect.x + faceRect.width - 1, faceRect.y + 

faceRect.height - 1), CV_RGB(0, 255, 0), 1, 8, 0);

    //在原Iplimage结构用矩形中标记出人脸

}

人脸检测部分就先更新到这里了。
17dc1d01-8d20-4371-b9f3-1d3bca4367c5