OpenCV人脸识别之人脸检测

qi.wei

发布于 2018.10.25 15:10 阅读 3025 评论 0

程序背景

      当下,“人脸识别”技术在各种设备、各种场景出现的频率越来越多,这项技术在以后的几年内必定也会被更广泛、更普遍地应用于我们的日常生活中。本文介绍OpenCV“人脸识别”的第一步——人脸检测。

 

 

 

 

如何实现

      下载OpenCV库解压后,我们可以找到这样一个文件夹:opencv\sources\data,这个文件夹中大概包含如下图所示内容:

 

      我来介绍一下其中几个重要文件夹的用处: haar开头的文件夹,这里面保存着各种haar开头的xml文件,这些文件就是用于人脸检测的分类器;hog开头的文件夹,里面的xml文件是用于行人检测的分类器;lbp开头的文件夹,里面的xml文件是用于人脸识别的分类器。

 

 

      在MinGW版本的库中可能路径略有不同,但是通过文件夹名称依然能够很快找到我们需要的文件,我这里的路径如下图所示:

 

 

      实现人脸检测功能,只需要用到haarcascades文件夹下的haarcascade_frontalface_alt.xml文件:

 

 

 

 

代码示例

//核心函数代码
void faceTest()
{

    //人脸检测分类器的路径
    String facefile = "F:\\OpenCV\\mingw3.0\\mingw-dist\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";

    //脸部识别分类器
    CascadeClassifier faceCascader;

    //加载分类器
    if (!faceCascader.load(facefile)) {

        //printf("无法加载脸部特征文件:%s",facefile);
        return;

    }

    namedWindow("摄像头", CV_WINDOW_AUTOSIZE);

    VideoCapture capture(0);//打开摄像头
    
    Mat frame;

    Mat gray;

    vector<Rect> faces;

    int sn = 0;

    while (capture.read(frame)) {

        //将获取到的图像灰度化并保存给gray
        cvtColor(frame, gray, COLOR_RGB2GRAY);

        //直方图均衡化
        equalizeHist(gray, gray);

        //人脸检测函数,并将人脸相关数据保存到faces中
        faceCascader.detectMultiScale(gray, faces, 1.2, 3, 0, Size(30, 30));

        for (size_t faceSize=0;faceSize<faces.size();faceSize++)

        {

            //获取脸部图像矩形面积的坐标和宽高
            Rect roi;
            roi.x = faces[static_cast<int>(faceSize)].x;
            roi.y = faces[static_cast<int>(faceSize)].y;
            roi.width = faces[static_cast<int>(faceSize)].width;
            roi.height = faces[static_cast<int>(faceSize)].height ;

            //在人脸区域画一个矩形
            rectangle(frame, faces[static_cast<int>(faceSize)], Scalar(0, 0, 255), 2, 8, 0);

            sn++;
/*
            //将sn整型值转为字符串
            stringstream stream;
            stream << sn;

            //生产一个新的文件名
            String snStr = "F:\\img-" + stream.str() + ".jpg";
            cout << snStr << endl;


            //获取脸部矩形面积内的图片
            Mat faceROI = frame(roi);

            //保存脸部图像
            imwrite(snStr, faceROI);
*/

            if(!faces.empty()){
                qDebug()<<"检测到人脸!"<<endl;
            }

        }

        imshow("摄像头", frame);

        //必须加时延,否则无法显示图像

        char key = waitKey(30);

        //按ESC键退出

        if (key == 27) {

            break;

        }

    }

}

 

 

 

 

效果图: