opencv人脸识别

本篇博文中的代码实际参考https://blog.****.net/zuidao3105/article/details/79346591,opencv版本为2.4.9

 

在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。使用已经训练好的XML格式的分类器进行人脸检测。在OpenCV的安装目录下的data文件夹里可以看到下图所示的内容

opencv人脸识别

笔记:

文件夹的名字“haarcascades”、“hogcascades”和“lbpcascades”分别表示通过“haar”、“hog”和“lbp”三种不同的特征而训练出的分类器。

"haar"特征主要用于人脸检测,

“hog”特征主要用于行人检测,

“lbp”特征主要用于人脸识别

“eye”特征主要用于眼睛的检测识别。

实现人脸检测主要依赖于detectMultiScale()函数,下面简单说一下函数参数的含义,先看函数原型:

    CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector<Rect>& objects,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size() );

    CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector<Rect>& objects,
                                   vector<int>& rejectLevels,
                                   vector<double>& levelWeights,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size(),
                                   bool outputRejectLevels=false );

参数1:image--待检测图片,灰度图;

参数2:objects--被检测物体的矩形框向量组,也就是保存被检测出的人脸位置坐标序列;

参数3、参数4:rejectLevels-、levelWeight     和人脸得分有关,本篇先只做第一个重载的说明并且给出demo,详情请参考https://blog.****.net/u011783201/article/details/52160629


参数5:scaleFactor--表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;
参数6:minNeighbors--表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,这种设定值一般用在用户自定义对检测结果的组合程序上;如果想要提高检测人脸的正确率,设置大一些
参数7:flags--要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,

如果设置为 CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域; 决定是缩放分类器来检测,还是缩放图像

参数意义:用户指定是否要查找所有人脸(默认)或只查找最大人脸
参数8、9:minSize和maxSize用来限制得到的目标区域的范围,即人脸的最大最小尺寸

注意:  这个函数的参数对检测的影响是很大的

检测图片中的人脸代码:

#include "opencv2/opencv.hpp"
//#include <opencv2/calib3d/calib3d.hpp>

#include <QDebug>

using namespace cv;


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);


    Mat image, image_gray;      //定义两个Mat变量,用于存储每一帧的图像

    image = imread("../imgs/c.jpg");
    imshow("原图", image);

    cvtColor(image, image_gray, CV_BGR2GRAY);//转为灰度图
    equalizeHist(image_gray, image_gray);//直方图均衡化,增加对比度方便处理

    CascadeClassifier eye_Classifier;  //载入分类器
    CascadeClassifier face_cascade;    //载入分类器

    //加载分类训练器,OpenCv官方文档提供的xml文档,可以直接调用
    //xml文档路径  opencvPath/data/haarcascades
    if (!eye_Classifier.load("../haarcascade_eye_tree_eyeglasses.xml"))  //需要将xml文档放在自己指定的路径下
    {
        qDebug() << "Load haarcascade_eye.xml failed!" << endl;
        return 0;
    }

    if (!face_cascade.load("../haarcascade_frontalface_default.xml"))
    {
        qDebug() << "Load haarcascade_frontalface_alt failed!" << endl;
        return 0;
    }

    //vector 是个类模板 需要提供明确的模板实参 vector<Rect>则是个确定的类 模板的实例化
    vector<Rect> eyeRect;
    vector<Rect> faceRect;

    //检测关于眼睛部位位置
    eye_Classifier.detectMultiScale(image_gray, eyeRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(40, 40));
    for (size_t eyeIdx = 0; eyeIdx < eyeRect.size(); eyeIdx++)
    {
        rectangle(image, eyeRect[eyeIdx], Scalar(0, 0, 255));   //用矩形画出检测到的位置
    }

    //检测关于脸部位置
    face_cascade.detectMultiScale(image_gray, faceRect, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(40, 40));
    qDebug() << "faces number:"<< faceRect.size();
    for (size_t i = 0; i < faceRect.size(); i++)
    {
        rectangle(image, faceRect[i], Scalar(0, 0, 255));      //用矩形画出检测到的位置
    }

    imshow("人脸识别图", image);         //显示当前帧


    return a.exec();
}