zoukankan      html  css  js  c++  java
  • opencv学习之路(40)、人脸识别算法——EigenFace、FisherFace、LBPH

    一、人脸识别算法之特征脸方法(Eigenface)

    1、原理介绍及数据收集

    特征脸方法主要是基于PCA降维实现。

    详细介绍和主要思想可以参考

    http://blog.csdn.net/u010006643/article/details/46417127

    上述博客的人脸数据库打不开了,大家可以去下面这个博客下载ORL人脸数据库

    http://blog.csdn.net/xdzzju/article/details/50445160

    下载后,ORL人脸数据库有40个人,每人10张照片。

    2、流程

    3、相关图示

     

    4、代码

      1 #include <opencv2/opencv.hpp>
      2 #include <opencv2/face.hpp>
      3 
      4 using namespace cv;
      5 using namespace cv::face;
      6 using namespace std;
      7 
      8 //对原图归一化
      9 Mat normal(Mat src, Mat dst) {
     10     if (src.channels() == 1)//若原图单通道
     11         normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
     12     else //否则,原图三通道
     13         normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
     14     return dst;
     15 }
     16 
     17 void main() {
     18     //读取文件,转换为数据流
     19     string filename = string("at.txt");
     20     ifstream file(filename.c_str(), ifstream::in);
     21     if (!file)
     22         cout << "error" << endl;
     23 
     24     string line, path, classlabel;
     25     vector<Mat>image;
     26     vector<int>labels;
     27     char separator = ';';
     28     while (getline(file,line))
     29     {
     30         stringstream liness(line);
     31         getline(liness, path, separator);
     32         getline(liness, classlabel);
     33         if (!path.empty()&&!classlabel.empty())
     34         {
     35             //cout << "path:" << path<< endl;
     36             image.push_back(imread(path, 0));
     37             labels.push_back(atoi(classlabel.c_str()));
     38         }
     39     }
     40 
     41     if (image.size() < 1 || labels.size() < 1)
     42         cout << "invalid image path..." << endl;
     43 
     44     int height = image[0].rows;
     45     int width = image[0].cols;
     46     //cout << "height:" << height << "," << width<<endl;
     47 
     48     //最后一个人为测试样本
     49     Mat testSample = image[image.size() - 1];
     50     int testLabel = labels[labels.size() - 1];
     51     image.pop_back();
     52     labels.pop_back();
     53 
     54     //训练
     55     Ptr<BasicFaceRecognizer>model = createEigenFaceRecognizer();
     56     model->train(image, labels);
     57 
     58     //识别
     59     int predictLabel = model->predict(testSample);
     60     cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;
     61 
     62     //获得特征值,特征向量,均值    平均脸
     63     Mat eigenvalues = model->getEigenValues();
     64     Mat eigenvectors = model->getEigenVectors();
     65     Mat mean = model->getMean();
     66     Mat meanFace = mean.reshape(1,height);
     67     Mat dst;
     68     dst= normal(meanFace,dst);
     69     imshow("Mean Face", dst);
     70     
     71     //特征脸
     72     for (int i = 0; i < min(10,eigenvectors.cols); i++)
     73     {
     74         Mat ev = eigenvectors.col(i).clone();
     75         Mat eigenFace = ev.reshape(1, height);
     76         Mat grayscale;
     77         grayscale = normal(eigenFace, grayscale);
     78         Mat colorface;
     79         applyColorMap(grayscale, colorface, COLORMAP_BONE);
     80         char* winTitle = new char[128];
     81         sprintf(winTitle, "eigenface_%d", i);
     82         imshow(winTitle, colorface);
     83     }
     84 
     85     //重建人脸
     86     for (int num = min(10, eigenvectors.cols); num < min(300, eigenvectors.cols); num+=15)
     87     {
     88         Mat evs = Mat(eigenvectors, Range::all(), Range(0, num));
     89         Mat projection = LDA::subspaceProject(evs, mean, image[0].reshape(1, 1));
     90         Mat reconstruction= LDA::subspaceReconstruct(evs, mean, projection);
     91 
     92         Mat result = reconstruction.reshape(1, height);
     93         reconstruction = normal(result, reconstruction);
     94         char* winTitle = new char[128];
     95         sprintf(winTitle, "recon_face_%d", num);
     96         imshow(winTitle, reconstruction);
     97     }
     98     
     99     waitKey(0);
    100 }

    二、FisherFace(LDA线性判别分析)

    1、理论介绍

    http://blog.csdn.net/feirose/article/details/39552997

     

    2、流程

    3、PCA和LDA的对比

     

    4、代码(与特征脸代码几乎一致)

    此处只列出修改部分

    55行模型训练    Ptr<BasicFaceRecognizer>model = createFisherFaceRecognizer();
    
    72行显示特征脸  for (int i = 0; i < min(16,eigenvectors.cols); i++)
                       Mat ev = eigenvectors.col(i).clone();
    
    86行重建人脸    for (int num = 0; num < min(16, eigenvectors.cols); num++)

    三、LBPH

     1、原理介绍

    大家可以参考http://blog.csdn.net/xiaomaishiwoa/article/details/46640377

    二、流程

    3、代码

    #include <opencv2/opencv.hpp>
    #include <opencv2/face.hpp>
    
    using namespace cv;
    using namespace cv::face;
    using namespace std;
    
    //对原图归一化
    Mat normal(Mat src, Mat dst) {
        if (src.channels() == 1)//若原图单通道
            normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
        else //否则,原图三通道
            normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
        return dst;
    }
    
    void main() {
        //读取文件,转换为数据流
        string filename = string("at.txt");
        ifstream file(filename.c_str(), ifstream::in);
        if (!file)
            cout << "error" << endl;
    
        string line, path, classlabel;
        vector<Mat>image;
        vector<int>labels;
        char separator = ';';
        while (getline(file,line))
        {
            stringstream liness(line);
            getline(liness, path, separator);
            getline(liness, classlabel);
            if (!path.empty()&&!classlabel.empty())
            {
                //cout << "path:" << path<< endl;
                image.push_back(imread(path, 0));
                labels.push_back(atoi(classlabel.c_str()));
            }
        }
    
        if (image.size() < 1 || labels.size() < 1)
            cout << "invalid image path..." << endl;
    
        int height = image[0].rows;
        int width = image[0].cols;
        //cout << "height:" << height << "," << width<<endl;
    
        //最后一个人为测试样本
        Mat testSample = image[image.size() - 1];
        int testLabel = labels[labels.size() - 1];
        image.pop_back();
        labels.pop_back();
    
        //训练
        Ptr<LBPHFaceRecognizer>model = createLBPHFaceRecognizer();
        model->train(image, labels);
    
        //识别
        int predictLabel = model->predict(testSample);
        cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;
    
        //打印参数
        int radius = model->getRadius();    //中心像素点到周围像素点的距离
        int neibs = model->getNeighbors();    //周围像素点的个数
        int grad_x = model->getGridX();        //将一张图片在x方向分成几块
        int grad_y = model->getGridY();        //将一张图片在y方向分成几块
        double t = model->getThreshold();    //相似度阈值    
        cout << "radius:" << radius << endl;
        cout << "neibs:" << neibs << endl;
        cout << "grad_x:" << grad_x << endl;
        cout << "grad_y:" << grad_y << endl;
        cout << "threshold:" << t<<endl;
        
        waitKey(0);
    }

  • 相关阅读:
    关于近期
    Tips on Importons and Irradiance Particles in mental ray
    给她的歌
    Fatal In Code Generation Of Visual C++
    kdtree vs octree
    疯子的胜利——记6.18毕业晚会
    转凉
    事件与委托的匿名方法使用方法示例
    VS2008使用技巧
    硬链接和软连接的区别
  • 原文地址:https://www.cnblogs.com/little-monkey/p/8118938.html
Copyright © 2011-2022 走看看