Matlab 人脸识别之PCA算法,使用Yale人脸数据库

    写这个程序是老师布置的作业。一个莫名其妙的机会选了一个莫名其妙的课,于是写了与自己关系不大的人工智能的人脸识别的程序。这里给自己记录一下,估计这个学习都要和这个方面的打交道了。

   

    Part 1:程序流程简介

   

    这个程序是典型的。在已有资源中使用一部分做训练集,找到一个合适的模型或者结论,然后用剩下的部分来测试自己的结论的正确度,进而一步步提高自己的算法效率或者正确性等。

 

    所以,在这次的程序中,前半部分是训练部分,中间有几段是画图部分,后面部分是测试部分。

 

    Part 2:数据库和PCA算法简介

   

    数据库使用的是Yale的人脸数据库。一共15组图片,每组图片里面有11张图片。在我的程序里面,我使用了每组里面的8张照片为训练集,剩下的3张为测试集。所以,一共是120张训练照片,45张测试照片。

 

    PCA算法步骤:

 

    1.Matrix X (input data)                                         N dimensional input space

       即原始矩阵

 

    2.Matrix QX (Covariance of X)                              QX = cov(X) = E[(x-m)(x-m)T]

       求出X的协方差矩阵QX

 

    3.Valuable λk(eigenvalue of QX)                        λ1≥λ2≥λ3。。。

     求出特征值,降序排列

 

   4.Vector Vk

     求出对应的特征向量

 

   5.Projection: V*X

     最后一步,在求出的向量基上面投影(降维)

 

    Part 3:具体代码

    

%**********************************************
% Aim : The first AI program homework
% Title : PCA for face recognition
% Author : GongWanlu & Hufei
% Version : 1.0 final
% Submit Time : 2011-04-07
%**********************************************

% %%%%%%%%%%%%%%%%%%%%%%INITIAL
clear all
clc
close all

% %%%%%%%%%%%%%%%%%%%%%%Some variables according to the Yale Face DB
Num_subject = 15;
Num_image = 11;
Train_num_image = 8;                    %for every subject we choose 8 to train
Test_num_image = 9;                     %choose the left 3 images to test

% %%%%%%%%%%%%%%%%%%%%%%Load Data
Data = [];
for i=1:Num_subject
    for j=1:Train_num_image
        path = sprintf('FaceDB_yaleA/%03d/%02d.jpg',i,j);
        pic = imread (path);            %read one picture
        
        %Make Data ,Add pic into Data
        pic_line = pic(1:147*137);      %The pic size is 147*137
                                        %pic_line is 1*N ,N=147*137. from up to
                                        %down,left to right.
                                        %Reshape 2D image to 1D image
                                        %vectors
        Data = [Data;double(pic_line)]; %add pic_line into Data
    end
end
% End of Load Data

%%%%%%%%%%%%%%%%%%%%%%%Substract mean from Data and make covariance from centering Data
samplemean = mean(Data);                %mean pic 1*N

for k = 1:(Num_subject * Train_num_image)
    xmean(k,:)=Data(k,:)-samplemean;    %Normalize
end                                     %xmean is M*N ,each line is one pic
                                        %data(mean data) be normalized
sigma = xmean *xmean';                  %M*M , here is 120*120
[V D]=eig(sigma);                       %calculate the eigenvalue&eigenvector
                                        %eigenvalue in D,and vectors in V
 D1=diag(D);                            %the eigenvalues
 
 %%%%%%%%%%%%%%%%%%%%%%%% Sorting and eliminating eigenvalues
 % At first : sort desc
 Dsort=flipud(D1);
 Vsort=fliplr(V);
 
 %choose part eigenvalues
 Dsum = sum(Dsort);                     %sum of the eigenvalues,we only choose 80%
                                        %we have different ways to choose
                                        %eigenvalues we need,90%,or>1……
temp_sum = 0;
p = 0;
while(temp_sum/Dsum<0.8)
    p = p+1;
    temp_sum = sum(Dsort(1:p));
end
%End of sort part

 %%%%%%%%%%%%%%%%%%%%%%%Train Step: get the coordinate system
 i=1;
 while(i<=p && Dsort(i)>0)
     face_base(:,i) = Dsort(i)^(-1/2) * xmean' * Vsort (:,i);
     i=i+1;
 end
 % Dsort(i)^(-1/2) used to normalize, make variance=1
 % face_base is N*p
 % xmean' * Vsort (:,i); is change small matrix to big matrix. CHACHENG(Chinese)
 
 %next sentence is vary important is our train result
 allcoor = Data * face_base;
 %End of training
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Draw part
  %draw CDF
 x = Dsort (1:p);
 x = flipud (x);
 for i=1:p
     y(i) = 1/p*i;
 end
 figure,plot(x,y,'r*'),hold on,plot(x,y,'b');
 axis([0 inf 0 1]);
 title('CDF of selected values','fontsize',18);
 
 %draw the face (only use the first value) to show the result
 for k=1
     temp = reshape(face_base(:,k),147,137);        %1D to 2D
 end
 figure,imshow(mat2gray(temp));                     %draw it
 title('one eigen face','fontsize',18);

%draw the face (use 100 values) to show the result
 BigMap = [];
 for k=1:4
     map = [];
     for j=1:4
        temp = reshape(face_base(:,(k-1)*4+j),147,137);%1D to 2D
        map = cat(2,map,temp); 
     end
     BigMap = cat (1,BigMap,map);
 end
 figure,imshow(mat2gray(BigMap));                     %draw it
 Title ('Result of Chosen EigenValues','fontsize',18);
 %End of drwing part
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%Test Part
 Bingo = 0;  
 for i=1:Num_subject
    for j=Test_num_image:Num_image                  %read the left 15*3 images
        
        path = sprintf('FaceDB_yaleA/%03d/%02d.jpg',i,j);
        test_pic = imread(path);

        test_pic_line = test_pic(1:147*137);
        test_pic_line = double(test_pic_line);
        
        tcoor= test_pic_line * face_base;           %get the value
        
        for k=1:Num_subject* Train_num_image
            mdist(k)=norm(tcoor-allcoor(k,:));      %norm() distence
        end;
        
        %三阶近邻 
        [dist,index2] = sort(mdist);
        class1=floor( (index2(1)-1)/Train_num_image)+1;
        class2=floor((index2(2)-1)/Train_num_image)+1;
        class3=floor((index2(3)-1)/Train_num_image)+1;
        
        if class1~=class2 && class2~=class3   ID = class1;      
        elseif (class1==class2)  ID = class2;  
        elseif (class2==class3)   ID = class3; 
        end;
        
        if  ID==i
            Bingo=Bingo+1;
        end;
    end;
end;
accuracy = Bingo/45; %output the result
disp(accuracy);
% End of Test

 

 

 

附件里面,faceDB是使用的数据库。PCA是原始的程序。ProgramResult是一些简单的结论。直接把m文件和数据库文件夹放在一个目录下面就可以运行了。

 

 

 

 

 

你可能感兴趣的:(算法,J#,matlab,UP)