本文主要参考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张人脸样本如下所示:

      下面我们我们创建一个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

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

  1. 计算均值向量

  1. 计算协方差矩阵 S

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

x的K个主成份:

其中  .

PCA基的重构:

其中 .

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

  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;

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\n", eigenvalues.rows);
printf("特征向量维数 :%d\n",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图如下:

程序代码:工程FirstOpenCV31

 

 

OpenCV学习(36) 人脸识别(1)的更多相关文章

  1. OpenCV学习(38) 人脸识别(3)

                前面我们学习了基于特征脸的人脸识别,现在我们学习一下基于Fisher脸的人脸识别,Fisher人脸识别基于LDA(线性判别算法)算法,算法的详细介绍可以参考下面两篇教程内容: ...

  2. OpenCV学习(37) 人脸识别(2)

          在前面一篇教程中,我们学习了OpenCV中基于特征脸的人脸识别的代码实现,我们通过代码 Ptr<FaceRecognizer> model = createEigenFaceR ...

  3. OpenCV学习(40) 人脸识别(4)

    在人脸识别模式类中,还实现了一种基于LBP直方图的人脸识别方法.LBP图的原理参照:http://www.cnblogs.com/mikewolf2002/p/3438698.html       在 ...

  4. 【从零学习openCV】IOS7人脸识别实战

    前言 接着上篇<IOS7下的人脸检測>,我们顺藤摸瓜的学习怎样在IOS7下用openCV的进行人脸识别,实际上非常easy,因为人脸检測部分已经完毕,剩下的无非调用openCV的方法对採集 ...

  5. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【一】如何配置caffe属性表

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  6. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【三】VGG网络进行特征提取

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  7. 基于深度学习的人脸识别系统(Caffe+OpenCV+Dlib)【二】人脸预处理

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  8. 基于深度学习的人脸识别系统系列(Caffe+OpenCV+Dlib)——【四】使用CUBLAS加速计算人脸向量的余弦距离

    前言 基于深度学习的人脸识别系统,一共用到了5个开源库:OpenCV(计算机视觉库).Caffe(深度学习库).Dlib(机器学习库).libfacedetection(人脸检测库).cudnn(gp ...

  9. 基于Opencv快速实现人脸识别(完整版)

    无耻收藏网页链接: 基于OpenCV快速实现人脸识别:https://blog.csdn.net/beyond9305/article/details/92844258 基于Opencv快速实现人脸识 ...

随机推荐

  1. 8-4 奖品的价值 uva11491(贪心)

    题意:给出一个n位整数   请删除d个数字 使得剩余数字最大 一开始写成窗口扫描  非常的麻烦易错 只要保证前d+1 降序即可  如果非降序   则删除 很巧妙的贪心 每次读入和已经保存的数组相比较 ...

  2. 001 Anaconda的介绍与安装

    1.官网 www.continuum.io 2.ananconda的版本 同一个版本下对应一个python3与python2,在这里下载使用python 2.7的版本. 3.概述 Anaconda是一 ...

  3. linux config

    1.自定义命令:.bashrc 文件添加自定义命令 2.完成后,命令:source . .bashrc  使配置的自定义命令生效,如果提示没有该命令的情况,用   . .bashrc (注意是2个“点 ...

  4. 预备作业02:体会做中学(Learning By Doing)

    1.很惭愧,我并没有什么技能能强过大家. 2...... 3.我觉得培养一个技能,必须要通过勤勉的练习,认真的学习,还有不断地结合实践. 4.我觉得我学习<程序设计与数据结构>之后应该对程 ...

  5. CSUOJ 1781 阶乘除法

    Description 输入两个正整数 n, m,输出 n!/m!,其中阶乘定义为 n!= 1*2*3*...*n (n>=1). 比如,若 n=6, m=3,则 n!/m!=6!/3!=720 ...

  6. [leetcode sort]75. Sort Colors

    Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...

  7. 数据准备<4>:变量筛选-理论篇

    在上一篇文章<数据准备<3>:数据预处理>中,我们提到降维主要包括两种方式:基于特征选择的降维和基于维度转换的降维,其中基于特征选择的降维通俗的讲就是特征筛选或者变量筛选,是指 ...

  8. 读书笔记_Effective_C++_条款四十:明智而审慎地使用多重继承

    多重继承是一种比较复杂的继承关系,它意味着如果用户想要使用这个类,那么就要对它的父类也了如指掌,所以在项目中会带来可读性的问题,一般我们都会尽量选择用单继承去替代它. 使用多重继承过程容易碰到的问题就 ...

  9. [JAVA] JAVA JDK 安装配置

    JDK 安装 下载安装 下载JDK 从oracle官方网站下载并安装JDK. 下载使用文档 从oracle官方网站下载使用帮助文档. 安装库源文件 源文件位于安装目录的 /Library/Java/J ...

  10. XStream转换Java对象与XML

    1.引入需要的jar包,在pom.xml中配置依赖 <dependency> <groupId>com.thoughtworks.xstream</groupId> ...