使用PCA通过MATLAB实现简单的人脸识别。使用的是ORL人脸库,里面共40个人,每人10张照片。主要通过两种分组方式来实现人脸识别。
分组一流程图
分组二流程图
主成分分析法(PCA)又称特征脸方法,实质是通过K-L变换来实现的。PCA的目的是使各个维度上的方差尽可能大,不同维度间的相关性尽可能小,以使降维同时最大程度保持数据原始特征。以上是我对使用PCA进行人脸识别的两种分组的大致步骤框图,可能表述不准确。
对于测试样本,读取图像,将其变换至PCA空间,利用近邻法识别。
对待识别的每一张照片进行测试,与训练样本库中的每一张照片进行比对,若得到的最小距离的照片与待识别的照片为同一组(根据输入的每组照片训练数目判断),则标记为正确。定义准确率公式为正确数/总待识别数。
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global W %特征脸空间
global V %特征脸
global img_pj %均值
global wts %训练的样本总数
global train_num %每个人训练的照片
n = 1;
p=1;
%分成train和test两个文件夹,并且图片重命名
for i=1:40 %40个人
a=1:10; %每个人10张
Ind = a(:,randperm(size(a,2))); %size:取矩阵的列数 randperm:打乱顺序
for h = 1:train_num
j= Ind(1,h);
File=['人脸库地址',sprintf('%d',i),'\',sprintf('%d',j),'.pgm'];
Filesave=['训练集地址','\',sprintf('%03d',p),'.pgm'];
copyfile(File,Filesave)
p = p + 1; %训练样本总数
end
for h = train_num+1:10
j= Ind(1,h);
File=['人脸库地址',sprintf('%d',i),'\',sprintf('%d',j),'.pgm'];
Filesave=['测试集地址','\',sprintf('%03d',n),'.pgm'];
copyfile(File,Filesave)
n = n + 1; %测试样本总数
end
end
%批量读取指定文件夹下的图片
path = uigetdir; %打开一个模态对话框
img_path = dir(strcat(path,'\*.pgm')); %列出.pgm文件
img_num = length(img_path); %img_num:文件夹中的总数
imagedata = []; %一张图片为一列
if img_num >0
for j = 1:img_num
img_name = img_path(j).name;
temp = imread(strcat(path, '/', img_name));
temp = double(temp(:));
imagedata = [imagedata, temp];
end
end
%中心化并计算协方差矩阵
wts = size(imagedata,2); %imagedata的列数(等于训练的样本数)
img_pj= mean(imagedata,2); %均值
for i = 1:wts
imagedata(:,i) = imagedata(:,i) - img_pj; %中心化
end
covMat = imagedata'*imagedata; %':转置
[COEFF, latent, explained] = pcacov(covMat);
%留下使累计贡献量达95%的k个特征向量
i = 1;
proportion = 0;
while(proportion < 95)
proportion = proportion + explained(i);
i = i+1;
end
k = i - 1;
%求出原协方差矩阵的特征向量,即特征脸
V = imagedata*COEFF; % N*M阶
V = V(:,1:k);
%显示前5的特征脸
A=reshape(V(:,1),[112 92]); %每张图片大小为112*92
A=mat2gray(A);
axes( handles.axes1 )
imshow([A])
B=reshape(V(:,2),[112 92]);
B=mat2gray(B);
axes( handles.axes2 )
imshow([B])
C=reshape(V(:,3),[112 92]);
C=mat2gray(C);
axes( handles.axes3 )
imshow([C])
D=reshape(V(:,4),[112 92]);
D=mat2gray(D);
axes( handles.axes4 )
imshow([D])
E=reshape(V(:,5),[112 92]);
E=mat2gray(E);
axes( handles.axes5 )
imshow([E])
% 训练样本在 PCA 特征空间下的表达矩阵 k*M
W= V'*imagedata;
msgbox(['训练完成'])
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global im;
[filename, path] = uigetfile({
'*.pgm'},'choose photo');
str = [path, filename];
im = imread(str);
axes( handles.axes6);
imshow(im);
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global im %待识别的图片
global V
global W
global img_pj
global wts
im1 = double(im(:));
objectone = V'*(im1 - img_pj); %计算待识别图片的投影
%最小距离法,寻找和待识别图片最为接近的训练图片
for k = 1:wts
temp1(k) = norm(objectone - W(:,k)); %欧氏距离
end
[s_temp,id]=sort(temp1,'ascend'); %筛选出距离前三小的
axes( handles.axes7 )
imshow(['训练集地址','\',sprintf('%03d',id(1)),'.pgm'])
axes( handles.axes8 );
imshow(['训练集地址','\',sprintf('%03d',id(2)),'.pgm'])
axes( handles.axes9 )
imshow(['训练集地址','\',sprintf('%03d',id(3)),'.pgm'])
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global V
global W
global train_num
col_of_data = 40*train_num;
pathname = uigetdir;
img_path_list = dir(strcat(pathname,'\*.pgm'));
img_num = length(img_path_list);
testdata = [];
if img_num >0
for j = 1:img_num
img_name = img_path_list(j).name;
temp = imread(strcat(pathname, '/', img_name));
temp = double(temp(:));
testdata = [testdata, temp];
end
end
col_of_test = size(testdata,2); %col_of_test:待测样本数
img_pj= mean(testdata,2);
for i = 1:size(testdata,2)
testdata(:,i) = testdata(:,i) - img_pj;
end
object =V'* testdata;
num = 0;
for j = 1:col_of_test
distance = 1e8;
for k = 1:col_of_data %col_of_data:训练样本总数
temp = norm(object(:,j) - W(:,k));
if(distance>temp)
aimone = k; %取出距离最小的
distance = temp;
end
end
if ceil(j/(10-train_num))==ceil(aimone/(train_num))
num = num + 1; %TP:预测和真实值都为1
end
end
accuracy = num/col_of_test;
set(handles.edit2,'String',num2str(accuracy));
x=2:1:9;
a=[0.74375,0.85,0.89167,0.915,0.93125,0.95,0.96245,1]; %数据
plot(x,a,'-*b'); %线性,颜色,标记
axis([2,9,0.7,1])
set(gca,'XTick',[2:1:9])
set(gca,'YTick',[0.7:0.05:1])
xlabel('训练数目(n/10)')
ylabel('准确率(%)')
% 新建train和test文件夹
% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton6 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
cd('C:\Users\Administrator\Desktop\实验四');
mkdir train;
mkdir test;
%删除文件夹
% --- Executes on button press in pushbutton7.
function pushbutton7_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton7 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
cd('C:\Users\Administrator\Desktop\实验四');
%delete('*.pgm')
rmdir train s
rmdir test s
%分成train、test、yanzheng三个文件夹,并且图片重命名
for i=1:train_num %前n个人
a=1:10; %每个人10张
Ind = a(:,randperm(size(a,2))); %size:取矩阵的列数 randperm:打乱顺序
for h = 1:10
j= Ind(1,h);
File=['人脸库地址',sprintf('%d',i),'\',sprintf('%d',j),'.pgm'];
Filesave=['训练集地址','\',sprintf('%03d',p),'.pgm'];
copyfile(File,Filesave)
p = p + 1; %训练样本总数
end
end
for i=train_num+1 :40 %后40-n个人的前5张
a=1:10;
Ind = a(:,randperm(size(a,2)));
for h = 1:5
j= Ind(1,h);
File=['人脸库地址',sprintf('%d',i),'\',sprintf('%d',j),'.pgm'];
Filesave=['验证集地址','\',sprintf('%03d',m),'.pgm'];
copyfile(File,Filesave)
m = m + 1; %测试样本总数
end
for h = 6:10
j= Ind(1,h);
File=['人脸库地址',sprintf('%d',i),'\',sprintf('%d',j),'.pgm'];
Filesave=['测试集地址','\',sprintf('%03d',n),'.pgm'];
copyfile(File,Filesave)
n = n + 1; %待识别总数
end
End
% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global V
global W1
global img_pj1
%批量读取指定文件夹下的图片
path = uigetdir; %打开一个模态对话框
img_path = dir(strcat(path,'\*.pgm')); %列出.pgm文件
img_num = length(img_path); %img_num:文件夹中的总数
imagedata1 = []; %一张图片为一列
if img_num >0
for j = 1:img_num
img_name = img_path(j).name;
temp = imread(strcat(path, '/', img_name));
temp = double(temp(:));
imagedata1 = [imagedata1, temp];
end
end
%中心化并计算协方差矩阵
wts = size(imagedata1,2); %imagedata的列数(等于训练的样本数)
img_pj1= mean(imagedata1,2); %均值
for i = 1:wts
imagedata1(:,i) = imagedata1(:,i) - img_pj1; %中心化
end
size(imagedata1)
% 训练样本在 PCA 特征空间下的表达矩阵 k*M
W1= V'*imagedata1;
msgbox(['训练2完成'])
以上仅个人拙见,欢迎共同学习交流。