从3D打印到python编程从opencv到人脸识别从win10到树莓

1、如何使用OpenCV进行人脸识别

1、如何使用OpenCV进行人脸识别

友情提示,在看懂代码之前,首先要了解OpenCV的安装和配置,知道如何使用C++,并且已经使用过一些OpenCV的功能。还需要基本的图像处理和矩阵知识。 【gm:我是小明的笔记】因为我只是个翻译,对于我这个才六级的人来说,肯定有一些错误或者翻译不当,还望指正。

1、1、简介简介

从OpenCV2、4开始,新增了一个FaceRecognizer类,我们可以用它来方便的进行人脸识别实验。本文介绍了代码使用和算法原理。 (他写的源码,我们可以在OpenCV的opencvmolescontribdocfacerecsrc下找到,当然你也可以在他的github里找到。如果你想研究源码,可以自然看看,不复杂)

目前支持的算法有

Eigenfaces特征面createEigenFaceRecognizer()

FisherfacescreateFisherFaceRecognizer()

LocalBinaryPatternsHistograms局部二值直方图createLBPHFaceRecognizer()所有例子中的代码下面是OpenCV安装目录下的samples/cpp,所有代码都可以免费用于商业使用或学习。

1、2、人脸识别

对于人类来说,人脸识别非常容易。文献[]告诉我们,只有三天大的婴儿可以分辨出周围熟悉的面孔。那么电脑到底有多难呢?事实上,到目前为止,我们对人类为什么能够区分不同的人知之甚少。面部的内部特征(眼睛、鼻子、嘴巴)还是外部特征(头部形状、发际线)对人类识别更有效?我们如何分析图像以及大脑如何对其进行编码? David Hubel 和 Torsten Wiesel 向我们展示了我们的大脑具有专门的神经细胞来响应不同的场景,例如线条、边缘、角落或运动。显然,我们不认为世界是碎片化的。我们的视觉皮层必须以某种方式将不同的信息来源转化为有用的模式。自动人脸识别是如何从图像中提取有意义的特征,将它们放入有用的表示中,然后对它们进行分类。基于几何特征的人脸识别可能是最直观的人脸识别方法。 []中描述了**个自动人脸识别系统:标记点(眼睛,耳朵,鼻子等的位置)用于构造特征向量(点之间的距离,角度等)。通过计算测试图像和训练图像的特征向量的欧几里德距离来进行识别。这样的方法对光照的变化是鲁棒的,但它也有一个巨大的缺点:标记点的确定非常复杂,即使使用***的算法。文献[]中描述了一些最近关于几何特征人脸识别的工作。大型数据库使用22维特征向量,仅几何特征无法为人脸识别提供足够的信息。

文献[]中描述了特征脸方法。他描述了一种识别人脸的综合方法:人脸图像就是一个点,这个点就是从高维图像空间中找到它在低维空间中的表示,因此分类变得非常简单。低维子空间低维是使用主成分分析(PCA)找到的,它可以找到方差**的轴。虽然这种转换是从**重构的角度考虑的,但他并没有考虑标注问题。 [gm:要理解这段话需要一些机器学习知识]。想象一种情况,如果变化是基于外部源,例如光。轴的**方差不一定包含任何判别信息,因此此时分类是不可能的。因此,提出了一种使用线性判别分析(LDA)的特定类投影方法来解决人脸识别问题[]。基本思想之一是**化类外方差,同时最小化类内方差。

近年来,出现了各种局部特征提取方法。为了避免输入图像的高维数据,提出了一种仅使用局部特征来描述图像的方法。提取的特征(希望如此)对局部遮挡、光照变化、小样本等更加鲁棒。局部特征提取的方法有Gabor Wavelets([])、离散傅立叶变换(DiscreteCosinusTransform, DCT)([])、Local Binary Patterns(LocalBinaryPatterns, LBP)([])。应该使用什么方法来提取时间空间中的局部特征仍然是一个悬而未决的研究问题,因为空间信息是潜在的有用信息。

