www.pudn.com > wt_pca.rar > wt_pca.m
function recognize = wt_pca (path,persons,numface,numtrain,numpc)
% RECOGNIZE = MY_PCA(PATH,PERSONS,NUMFACE,NUMTRAIN,NUMPC)
% Recognize 正确识别率; path 存放人脸图像的路径;
% persons 类别数; numface 每个类别的样本数;numtrain 训练样本的个数;
% numpc 主元个数
% 例:用orl人脸库,训练样本为8,选取主元数目为10
path='E:\orl\';
persons=40;
numface=10;
numtrain=8;
numpc=10;
%recognize=wt_pca (path,persons,numface,numtrain,numpc)
% 结果显示: 正确识别率:97.5%
% 《1》生成路径
%******************************************************************************************
for i=1:persons
str=num2str(i);
if i<10
str=['0',str];
end
Folder(i,:)=[path,'s',str,'\'];
end
BMPfile =['01.bmp';'02.bmp';'03.bmp';'04.bmp';'05.bmp';
'06.bmp';'07.bmp';'08.bmp';'09.bmp';'10.bmp'];
% <<< 2 >>> 计算参数
%=====================================================================
numtest=numface-numtrain; % 每个人参加测试的样本数
all_train=persons*numtrain; % 所有参加训练的样本数
all_test=persons*numtest; % 所有参加测试的样本数
% 《2》样本训练,由选取的主元数目生成正交的子空间 ******************************************************************************************
% <1> 装载训练样本,变成列向量,并组成矩阵 A -----------------------------------------------------------------
for i=1:persons
for j=1:numtrain
img_name=[Folder(i,:),BMPfile(j,:)];
img=double(imread(img_name)); % 读入图像并转换为双精度以便计算
img=wpdec2(img,2,'db2'); % 使用小波包db2进行1层分解
img=wpcoef(img,[1 0]); %提取节点(1,0)的系数
[c1,s1]=wavedec2(img,3,'haar'); % 用小波函数haar对信号进行1尺度分解
img=appcoef2(c1,s1,'haar'); % 提取低频系数
%img=imresize(img,[28 23],'bilinear'); % 用imresize改变尺寸 28by23
if i==1 & j==1 % 用第一个样本来确定人脸样本的大小
size_img=size(img);
Dim=size_img(1)*size_img(2);
A=zeros(Dim,all_train);
end
img=reshape(img,Dim,1); % 变换为列向量
A(:,numtrain*(i-1)+j)=img; % 成为矩阵中的一列
end
end
% <2> 计算平均脸 eface --------------------------------------------------------------------------------------------------
eface=zeros(Dim,1); % 累加器
for i=1:all_train
eface=eface+A(:,i);
end
eface=eface/all_train; % 平均脸
% <3> 训练样本规范化 ------------------------------------------------------------------------------------------------
for i=1:all_train
A(:,i)=A(:,i)-eface;
end
% <4> 计算协方差矩阵 Q ----------------------------------------------------------------------------------------------
Q=A*A';
% <5> 计算特征值 D ,特征向量 V -----------------------------------------------------------------------------------
[V,D]=eig(Q);
% <6> 抽取最大的 numpc 个特征值对应的特征向量, 组成正交子空间 W --------------------------------
[ld,ind]=sort(diag(D));
landa=ld(end:-1:1);
Ind=ind(end:-1:1);
for i=1:numpc
W(:,i)=V(:,Ind(i)); % V is a Dim(size_img(1)*size_img(2);112 by 92) matrix
% W_mo=norm(W(:,i));
end
% <7> 投影到子空间,提取得训练样本的特征 -------------------------------------------------------------------------
Feature_A = W'*A; % Feature_A is numpc*1 matrix
% 《3》测试
%******************************************************************************************
% <8> 装载测试样本, 变成列向量, 并组成矩阵 B ----------------------------------------------------------
tic;
B=zeros(Dim,all_test);
for i=1:persons
for j=(numtrain+1):numface
img_name=[Folder(i,:),BMPfile(j,:)];
img=double(imread(img_name)); % 读入图像并转换为双精度以便计算
img=wpdec2(img,2,'db2'); % 使用小波包db2进行两层分解
img=wpcoef(img,[1 0]); %提取节点(1,0)的系数
[c1,s1]=wavedec2(img,3,'haar'); %用小波函数haar对信号进行3尺度分解
img=appcoef2(c1,s1,'haar'); %提取低频系数
%img=imresize(img,[22 18],'bilinear'); % 用imresize改变尺寸 22by18
img=reshape(img,Dim,1); % 变换为列向量
B(:,numtest*(i-1)+(j-numtrain))=img; % 成为矩阵中的一列
end
end
% <9> 测试样本规范化 -------------------------------------------------------------------------------------------
for i=1:all_test
B(:,i)=B(:,i)-eface;
end
% <10> 测试样本的投影特征 ----------------------------------------------------------------------------------
Feature_B=W'*B;
% <11> 结果分析-------------------------------------------------------------------------------------------------
err=0; % 错判计数器
Aclass=zeros(all_train,1); % 训练样本的类别
Bclass=zeros(all_test,1); % 测试样本的本应属于的类别
Bresult=zeros(all_test,1); % 测试样本被判别属于的类别
for ac=1:all_train
Aclass(ac)=ceil(ac/numtrain); % 训练样本的类别
end
for bc=1:all_test
Bclass(bc)=ceil(bc/numtest); % 测试样本的本应类别
end
for i=1:all_test
Dij=zeros(all_train,1); % 第 i 个测试样本到所有训练样本的距离
for j=1:all_train
FD=Feature_B(:,i)-Feature_A(:,j); % 第 i 个测试样本与第 j 个训练样本的各个投影特征向量的差
Dij(j)=norm(FD); % 两特征向量差的二范数即为两者的欧氏距离
end
[Min,IND]=sort(Dij); % 从小到大索引,取最小的那个类别即为结果
Bresult(i)=Aclass(IND(1));
if Bresult(i)~=Bclass(i) % 判别错误
err=err+1;
end
end
recognize=['正确识别率:',num2str((1-err/all_test)*100),'%']; % 显示识别结果
t=toc;
fprintf('the reganization time is %8.5f\n',t/all_test);