基于opencv的人脸识别

来源:互联网 发布:小甲鱼c语言教程 编辑:程序博客网 时间:2024/05/22 01:53

1前言
最常见的人脸识别方法采用的是:人脸检测+人脸对齐+特征提取+识别,本文方法没有采用人脸对齐,因为本来opencv提取的特征效果就不好,只是参考玩玩。

参考的是> http://blog.csdn.net/mr_curry/article/details/51994497 这篇用的是dlib的对齐还加了mask。
本文方法:人脸检测( ShiqiYu/libfacedetection)+opencv提取Ptr类
2代码
FaceDetect.h

#include <opencv.hpp>#include <opencv.hpp>#include <iostream>#include <fstream>#include "facedetect-dll.h"using namespace cv;using namespace std;Ptr<FaceRecognizer>  GetTrainModel(string fn_csv);Mat FaceDetect(Mat& frame);

FaceDetect.cpp

#include "FaceDetect.h"void read_csv(const string& filename, cv::vector<Mat>& images, cv::vector<int>& labels, char separator = ';') {    std::ifstream file(filename.c_str(), ifstream::in);    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)) {        stringstream liness(line);        getline(liness, path, separator);        getline(liness, classlabel);        if (!path.empty() && !classlabel.empty()) {            Mat image = imread(path, 1);            Mat face = FaceDetect(image);            /*Mat facegray;            cvtColor(face, facegray, CV_BGR2GRAY);*/            images.push_back(face);            labels.push_back(atoi(classlabel.c_str()));        }    }}cv::Mat FaceToOne(cv::Mat source)//归一化处理函数{    cv::equalizeHist(source, source);//直方图均衡    cv::resize(source, source, cv::Size(92, 112));//裁剪    cv::Mat Mask = cv::imread("mask.jpg", 0);    cv::Mat changedMask;    source.copyTo(changedMask, Mask);    return changedMask;}Mat FaceDetect(Mat& frame)//脸是否存在{    Mat gray, error;    cvtColor(frame, gray, CV_BGR2GRAY);    int * pResults = NULL;    pResults = facedetect_frontal((unsigned char*)(gray.ptr(0)), gray.data, gray.cols, gray.rows, gray.step,        1.2f, 5, 24);    //pResults = facedetect_frontal_tmp((unsigned char*)(gray.ptr(0)), gray.cols, gray.rows, gray.step, 1.2f, 5, 24);    int peopleNUM = (pResults ? *pResults : 0);    float Area = 0.0f;    Rect MaxRect(0,0,0,0);    for (int i = 0; i < peopleNUM; i++)//代表有几张人脸(pResults ? *pResults : 0)    {        short * p = ((short*)(pResults + 1)) + 142* i;//新版本的lib是142,旧版是6*i        float area = p[2] * p[3];        if(area > Area)        {            Area = area;            Rect opencvRect(p[0], p[1], p[2], p[3]);            MaxRect = opencvRect;        }               }    if (0 != MaxRect.area())    {        cv::rectangle(frame, MaxRect, Scalar(255, 0, 0), 2);        Mat pic = gray(MaxRect);//感觉加了mask以后效果并不好        Mat pic_resize;        cv::resize(pic, pic_resize, cv::Size(100, 100));         /*cvtColor(pic, pic, CV_BGR2GRAY);        return FaceToOne(pic);*/        return pic_resize;    }    else        return error;}Ptr<FaceRecognizer>  GetTrainModel(string fn_csv)//输入CSV文件的路径名{    vector<Mat> images;    vector<int> labels;    try {        read_csv(fn_csv, images, labels);    }    catch (cv::Exception& e) {        cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;        // 文件有问题,我们啥也做不了了,退出了        exit(1);    }    // 如果没有读取到足够图片,我们也得退出.    if (images.size() <= 1) {        string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";        CV_Error(CV_StsError, error_message);    }    Ptr<FaceRecognizer> model = createLBPHFaceRecognizer();//创建人脸识别类 可修改 LBPHFace、EigenFace、FisherFace    model->train(images, labels);    return model;}

Main.cpp

#include "FaceDetect.h"const int namenumber = 4;//测试的人脸数量const string textname[namenumber] = {"Yong,Huan","CAO.YONG", "HUA.DONG", "Shen,Zhan"};//做一个储存人脸名字的数组int main(){       Ptr<FaceRecognizer> model = GetTrainModel("face.csv");//获得模型    VideoCapture cap(0);    if (!cap.isOpened())    {        cout << "Can't open camera!" << endl;        return -1;    }    Mat frame, gray;    while (true)    {        cap >> frame;        if (!frame.empty())        {            gray = FaceDetect(frame);            if (!gray.empty())            {                int LAB = model->predict(gray);                putText(frame, textname[model->predict(gray)], Point(50, 50), FONT_HERSHEY_DUPLEX, 2, Scalar(255, 0, 0));//model->predict(frame) = predictLabel 名字写在 1 1            }            imshow("Face Recogniton", frame);            waitKey(1);        }        else{ cout << "The Video's end." << endl;  }    }}

3实验效果
这里写图片描述

完整项目

http://download.csdn.net/download/bleakie/10018248

原创粉丝点击