zoukankan      html  css  js  c++  java
  • OpenCV学习(36) 人脸识别(1)

    本文主要参考OpenCV人脸识别教程:http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html

    1、OpenCV 从2.4开始支持3个新的人脸识别算法。

      1. Eigenfaces 极值特征脸 createEigenFaceRecognizer()
      2. Fisherfaces createFisherFaceRecognizer()
      3. Local Binary Patterns Histograms局部二值直方图 createLBPHFaceRecognizer()

    2、为了使用这三种算法,我们首先需要准备人脸训练样本,本文采用AT&T Facedatabase(点击下载)提供的人脸训练样本,该样本包括40个人,每人10张照片。照片在不同时间、不同光照、不同表情(睁眼闭眼、笑或者不笑)、不同人脸细节(戴眼镜或者不戴眼镜)下采集。所有的图像都在一个黑暗均匀的背景下,正面竖直人脸(有些有轻微旋转)。图像格式为pgm,图像大小为92*112,我们可以用gimp打开该格式的图像。

         解压AT&T人脸数据库后,我们把目录att_faces拷贝到solution文件目录。在att_faces目录中,有s1,s2,...s40,共40个子目录,每个子目录中有1.pgm...10.pgm,10个文件,每个子目录对应一个人,子目录中的每副照片,对应一个人的各种人脸表情。比如s1中存放的10张人脸样本如下所示:

    imageimageimageimageimageimageimageimageimageimage

          下面我们我们创建一个txt文件facerec_at.txt,格式如下,每一行包括两个字段,中间用“;”分开,第一个字段表示样本图片的路径文件名,第二个参数是一个整数索引,表示第几个人,例如第二个参数都为0,则表示第一个人,后面依次类推:

    ../att_faces/s13/2.pgm;12
    ../att_faces/s13/7.pgm;12
    ../att_faces/s13/6.pgm;12
    ../att_faces/s13/9.pgm;12
    ../att_faces/s13/5.pgm;12
    ../att_faces/s13/3.pgm;12
    ../att_faces/s13/4.pgm;12
    ../att_faces/s13/10.pgm;12
    ../att_faces/s13/8.pgm;12
    ../att_faces/s13/1.pgm;12
    ../att_faces/s17/2.pgm;16
    ../att_faces/s17/7.pgm;16

    ...

    ../att_faces/s38/10.pgm;37
    ../att_faces/s38/8.pgm;37
    ../att_faces/s38/1.pgm;37

    3. Eigenfaces算法描述:

          二维灰度图像p*q大小,是一个m=pq维的向量空间,一个100*100像素大小的图像就是10000维的图像空间。我们可以通过主成分分析算法(PCA)来对m维的图像向量进行降维操作。OpenCV中PCA算法细节,可以参考:http://www.cnblogs.com/mikewolf2002/p/3432243.html,通过PCA算法,我们可以得到k个特征脸,k就是我们选择降到的维数。

    算法描述Algorithmic Description

    1348661752_2689  表示一个随机特征,其中 1348661752_6394 .

    1. 计算均值向量 1348661752_2047

    1348661752_5619

    1. 计算协方差矩阵 S

    1348661765_8882

    1. 计算 的特征值1348661765_1659    和对应的特征向量   1348661765_8011 1348661765_7365
    1. 对特征值进行递减排序,特征向量和它顺序一致. k个主成分也就是k个最大的特征值对应的特征向量。

    x的K个主成份:

    1348661765_6154

    其中1348661776_6981  .

    PCA基的重构:

    1348661776_4408

    其中 1348661776_3871 .

    然后特征脸通过下面的方式进行人脸识别:

    1. 把所有的训练数据投影到PCA子空间
    2. 把待识别图像投影到PCA子空间
    3. 找到训练数据投影后的向量和待识别图像投影后的向量最近的那个。

    4. 程序开始后,我们把样本图像和索引标签读到两个vector变量中。

        // 得到txt文件的名字
        string fn_csv = string("facerec_at_t.txt");
        // 定义一个Mat格式的vector用来保存图像,int格式的vector表示图像索引标签
        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);
            }
        我们选择images中的最后一副图片,作为检测的图像,并把它从images中移除。

    Mat testSample = images[images.size() - 1];
    int testLabel = labels[labels.size() - 1];
    images.pop_back();
    labels.pop_back();

    通过下面的代码,我们输入待检测的图像,返回结果是对应人的索引标签,我们输入图像是第37个人,从结果看是对的。

        //创建特征脸算法模型,并通过样本训练数据
        Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
        model->train(images, labels);

        //通过predict输入待检测的图像,返回结果是索引标签
        int predictedLabel = model->predict(testSample);
        string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);
        cout << result_message << endl;

    image

    5. 通过下面的代码,我们可以求得特征值和特征向量值,并把特征向量显示为特征脸。

    // 特征值和特征向量
    Mat eigenvalues = model->getMat("eigenvalues");
    // And we can do the same to display the Eigenvectors (read Eigenfaces):
    Mat W = model->getMat("eigenvectors");
    //特征值列数是1,行数是特征值的数量399
    //特征向量10304*399,每一列都是一个特征向量
    //每一个特征值对应一个特征向量

    printf("特征值数量 :%d ", eigenvalues.rows);
    printf("特征向量维数 :%d ",W.rows);

    //显示10个特征向量
    for (int i = 0; i < min(10, W.cols); i++)
        {
        string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
        cout << msg << endl;
       // 得到第i个特征向量
        Mat ev = W.col(i).clone();
        // 把特征向量归一化到0-255,便于显示
        Mat grayscale = toGrayscale(ev.reshape(1, height));
        // 用Jet colormap显示灰度图.
        imshow(format("gray image%d", i), grayscale);
        Mat cgrayscale;
        applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
        imshow(format("%d", i), cgrayscale);
        }

    我们总共显示了10个特征向量(特征脸),第一个特征脸的灰度图和color map图如下:

    imageimage

    程序代码:工程FirstOpenCV31

     

     

  • 相关阅读:
    URAL 2067 Friends and Berries (推理,数学)
    URAL 2070 Interesting Numbers (找规律)
    URAL 2073 Log Files (模拟)
    URAL 2069 Hard Rock (最短路)
    URAL 2068 Game of Nuts (博弈)
    URAL 2066 Simple Expression (水题,暴力)
    URAL 2065 Different Sums (找规律)
    UVa 1640 The Counting Problem (数学,区间计数)
    UVa 1630 Folding (区间DP)
    UVa 1629 Cake slicing (记忆化搜索)
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/3432270.html
Copyright © 2011-2022 走看看