1、3、 FaceDatabase

让我们获取一些数据进行实验。我不想在这里成为一个天真的例子。我们正在研究人脸识别,所以我们需要一张真实的人脸图像!你可以自己创建自己的数据集,也可以从这里下载一个(http://face-.

AT&TFacedatabase 也称为ORL人脸数据库,40个人,每人10张照片。不同时间和不同光线下的照片,不同表情(睁眼和闭眼,微笑或不微笑),收集不同的面部细节(戴眼镜或不戴眼镜)。所有图像都收集在深色均匀背景上,正面垂直的脸(有些有轻微旋转)。
YaleFacedatabaseAORL 数据库更适合初始测试,但它是一个简单的数据库,特征脸的识别率可以达到 97%,所以你很难用其他方法得到更好的改进。Yale 人脸数据库是一个初始实验用的更好的数据库,因为识别问题比较复杂。这个数据库包括15个人(14男1女),每个人有11张灰度图,大小为*像素。数据库有光线变化(分RAL光,左光,右光),表情变化(快乐,正常,悲伤,困,惊讶,眨眼),眼镜(戴眼镜或不戴眼镜)。

坏消息是它。不能公开下载,可能是原服务器坏了。但是我们可以找到一些镜像(例如MIT),但我不能保证其完整性。如果需要自己裁剪和校准图片,可以看我的笔记(

ExtendedYaleFacedatabaseB 这个数据库包含38张人物图片,都是裁剪出来的。这个数据库的重点是测试特征提取对变化的鲁棒性在光照方面,因为图像的表情、遮挡等都没有改变。我觉得这个数据库太大了,不适合这个对于本文的实验,我推荐使用ORL数据库。

准备数据
我们从网上下载了数据,需要在程序中读取,我决定用一个CSV文件来读取,一个CSV文件包含文件名,后面跟着一个标签。

/path/to /image.ext;0

假设/path/to/image.ext是一张图片,就像windows image0、jpg下的c:/faces/person0/一样,**我们给它一个标签0、这个标签类似到人名,所以同一人的照片标签是一样的,我们识别下载的ORL数据库,可以得到如下结果:

。 /at/s1/1、pgm;0

./at/s1/2、pgm;0、/at/s2/1、pgm;1

./at/s2/2、pgm;1、 /at//1、pgm;39

./at//2、pgm;39

想象一下我解压了图片在D:/data/at下,CSV文件在D:/data /at.txt。现在您可以根据自己的情况进行修改和替换。成功创建 CSV 文件后,您可以像这样运行示例程序:

facerec_demo.exeD:/data/at.txt

您不需要手动创建 CSV 文件,我已经编写了一个 Python 程序来做到这一点。

[gm:告诉我一个我实现的方法

如果你知道cmd命令,或者DOS命令,那么你打开命令控制台。假设我们的图片放在J:下的Faces文件夹中,可以输入如下语句:

J:FacesORL>dir/b/s*.bmp>at.txt

然后你打开at . txt文件中可能会看到如下内容(以下0、1、标签是自己添加的):

. . . .

J:FacesORLs11、bmp;0

J:FacesORLs110、bmp;0

J:FacesORLs12、bmp; 0

J:FacesORLs13、bmp;0

J:FacesORLs14、bmp;0

J:FacesORLs15、bmp ;0

J:FacesORLs16、bmp;0

J:FacesORLs17、bmp;0

J:FacesORLs18、 bmp;0

J:FacesORLs19、bmp;0

J:FacesORL1、bmp;1

J:FacesORL10、bmp ;1

J:FacesORL2、bmp;1

J:FacesORL3、bmp;1

J:FacesORL4、bmp;1

J:FacesORL5、bmp;1

J:FacesORL6、bmp;1

。 . . .

当然还有C++编程等方法可以做得更好。看了这篇文章的回复,如果很多人需要,我会写这部分代码。 (遍历多个文件夹并标记它们) Eigenfaces

正如我们所说,图像表示的问题是他的高维问题。二维灰度图像p*q的大小是一个m=qp维的向量空间,所以一个大小为*pixel的图像就是一个10维的图像空间。问题是,所有维度空间对我们都有用吗?我们可以做一个决定,如果数据有任何差异,我们可以找到主要信息来了解主要信息。主成分分析(PCA)由Karl Pearson()独立发表,HaroldHotelling()将一些可能相关的变量转化为更小的不相关的子集。其思想是,一个高维数据集通常由相关变量表示,因此只有一些维数据是有意义的,并且包含最多的信息。 PCA方法在数据中找出方差**的方向,称为主成分。

AlgorithmicDescription

设2代表随机特​​征,其中3、

计算均值向量4计算协方差矩阵S计算特征值7和对应的特征向量89

减小特征值进行排序,特征向量一致与它的顺序。 K 个主成分是对应于 k 个**特征值的特征向量。

x的K个主要成分:11、

PCA基的重建:13、

然后特征人脸通过以下方法识别:

A.将所有训练数据投影到 PCA 子空间

B。将要识别的图像投影到 PCA 子空间

C。找到投影训练数据的最近向量和待识别图像的投影向量。

还有一个问题需要解决。例如,如果我们有一张图片,每个*像素大小,那么PCA需要求解协方差矩阵14、X的大小为*,那么我们将得到一个*大小的矩阵,大约需要0、8GB的内存。解决这个问题并不容易,所以我们需要另一种策略。把它转一下再问,特征向量没有变化。它在文献[]中有描述。

[gm:让我们自己搜索这个 PCA。这里解释不清楚,不适合初学者]

在OpenCV中使用特征脸EigenfacesinOpenCV

给出示例程序源码

#include”opencv2/core/core.hpp”

#include “opencv2/contrib/contrib.hpp”

#include”opencv2/highgui/highgui.hpp”

#include

#include

#include

usingnamespacecv;

usingnamespacestd;

staticMatnorm_0_(InputArray_src){

Matsrc=_src.getMat();

//创建并返回一个归一化图像矩阵:

Matdst;

switch(src .channels())(

case1:

cv::normalize(_src,dst,0,,NORM_MINMAX,CV_8UC1);

break;

case3:

cv::normalize(_src ,dst,0,,NORM_MINMAX,CV_8UC3);

break;

default:

src.copyTo(dst);

break;returndst;//使用CSV文件读取图片和标签,主要是使用 stringstream 和 getline 方法

staticvoidread_csv(conststring&filename,vector &images,vector &labels,charseparator=’;’){

std::ifstreamfile(filename.c_str(),ifstream::in) ;

if(!file){

stringerror_message=”Novalidinputfilewasgiven,pleasecheckthegivenfilename.”;

CV_Error(CV_StsBadArg,error_message);stringline,path,classlabel;

while(getline(file,line)){

stringstreamliness(line);

getline(liness,path,separator);

getline(liness,classlabel);

if(!path.empty()&& !classlabel.empty()){

images.push_back(imread(path, 0));

labels.push_back(atoi(classlabel.c_str()));}

intmain(intargc,constchar* argv[]){

//检测合法命令并显示用法

//如果没有参数输入,退出! .

if(argc<2){

cout<<"用法:"< <<" “<

exit(1) ;stringoutput_folder;

if(argc==3){

output_folder=string(argv[2]);//读取你的CSV文件路径。

stringfn_csv=string(argv[1]);

//2 个容器,用于存储图像数据和相应的标签

vector images;

vector labels;

//读取数据。如果文件不合法,会报错

//输入的文件名已经存在。

try{

read_csv(fn_csv,images,labels);

}catch(cv::Exception&e) {

cerr<<"Erroropeningfile ""< <<"".Reason:"< <

//文件有问题,我们不能做任何事情,我们退出

exit(1); //如果没有足够的图片,我们必须退出。

if(images.size()<=1){

stringerror_message=”.Pleaseaddmoreimagestoyourdataset!”;

CV_Error(CV_StsError,error_message) ; //获取**张照片的高度。下面的图片

//需要变形到原来的大小

intheight=images[0].rows;

//下面几行代码只是把**一张图片从你的数据中去掉set.

//[gm: 自然要根据自己的需要修改。他在这里简化了很多问题]

MattestSample=images[images.size()-1];

inttestLabel=labels[labels.size()-1];

images.pop_back();

labels.pop_back();

//以下几行创建了一个特征人脸模型,用于人脸识别,

//从CSV文件中读取的图像和标签中对其进行训练。

//T 这里是一个完整的PCA变换

//如果你只想保留10个主成分,使用下面的代码

//cv::createEigenFaceRecognizer(10);//如果你还想要使用置信度阈值进行初始化,使用如下语句:

//cv::createEigenFaceRecognizer(10,.0);//如果使用所有特征并使用阈值,则使用以下语句:

// cv::createEigenFaceRecognizer(0,.0);Ptr model=createEigenFaceRecognizer();

model->train(images,labels);

//下面是对测试图像的预测,和PredictedLabel为预测标签结果

intpredictedLabel=model->predict(testSample);//还有一个调用方法,可以同时获取结果和获取阈值:

//intpredictedLabel= -1;

//doubleconfidence=0、0;

//model->predict(testSample,predictedLabel,confidence);stringresult_message=format(“Predictedclass=%d/Actualclass=%d.”,predictedLabel,testLabel) ;

cout< <

//这里以获取特征脸模型的特征值为例,使用getMat方法:

Mateigenvalues=model->getMat(“eigenvalues”);

//特征向量也可以获得:

MatW =model->getMat(“eigenvectors”);

//获取训练图像的均值向量

Matmean=model->getMat(“mean”);

//现实还是保存:

if (argc==2){

imshow(“mean”,norm_0_(mean.reshape(1,images[0].rows)));

}else{
imwrite(format(“%s /mean.png”,output_folder.c_str()),norm_0_(mean.reshape(1,images[0].rows)));//现实还是保存特征脸:
for(inti=0;i

stringmsg=format(“Eigenvalue#%d=%.5f”,i,eigenvalues.at (i) );

cout< <

//得到#i特征

Matev=W.col(i).clone();

//变成原来的大小,为了将数据显示归一化为0~。

Matgrayscale=norm_0_ (ev.reshape(1,height));

//使用伪色显示结果,为了更好的感觉。
Matcgrayscale;

applyColorMap(grayscale,cgraysc ale,COLORMAP_JET);

//显示或保存:

if(argc==2){

imshow(format(“eigenface_%d”,i),cgrayscale);

}else{

imwrite(format(“%s/eigenface_%d.png”,output_folder.c_str(),i),norm_0_(cgrayscale));//在一些预测过程中,显示​​或保存重构图像:

for(intnum_components=10;num_components <;num_components+=15){

//截取模型中的一部分特征向量

Matevs=Mat(W,Range::all(),Range(0,num_components) ));

Matprojection=subspaceProject (evs,mean,images[0].reshape(1,1));

Matreconstruction=subspaceReconstruct(evs,mean,projection);

//归一化的结果,在显示顺序:

reconstruction= norm_0_(reconstruction.reshape(1,images[0].rows));

//显示或保存:

if(argc==2){

imshow (format(“e igenface_reconstruction_%d”,num_components),reconstruction);

}else{

imwrite(format(“%s/eigenface_reconstruction_%d.png”,output_folder.c_str(),num_components),reconstruction );//如果我们没有把它存储在文件中,就显示它,这里我们暂时使用等待键盘输入:

if(argc==2){

waitKey(0);return0;

1、如何使用OpenCV进行人脸识别

1、如何使用OpenCV进行人脸识别

友情提示,在看懂代码之前,首先要了解OpenCV的安装和配置,知道如何使用C++,并且已经使用过一些OpenCV的功能。还需要基本的图像处理和矩阵知识。 【gm:我是小明的笔记】因为我只是个翻译,对于我这个才六级的人来说,肯定有一些错误或者翻译不当,还望指正。

1、1、简介简介

从OpenCV2、4开始,新增了一个FaceRecognizer类,我们可以用它来方便的进行人脸识别实验。本文介绍了代码使用和算法原理。 (他写的源码,我们可以在OpenCV的opencvmolescontribdocfacerecsrc下找到,当然你也可以在他的github里找到。如果你想研究源码,可以自然看看,不复杂)

目前支持的算法有

Eigenfaces特征面createEigenFaceRecognizer()

FisherfacescreateFisherFaceRecognizer()

LocalBinaryPatternsHistograms局部二值直方图createLBPHFaceRecognizer()所有例子中的代码下面是OpenCV安装目录下的samples/cpp,所有代码都可以免费用于商业使用或学习。

1、2、人脸识别

对于人类来说,人脸识别非常容易。文献[]告诉我们,只有三天大的婴儿可以分辨出周围熟悉的面孔。那么电脑到底有多难呢?事实上,到目前为止,我们对人类为什么能够区分不同的人知之甚少。面部的内部特征(眼睛、鼻子、嘴巴)还是外部特征(头部形状、发际线)对人类识别更有效?我们如何分析图像以及大脑如何对其进行编码? David Hubel 和 Torsten Wiesel 向我们展示了我们的大脑具有专门的神经细胞来响应不同的场景,例如线条、边缘、角落或运动。显然,我们不认为世界是碎片化的。我们的视觉皮层必须以某种方式将不同的信息来源转化为有用的模式。自动人脸识别是如何从图像中提取有意义的特征,将它们放入有用的表示中,然后对它们进行分类。基于几何特征的人脸识别可能是最直观的人脸识别方法。 []中描述了**个自动人脸识别系统:标记点(眼睛,耳朵,鼻子等的位置)用于构造特征向量(点之间的距离,角度等)。通过计算测试图像和训练图像的特征向量的欧几里德距离来进行识别。这样的方法对光照的变化是鲁棒的,但它也有一个巨大的缺点:标记点的确定非常复杂,即使使用***的算法。文献[]中描述了一些最近关于几何特征人脸识别的工作。大型数据库使用22维特征向量,仅几何特征无法为人脸识别提供足够的信息。

文献[]中描述了特征脸方法。他描述了一种识别人脸的综合方法:人脸图像就是一个点,这个点就是从高维图像空间中找到它在低维空间中的表示,因此分类变得非常简单。低维子空间低维是使用主成分分析(PCA)找到的,它可以找到方差**的轴。虽然这种转换是从**重构的角度考虑的,但他并没有考虑标注问题。 [gm:要理解这段话需要一些机器学习知识]。想象一种情况,如果变化是基于外部源,例如光。轴的**方差不一定包含任何判别信息,因此此时分类是不可能的。因此,提出了一种使用线性判别分析(LDA)的特定类投影方法来解决人脸识别问题[]。基本思想之一是**化类外方差,同时最小化类内方差。

近年来,出现了各种局部特征提取方法。为了避免输入图像的高维数据,提出了一种仅使用局部特征来描述图像的方法。提取的特征(希望如此)对局部遮挡、光照变化、小样本等更加鲁棒。局部特征提取的方法有Gabor Wavelets([])、离散傅立叶变换(DiscreteCosinusTransform, DCT)([])、Local Binary Patterns(LocalBinaryPatterns, LBP)([])。应该使用什么方法来提取时间空间中的局部特征仍然是一个悬而未决的研究问题,因为空间信息是潜在的有用信息。

1、3、 FaceDatabase

让我们获取一些数据进行实验。我不想在这里成为一个天真的例子。我们正在研究人脸识别,所以我们需要一张真实的人脸图像!你可以自己创建自己的数据集,也可以从这里下载一个(http://face-.

AT&TFacedatabase 也称为ORL人脸数据库,40个人,每人10张照片。不同时间和不同光线下的照片,不同表情(睁眼和闭眼,微笑或不微笑),收集不同的面部细节(戴眼镜或不戴眼镜)。所有图像都收集在深色均匀背景上,正面垂直的脸(有些有轻微旋转)。
YaleFacedatabaseAORL 数据库更适合初始测试,但它是一个简单的数据库,特征脸的识别率可以达到 97%,所以你很难用其他方法得到更好的改进。Yale 人脸数据库是一个初始实验用的更好的数据库,因为识别问题比较复杂。这个数据库包括15个人(14男1女),每个人有11张灰度图,大小为*像素。数据库有光线变化(分RAL光,左光,右光),表情变化(快乐,正常,悲伤,困,惊讶,眨眼),眼镜(戴眼镜或不戴眼镜)。

坏消息是它。不能公开下载,可能是原服务器坏了。但是我们可以找到一些镜像(例如MIT),但我不能保证其完整性。如果需要自己裁剪和校准图片,可以看我的笔记(

ExtendedYaleFacedatabaseB 这个数据库包含38张人物图片,都是裁剪出来的。这个数据库的重点是测试特征提取对变化的鲁棒性在光照方面,因为图像的表情、遮挡等都没有改变。我觉得这个数据库太大了,不适合这个对于本文的实验,我推荐使用ORL数据库。

准备数据
我们从网上下载了数据,需要在程序中读取,我决定用一个CSV文件来读取,一个CSV文件包含文件名,后面跟着一个标签。

/path/to /image.ext;0

假设/path/to/image.ext是一张图片,就像windows image0、jpg下的c:/faces/person0/一样,**我们给它一个标签0、这个标签类似到人名,所以同一人的照片标签是一样的,我们识别下载的ORL数据库,可以得到如下结果:

。 /at/s1/1、pgm;0

./at/s1/2、pgm;0、/at/s2/1、pgm;1

./at/s2/2、pgm;1、 /at//1、pgm;39

./at//2、pgm;39

想象一下我解压了图片在D:/data/at下,CSV文件在D:/data /at.txt。现在您可以根据自己的情况进行修改和替换。成功创建 CSV 文件后,您可以像这样运行示例程序:

facerec_demo.exeD:/data/at.txt

您不需要手动创建 CSV 文件,我已经编写了一个 Python 程序来做到这一点。

[gm:告诉我一个我实现的方法

如果你知道cmd命令,或者DOS命令,那么你打开命令控制台。假设我们的图片放在J:下的Faces文件夹中,可以输入如下语句:

J:FacesORL>dir/b/s*.bmp>at.txt

然后你打开at . txt文件中可能会看到如下内容(以下0、1、标签是自己添加的):

. . . .

J:FacesORLs11、bmp;0

J:FacesORLs110、bmp;0

J:FacesORLs12、bmp; 0

J:FacesORLs13、bmp;0

J:FacesORLs14、bmp;0

J:FacesORLs15、bmp ;0

J:FacesORLs16、bmp;0

J:FacesORLs17、bmp;0

J:FacesORLs18、 bmp;0

J:FacesORLs19、bmp;0

J:FacesORL1、bmp;1

J:FacesORL10、bmp ;1

J:FacesORL2、bmp;1

J:FacesORL3、bmp;1

J:FacesORL4、bmp;1

J:FacesORL5、bmp;1

J:FacesORL6、bmp;1

。 . . .

当然还有C++编程等方法可以做得更好。看了这篇文章的回复,如果很多人需要,我会写这部分代码。 (遍历多个文件夹并标记它们) Eigenfaces

正如我们所说,图像表示的问题是他的高维问题。二维灰度图像p*q的大小是一个m=qp维的向量空间,所以一个大小为*pixel的图像就是一个10维的图像空间。问题是,所有维度空间对我们都有用吗?我们可以做一个决定,如果数据有任何差异,我们可以找到主要信息来了解主要信息。主成分分析(PCA)由Karl Pearson()独立发表,HaroldHotelling()将一些可能相关的变量转化为更小的不相关的子集。其思想是,一个高维数据集通常由相关变量表示,因此只有一些维数据是有意义的,并且包含最多的信息。 PCA方法在数据中找出方差**的方向,称为主成分。

AlgorithmicDescription

设2代表随机特​​征,其中3、

计算均值向量4计算协方差矩阵S计算特征值7和对应的特征向量89

减小特征值进行排序,特征向量一致与它的顺序。 K 个主成分是对应于 k 个**特征值的特征向量。

x的K个主要成分:11、

PCA基的重建:13、

然后特征人脸通过以下方法识别:

A.将所有训练数据投影到 PCA 子空间

B。将要识别的图像投影到 PCA 子空间

C。找到投影训练数据的最近向量和待识别图像的投影向量。

还有一个问题需要解决。例如,如果我们有一张图片,每个*像素大小,那么PCA需要求解协方差矩阵14、X的大小为*,那么我们将得到一个*大小的矩阵,大约需要0、8GB的内存。解决这个问题并不容易,所以我们需要另一种策略。把它转一下再问,特征向量没有变化。它在文献[]中有描述。

[gm:让我们自己搜索这个 PCA。这里解释不清楚,不适合初学者]

在OpenCV中使用特征脸EigenfacesinOpenCV

给出示例程序源码

#include”opencv2/core/core.hpp”

#include “opencv2/contrib/contrib.hpp”

#include”opencv2/highgui/highgui.hpp”

#include

#include

#include

usingnamespacecv;

usingnamespacestd;

staticMatnorm_0_(InputArray_src){

Matsrc=_src.getMat();

//创建并返回一个归一化图像矩阵:

Matdst;

switch(src .channels())(

case1:

cv::normalize(_src,dst,0,,NORM_MINMAX,CV_8UC1);

break;

case3:

cv::normalize(_src ,dst,0,,NORM_MINMAX,CV_8UC3);

break;

default:

src.copyTo(dst);

break;returndst;//使用CSV文件读取图片和标签,主要是使用 stringstream 和 getline 方法

staticvoidread_csv(conststring&filename,vector &images,vector &labels,charseparator=’;’){

std::ifstreamfile(filename.c_str(),ifstream::in) ;

if(!file){

stringerror_message=”Novalidinputfilewasgiven,pleasecheckthegivenfilename.”;

CV_Error(CV_StsBadArg,error_message);stringline,path,classlabel;

while(getline(file,line)){

stringstreamliness(line);

getline(liness,path,separator);

getline(liness,classlabel);

if(!path.empty()&& !classlabel.empty()){

images.push_back(imread(path, 0));

labels.push_back(atoi(classlabel.c_str()));}

intmain(intargc,constchar* argv[]){

//检测合法命令并显示用法

//如果没有参数输入,退出! .

if(argc<2){

cout<<"用法:"< <<" “<

exit(1) ;stringoutput_folder;

if(argc==3){

output_folder=string(argv[2]);//读取你的CSV文件路径。

stringfn_csv=string(argv[1]);

//2 个容器,用于存储图像数据和相应的标签

vector images;

vector labels;

//读取数据。如果文件不合法,会报错

//输入的文件名已经存在。

try{

read_csv(fn_csv,images,labels);

}catch(cv::Exception&e) {

cerr<<"Erroropeningfile ""< <<"".Reason:"< <

//文件有问题,我们不能做任何事情,我们退出

exit(1); //如果没有足够的图片,我们必须退出。

if(images.size()<=1){

stringerror_message=”.Pleaseaddmoreimagestoyourdataset!”;

CV_Error(CV_StsError,error_message) ; //获取**张照片的高度。下面的图片

//需要变形到原来的大小

intheight=images[0].rows;

//下面几行代码只是把**一张图片从你的数据中去掉set.

//[gm: 自然要根据自己的需要修改。他在这里简化了很多问题]

MattestSample=images[images.size()-1];

inttestLabel=labels[labels.size()-1];

images.pop_back();

labels.pop_back();

//以下几行创建了一个特征人脸模型,用于人脸识别,

//从CSV文件中读取的图像和标签中对其进行训练。

//T 这里是一个完整的PCA变换

//如果你只想保留10个主成分,使用下面的代码

//cv::createEigenFaceRecognizer(10);//如果你还想要使用置信度阈值进行初始化,使用如下语句:

//cv::createEigenFaceRecognizer(10,.0);//如果使用所有特征并使用阈值,则使用以下语句:

// cv::createEigenFaceRecognizer(0,.0);Ptr model=createEigenFaceRecognizer();

model->train(images,labels);

//下面是对测试图像的预测,和PredictedLabel为预测标签结果

intpredictedLabel=model->predict(testSample);//还有一个调用方法,可以同时获取结果和获取阈值:

//intpredictedLabel= -1;

//doubleconfidence=0、0;

//model->predict(testSample,predictedLabel,confidence);stringresult_message=format(“Predictedclass=%d/Actualclass=%d.”,predictedLabel,testLabel) ;

cout< <

//这里以获取特征脸模型的特征值为例,使用getMat方法:

Mateigenvalues=model->getMat(“eigenvalues”);

//特征向量也可以获得:

MatW =model->getMat(“eigenvectors”);

//获取训练图像的均值向量

Matmean=model->getMat(“mean”);

//现实还是保存:

if (argc==2){

imshow(“mean”,norm_0_(mean.reshape(1,images[0].rows)));

}else{
imwrite(format(“%s /mean.png”,output_folder.c_str()),norm_0_(mean.reshape(1,images[0].rows)));//现实还是保存特征脸:
for(inti=0;i

stringmsg=format(“Eigenvalue#%d=%.5f”,i,eigenvalues.at (i) );

cout< <

//得到#i特征

Matev=W.col(i).clone();

//变成原来的大小,为了将数据显示归一化为0~。

Matgrayscale=norm_0_ (ev.reshape(1,height));

//使用伪色显示结果,为了更好的感觉。
Matcgrayscale;

applyColorMap(grayscale,cgraysc ale,COLORMAP_JET);

//显示或保存:

if(argc==2){

imshow(format(“eigenface_%d”,i),cgrayscale);

}else{

imwrite(format(“%s/eigenface_%d.png”,output_folder.c_str(),i),norm_0_(cgrayscale));//在一些预测过程中,显示​​或保存重构图像:

for(intnum_components=10;num_components <;num_components+=15){

//截取模型中的一部分特征向量

Matevs=Mat(W,Range::all(),Range(0,num_components) ));

Matprojection=subspaceProject (evs,mean,images[0].reshape(1,1));

Matreconstruction=subspaceReconstruct(evs,mean,projection);

//归一化的结果,在显示顺序:

reconstruction= norm_0_(reconstruction.reshape(1,images[0].rows));

//显示或保存:

if(argc==2){

imshow (format(“e igenface_reconstruction_%d”,num_components),reconstruction);

}else{

imwrite(format(“%s/eigenface_reconstruction_%d.png”,output_folder.c_str(),num_components),reconstruction );//如果我们没有把它存储在文件中,就显示它,这里我们暂时使用等待键盘输入:

if(argc==2){

waitKey(0);return0;

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注