《模式识别》大作业人脸识别方法---- 基于PCA 和欧几里得距离判据的模板匹配分类器一、 理论知识1、主成分分析主成分分析是把多个特征映射为少数几个综合特征的一种统计分析方法。
在多特征的研究中,往往由于特征个数太多,且彼此之间存在着一定的相关性,因而使得所观测的数据在一定程度上有信息的重叠。
当特征较多时,在高维空间中研究样本的分布规律就更麻烦。
主成分分析采取一种降维的方法,找出几个综合因子来代表原来众多的特征,使这些综合因子尽可能地反映原来变量的信息,而且彼此之间互不相关,从而达到简化的目的。
主成分的表示相当于把原来的特征进行坐标变换(乘以一个变换矩阵),得到相关性较小(严格来说是零)的综合因子。
1.1 问题的提出一般来说,如果N 个样品中的每个样品有n 个特征12,,n x x x ,经过主成分分析,将它们综合成n 综合变量,即11111221221122221122n nn n n n n nn ny c x c x c x y c x c x c x y c x c x c x =+++⎧⎪=+++⎪⎨⎪⎪=+++⎩ij c 由下列原则决定:1、i y 和j y (i j ≠,i,j = 1,2,...n )相互独立;2、y 的排序原则是方差从大到小。
这样的综合指标因子分别是原变量的第1、第2、……、第n 个主分量,它们的方差依次递减。
1.2 主成分的导出我们观察上述方程组,用我们熟知的矩阵表示,设12n x x X x ⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎣⎦是一个n 维随机向量,12n y y Y y ⎡⎤⎢⎥⎢⎥=⎢⎥⎢⎥⎣⎦是满足上式的新变量所构成的向量。
于是我们可以写成Y=CX,C 是一个正交矩阵,满足CC ’=I 。
坐标旋转是指新坐标轴相互正交,仍构成一个直角坐标系。
变换后的N 个点在1y 轴上有最大方差,而在n y 轴上有最小方差。
同时,注意上面第一条原则,由此我们要求i y 轴和j y 轴的协方差为零,那么要求T YY =Λ12n λλλ⎡⎤⎢⎥⎢⎥Λ=⎢⎥⎢⎥⎣⎦令T R XX =,则T T RC C =Λ经过上面式子的变换,我们得到以下n 个方程111111212112111221122111121211()0()0()0n n n n n n nn n r c r c r c r c r c r c r c r c r c λλλ-+++=+-++=+++-=1.3 主成分分析的结果我们要求解出C ,即解出上述齐次方程的非零解,要求ij c 的系数行列式为0。
最后得出结论i λ是||0R I λ-=的根,i y 的方差为i λ。
然后选取前面p 个贡献率大的分量,这样就实现了降维。
也就是主成分分析的目标。
二、 实现方法1、 获取数据。
在编程时具体是把一幅二维的图像转换成一维的;2、 减去均值。
要使PCA 正常工作,必须减去数据的均值。
减去的均值为每一维的平均,所有的x 值都要减去,同样所有的y 值都要减去,这样处理后的数据都具有0均值;3、 计算协方差矩阵;4、 计算协方差矩阵的特征矢量和特征值。
因为协方差矩阵为方阵,我们可以计算它的特征矢量和特征值,它可以告诉我们数据的有用信息;5、选择成分组成模式矢量现在可以进行数据压缩降低维数了。
如果你观察上一节中的特征矢量和特征值,会注意到那些特征值是十分不同的。
事实上,可以证明对应最大特征值的特征矢量就是数据的主成分。
对应大特征值的特征矢量就是那条穿过数据中间的矢量,它是数据维数之间最大的关联。
一般地,从协方差矩阵找到特征矢量以后,下一步就是按照特征值由大到小进行排列,这将给出成分的重要性级别。
现在,如果你喜欢,可以忽略那些重要性很小的成分,当然这会丢失一些信息,但是如果对应的特征值很小,你不会丢失很多信息。
如果你已经忽略了一些成分,那么最后的数据集将有更少的维数,精确地说,如果你的原始数据是n维的,你选择了前p个主要成分,那么你现在的数据将仅有p维。
现在要做的是你需要组成一个模式矢量,这只是几个矢量组成的矩阵的一个有意思的名字而已,它由你保持的所有特征矢量构成,每一个特征矢量是这个矩阵的一列。
6、获得新数据这是PCA最后一步,也是最容易的一步。
一旦你选择了须要保留的成分(特征矢量)并组成了模式矢量,我们简单地对其进行转置,并将其左乘原始数据的转置:其中rowFeatureVector是由特征矢量作为列组成的矩阵的转置,因此它的行就是原来的特征矢量,而且对应最大特征值的特征矢量在该矩阵的最上一行。
rowdataAdjust是减去均值后的数据,即数据项目在每一列中,每一行就是一维。
FinalData是最后得到的数据,数据项目在它的列中,维数沿着行。
FinalData = rowFeatureVector * rowdataAdjust这将仅仅给出我们选择的数据。
我们的原始数据有两个轴(x和y),所以我们的原始数据按这两个轴分布。
我们可以按任何两个我们喜欢的轴表示我们的数据。
如果这些轴是正交的,这种表达将是最有效的,这就是特征矢量总是正交的重要性。
我们已经将我们的数据从原来的xy轴表达变换为现在的单个特征矢量表达。
如果我们已经忽略了一些特征矢量,则新数据将会用我们保留的矢量表达。
三、matlab编程matlab程序分为三部分。
程序框图如下图所示。
四、总结从书里看我觉得最让人明白模板匹配分类器的一段话,就是“譬如A类有10个训练样品,就有10个模板,B类有8个训练样品,就有8个模板。
任何一个待测样品在分类时与这18个模板都算一算相似度,找出最相似的模板,如果该模板是B类中的一个,就确定待测样品为B类,否则为A类。
”意思很简单吧,算相似度就是算距离。
就是说,模板匹配就要用你想识别的样品与各类中每个样品的各个模板用距离公式计算距离,距离最短的那个就是最相似的。
这样的匹配方法明显的缺点就是在计算量大,存储量大,每个测试样品要对每个模板计算一次相似度,如果模板量大的时候,计算量就十分的大。
五、附录(matlab 程序代码)第一部分:CreatDatabase.mfunction T = CreatDatabase(TrainDatabasePath)%一系列人脸(训练样本T1,T2,……,TM)%函数描述:这个函数将所有训练样本的二维图像转换成一维列向量。
接着,它把这些一维列向量组合到一行里面构造出二维向量T,即每个单元的信息量是一幅图片%参数:TrainDatabasePath --- 训练数据库的路径%返回值:T ---%一个二维矩阵,包含了所有一维向量。
假设所有在训练样本的P幅图像拥有相同的大小(M*N)。
因此,这些一维向量的长度是M*N而且T将是一个MN*P的二维%矩阵%%%%%%%%%%%%%%文件处理%%%%%%%%%%%%%%%%%TrainFiles = dir(TrainDatabasePath);Train_Number = 0;for i = 1:size(TrainFiles,1)t = size(TrainFiles,1);ifnot(strcmp(TrainFiles(i).name,'.')|strcmp(TrainFiles(i).name,'..')|strcmp(TrainFiles(i).name,'Thumb s.db'))Train_Number = Train_Number + 1;endend%%%%%%%%%从一维数组构造成二维数组%%%%%%%%%%%%T = [];for i = 1: Train_Numberstr = int2str(i);str = strcat('\',str,'.pgm');str = strcat(TrainDatabasePath,str);img = imread(str);[irow icol] = size(img);temp = reshape(img',irow*icol,1);%将二维数组变成一维数组T = [T temp];end第二部分:EigenfaceCore.mfunction [m,A,Eigenfaces] = EigenfaceCore(T)%利用主成分分析(PCA)的方法在各张人脸中决定最明显的特征%描述:这个方程首先得到二维数组,包括所有的训练样本向量并且从训练样本中返回3个输出量%参数:T --- 一个二维矩阵,包含了所有一维向量。
假设所有在训练样本的P 幅图像拥有相同的大小(M*N)。
因此,这些一维向量的长度是M*N而且T将是一个MN*P 的二维%矩阵%返回值:m ---(M*Nx1)训练样本的均值% Eigenfaces --- (M*Nx(P-1))训练样本协方差矩阵的特征向量% A --- (M*NxP)中心向量的矩阵%%%%%%%%%计算均值%%%%%%%%%%%m = mean(T,2); %计算样本平均值m = (1/P)*sum(Tj's)Train_Number = size(T,2);%%%%%%%%%计算每个图像与均值的差%%%%%%%%%%%%要使PCA正常工作,必须减去数据的均值。
减去的均值为每一维的平均,所有的x 值都要减去,同样所有的y值都要减去%%%%%%这样处理后的数据都具有0均值%%%A = [];for i = 1 : Train_Numbertemp = double(T(:,i)) - m;A = [A temp]; %再次合并矩阵end%%%%%%%计算协方差矩阵%%%%%%%%%%%%%%%%%计算协方差矩阵的特征矢量和特征值%%%%%%%%L = A'*A; %L代表协方差矩阵C = A*A'.[V D] = eig(L);%计算矩阵A的特征值D(eigenvalues)和特征矩阵V(eigenvectors)%%%%%%选择成分组成模式矢量%%%%%%%%%%%L_eig_vec = [];for i = 1:size(V,2)if(D(i,i)>1)L_eig_vec = [L_eig_vec V(:,1)];endend%%%%%%计算协方差矩阵的特征向量%%%%%%%%%%Eigenfaces = A * L_eig_vec;第三部分:Recognition.mfunction OutputName = Recognition(TestImage, m, A, Eigenfaces)%函数描述:这个函数将源图像提取成特征脸,然后比较它们之间的欧几里得距离%输入量: TestImage ---测试样本的路径% m ---(M*Nx1)训练样本的均值% Eigenfaces --- (M*Nx(P-1))训练样本协方差矩阵的特征向量% A --- (M*NxP)中心向量的矩阵%返回值:OutputName ---在训练样本中的被识别的图像的名字%%%%%%%%%%从中心向量中提取特征脸%%%%%%%%%%%%%%ProjectedImages = [];Train_Number = size(Eigenfaces,2);for i = 1:Train_Numbertemp = Eigenfaces' * A(:,i)ProjectedImages = [ProjectedImages temp];end%%%%%%%%%%%%%%%%从测试样本中提取PCA特征%%%%%%%%%%%%%%% InputImage = imread(TestImage);temp = InputImage(:,:,1);[irow icol] = size(temp);InImage = reshape(temp',irow*icol,1);Difference = double(InImage) - m;ProjectedTestImage = Eigenfaces'*Difference;%%%%%%%%%%%%%计算欧几里得几何距离%%%%%%%%%%%%%%%%%%%%%% Euc_dist = [];for i = 1 : Train_Number,q = ProjectedImages(:,i);temp = (norm(ProjectedTestImage - q))^2;Euc_dist = [Euc_dist temp];end%找出A中最小元素及其索引,把最小值返回给C,最小值索引返回给I。