基于Opencv的人脸识别

要进行人脸的识别的训练,首先我们要对Openv中人脸识别类FaceRecognizer要有一个了解,http://www.cnblogs.com/guoming0000/archive/2012/09/27/2706019.html 可以参考这个博客对FaceRecognizer 有一个了解http://blog.csdn.net/u013088062/article/details/38588185 这个博客对人脸的训练解释的很好,具体怎么训练可以阅读这个博客。

关于人脸识别 我们有一下两个步骤
1.利用PCA变换的人脸识别,对人脸进行训练。
2.读取训练出的文件,并进行判别。

首先第一步是对人脸进行集中训练,训练成功后会生成一个xml文件。
下面是如何训练的代码:

#include
#include 
#include 
#include 
#include 
#include   
#include    


using namespace cv;
using namespace std;
using namespace face;

CascadeClassifier face_cascades;

void read_csv(const string& filename, vector& images, vector<int>& labels, char separator = ';')
{       
    std::ifstream file(filename.c_str(), ifstream::in);//c_str()函数可用可不用,无需返回一个标准C类型的字符串
    if (!file)
    {
        string error_message = "No valid input file was given, please check the given filename.";
        CV_Error(CV_StsBadArg, error_message);
    }
    string line, path, classlabel;
    while (getline(file, line))//从文本文件中读取一行字符,未指定限定符默认限定符为“/n”
    {
        stringstream liness(line);//这里采用stringstream主要作用是做字符串的分割
        getline(liness, path, separator);//读入图片文件路径以分好作为限定符
        getline(liness, classlabel);//读入图片标签,默认限定符
        if (!path.empty() && !classlabel.empty())//如果读取成功,则将图片和对应标签压入对应容器中 
        {
            images.push_back(imread(path, 0));
            labels.push_back(atoi(classlabel.c_str()));
        }
    }
}


int main()
{
    char   buffer[MAX_PATH];
    _getcwd(buffer, MAX_PATH);
    printf("The   current   directory   is:   %s ", buffer);
    string fn_csv;
    fn_csv = buffer;
    fn_csv = fn_csv + "\\image\\at.txt";
    //string fn_csv = "./image/at.txt";//读取你的CSV文件路径.  相对路径读取失败

    vector images;// 2个容器来存放图像数据和对应的标签
    vector<int> labels;
    read_csv(fn_csv, images, labels);//从csv文件中批量读取训练数据
    Ptr model = createEigenFaceRecognizer();
    model->train(images, labels);
    model->save("MyFaceRecognizer.xml");//保存路径
    return 0;
}

训练好后就是对人脸进行识别
代码如下:

#include

#include 
#include 
#include 
#include 

using namespace cv;
using namespace std;
using namespace face;

CascadeClassifier g_face_cascades;
RNG g_rng(12345);
Ptr model;
int Predict(Mat src_image);
void detectAndDisplay(Mat frame);
int main()
{
    VideoCapture capture(0);//读取视频并初始化
    Mat edges;//定义一个edges的类
    model = createEigenFaceRecognizer();
    model->load("MyFaceRecognizer.xml");//加载分类器
    g_face_cascades.load("haarcascade_frontalface_alt.xml");

    while (1)
    {
        Mat frame;//定义一个frame的变量用来储存每帧的图像
        capture >> frame;//读取当前帧
        if (!frame.data)
        {
            cout << "未能读取图片\n";
            return -1;
        }
        detectAndDisplay(frame);
    }
    return 0;
}

void detectAndDisplay(Mat frame)
{
    std::vector faces;    //存储人脸的矩形
    Mat frame_gray;
    if (frame.channels() == 1)
    {
        frame_gray = frame;
    }
    else
    {
        cvtColor(frame, frame_gray, CV_RGB2GRAY);
    }
    equalizeHist(frame_gray, frame_gray);   //直方图均衡化
                                            //detectMultiScale函数中frame_gray表示的是要检测的输入图像为frame_gray,faces表示检测到的人脸目标序列,1.1表示
                                            //每次图像尺寸减小的比例为1.1,2表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大
                                            //小都可以检测到人脸),CV_HAAR_SCALE_IMAGE表示不是缩放分类器来检测,而是缩放图像,Size(30, 30)为目标的
                                            //最小最大尺寸
    g_face_cascades.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
    Mat* pImage_roi = new Mat[faces.size()];    //定以数组
    string str;
    for (int i = 0; i < faces.size(); i++)
    {
        pImage_roi[i]=frame_gray(faces[i]); //将所有的脸部保存起来
        if (pImage_roi[i].empty())
            continue;
        switch (Predict(pImage_roi[i])) //每张图片进行识别
        {
            case 1:str = "Error"; break;
            case 2:str = "GanHaoYu"; break;
            case 3:str = "XuHaoRan"; break;
            case 4:str = "HuangLuYao"; break;
            default: str = "person"; break;
        }
        Scalar color = Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255));//所取的颜色任意值
        rectangle(frame, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), color, 1, 8);//放入缓存
        putText(frame, str, Point(faces[i].x, faces[i].y), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255));//添加文字
    }
    delete []pImage_roi;
    imshow("人脸识别", frame);
    waitKey(30);
}

int Predict(Mat src_image)  //识别图片
{
    Mat edges;
//  cvtColor(src_image, edges, COLOR_BGR2GRAY);//灰度
    resize(src_image, edges, cv::Size(92, 122));//大小一致
    return model->predict(edges);
}

这个是实现的效果
基于Opencv的人脸识别_第1张图片
之后我将他封装成了一个类,代码就几行搞定了,方便快捷。
基于Opencv的人脸识别_第2张图片

封装类的资料连接这里写链接内容

你可能感兴趣的:(opencv图像识别)