OpenCV学习(36) 人脸识别(1)
本文主要参考OpenCV人脸识别教程:http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html
1、OpenCV 从2.4开始支持3个新的人脸识别算法。
-
- Eigenfaces 极值特征脸 createEigenFaceRecognizer()
- Fisherfaces createFisherFaceRecognizer()
- 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
- 计算协方差矩阵 S
- 对特征值进行递减排序,特征向量和它顺序一致. k个主成分也就是k个最大的特征值对应的特征向量。
x的K个主成份:
PCA基的重构:
然后特征脸通过下面的方式进行人脸识别:
- 把所有的训练数据投影到PCA子空间
- 把待识别图像投影到PCA子空间
- 找到训练数据投影后的向量和待识别图像投影后的向量最近的那个。
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

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
教你实现语音识别(基于科大讯飞)
1),首先在官网下载相关jar包 2)自定义界面设计: R.layout.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请先到餐厅预定选择店铺" android:textAppearance="?android:attr/textAppearanc...
- 下一篇
OpenCV学习(37) 人脸识别(2)
在前面一篇教程中,我们学习了OpenCV中基于特征脸的人脸识别的代码实现,我们通过代码 Ptr<FaceRecognizer> model = createEigenFaceRecognizer(); 创建了人脸识别模型类,该识别模型类基于特征值人脸。该类有几个重要的成员: int _num_components; double _threshold; vector<Mat> _projections; Mat _labels; Mat _eigenvectors; Mat _eigenvalues; Mat _mean; _num_components表示我们的特征脸识别算法通过PCA降维后保留的特征向量数目,如果在创建人脸识别类时没有指定它的值,则它会保留所有的特征向量,比如我们例子中有399个采样图片,每个图片都为10304维,则最多的特征值数目为399,_num_components的值即为399。_threshold是判定输入的图像属于那一个特征脸时使用。如果类创建时候,没有指定它的值,则默认它会被赋予一个很大的值。我们可以通过下面的代码在类初始化时...
相关文章
文章评论
共有0条评论来说两句吧...