clear all clc close all address=[pwd,'\ORL','\s']; rows=112; cols=92; ClassNum=40; tol_num=10; image_fmt='.bmp'; train_samplesize=5; %-------------------------------------------------------------------------- %------------------------PCA降维 train=1:train_samplesize; test=train_samplesize+1:tol_num; %PCA维数 Eigen_NUM=40; %每类训练样本、测试样本个数 train_num=length(train); test_num=length(test); %读入训练样本,测试样本 [train_sample,train_label]=readsample(address,ClassNum,train,rows,cols,image_fmt); [test_sample,test_label]=readsample(address,ClassNum,test,rows,cols,image_fmt); %训练样本总数、测试样本总数 train_tol=length(train_label); test_tol=length(test_label); %PCA降维 Train_SET=train_sample'; [disc_set,disc_value,Mean_Image]=Eigenface_f(Train_SET,Eigen_NUM); %训练样本、测试样本第一次投影 train_pro=disc_set'*train_sample'; test_pro=disc_set'*test_sample'; %训练样本总体均值及每类均值 total_mean=mean(train_pro,2); EachClassMean=zeros(Eigen_NUM,ClassNum); EachClassNum=zeros(1,ClassNum); for i=1:ClassNum temp=train_pro(:,(i==train_label)); EachClassMean(:,i)=mean(temp,2); EachClassNum(i)=sum((i==train_label)); end %构造Fai_b、Fai_w,以便计算Sb和Sw Fai_b=zeros(Eigen_NUM,ClassNum); Fai_w=zeros(Eigen_NUM,train_tol); for i=1:ClassNum temp=EachClassMean(i)-total_mean; Fai_b(:,i)=sqrt(EachClassNum(i))*temp; end for i=1:train_tol Fai_w(:,i)=train_pro(:,i)-EachClassMean(:,train_label(i)); end Sb=Fai_b*Fai_b'; Sw=Fai_w*Fai_w'; %广义特征值分解,得到LDA的投影矩阵 LDA_dim=ClassNum-1; % LDA_dim=12; [eig_vec,eig_val]=eig(Sb,Sw); d=diag(eig_val)'; [sorted_d,ind]=sort(d,'descend'); sorted_vec=eig_vec(:,ind); W_LDA=sorted_vec(:,1:LDA_dim); %训练样本、测试样本再次投影 train_final=W_LDA'*train_pro; test_final=W_LDA'*test_pro; %调用最近邻分类器对测试样本分类 Sample=test_final'; Training=train_final'; Group=train_label'; k=1; distance='euclidean'; Class = knnclassify(Sample, Training, Group, k, distance); accuracy=sum(test_label==Class')/test_tol; %---------------------------------输出显示---------------------------------- fprintf('每类训练样本数为:%d\n',train_samplesize); fprintf(2,'FisherFace的识别率为:%.2f%%\n\n',accuracy*100);
function [sample,label]=readsample(address,ClassNum,data,rows,cols,image_fmt) %这个函数用来读取样本。 %输入: %address:要读取的样本的路径 %ClassNum:代表要读入样本的类别数 %data:数据 %rows:样本行数 %cols:样本列数 %image_fmt:图片格式 %输出: %sample:样本矩阵,每行为一个样本,每列为一个特征 %label:标签向量 ImageSize=rows*cols; sample_tol=ClassNum*length(data);%读入的样本总数 sample=zeros(sample_tol,ImageSize); label=zeros(1,sample_tol); m=1; for i=1:ClassNum for j=data a=imread(strcat(address,num2str(i),'_',num2str(j),image_fmt)); a=imresize(a,[rows cols]); b=double(reshape(a,1,ImageSize)); sample(m,:)=b; label(m)=i; m=m+1; end end
function [disc_set,disc_value,Mean_Image]=Eigenface_f(Train_SET,Eigen_NUM) %输入: %Train_SET:训练样本集,每列是一个样本,每行一类特征,mxn %Eigen_NUM:投影维数 %输出: %disc_set:特征向量 %disc_value:特征值 %Mean_Image:均值图像 %------------------------------------------------------------------------ % Eigenface computing function [NN,Train_NUM]=size(Train_SET); if NN<=Train_NUM % m<n时 Mean_Image=mean(Train_SET,2); Train_SET=Train_SET-Mean_Image*ones(1,Train_NUM); R=Train_SET*Train_SET'/(Train_NUM-1); %协方差矩阵 [V,S]=Find_K_Max_Eigen(R,Eigen_NUM); disc_value=S; disc_set=real(V); else % m>n时 Mean_Image=mean(Train_SET,2); Train_SET=Train_SET-Mean_Image*ones(1,Train_NUM); R=Train_SET'*Train_SET/(Train_NUM-1); [V,S]=Find_K_Max_Eigen(R,Eigen_NUM); disc_value=S; disc_set=zeros(NN,Eigen_NUM); clear R S; Train_SET=Train_SET/sqrt(Train_NUM-1); for k=1:Eigen_NUM a = Train_SET*V(:,k); b = (1/sqrt(disc_value(k))); disc_set(:,k)=b*a; end disc_set=real(disc_set); end function [Eigen_Vector,Eigen_Value]=Find_K_Max_Eigen(Matrix,Eigen_NUM) [NN,NN]=size(Matrix); [V,S]=eig(Matrix); %Note this is equivalent to; [V,S]=eig(St,SL); also equivalent to [V,S]=eig(Sn,St); % S=diag(S); [S,index]=sort(S); Eigen_Vector=zeros(NN,Eigen_NUM); Eigen_Value=zeros(1,Eigen_NUM); p=NN; for t=1:Eigen_NUM Eigen_Vector(:,t)=V(:,index(p)); Eigen_Value(t)=S(p); p=p-1; if p==0 break; end end