基于Opencv的人脸识别

来源:互联网 发布:tst代理淘宝开店规则 编辑:程序博客网 时间:2024/06/08 13:46

要进行人脸的识别的训练,首先我们要对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<iostream>#include <opencv2\opencv.hpp>#include <fstream>#include <sstream>#include <opencv2\face.hpp>#include <windows.h>  #include  <direct.h>  using namespace cv;using namespace std;using namespace face;CascadeClassifier face_cascades;void read_csv(const string& filename, vector<Mat>& 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<Mat> images;// 2个容器来存放图像数据和对应的标签    vector<int> labels;    read_csv(fn_csv, images, labels);//从csv文件中批量读取训练数据    Ptr<FaceRecognizer> model = createEigenFaceRecognizer();    model->train(images, labels);    model->save("MyFaceRecognizer.xml");//保存路径    return 0;}

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

#include<iostream>#include <opencv2\opencv.hpp>#include <fstream>#include <sstream>#include <opencv2\face.hpp>using namespace cv;using namespace std;using namespace face;CascadeClassifier g_face_cascades;RNG g_rng(12345);Ptr<FaceRecognizer> 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<Rect> 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);}

这个是实现的效果
这里写图片描述
之后我将他封装成了一个类,代码就几行搞定了,方便快捷。
这里写图片描述

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