%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Eigenfaces.m % % This file is my version of the eigenfaces approach to % face recognition. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% clear all, close all %------------------------------------------------------------------------- % Load and plot (if desired) the faces. Mean subtract the data since we are % computing a principle component analysis (PCA). %------------------------------------------------------------------------- N_training = 64; disp('1. First we load in and view the faces. Hit any key to continue.'), pause for I=1:N_training name=sprintf('face%dn.pcx',I); if ~exist(name,'file') name=['faces/' name]; end tempIm=imread(name); if I==1 [Dim1 Dim2] = size(tempIm); Data=zeros([Dim1*Dim2 N_training]); viewIm=input('Do you want to view the inputted images (1 for yes)?'); end Data(:,I)=tempIm(:); if viewIm figure(1) imagesc(tempIm), colormap(gray) title(['Training Image, Face number ', num2str(I)]) pause(0.2) end end % Mean subtract the data. A = (1/N_training)*sum(Data,2); for i = 1:N_training Data(:,i) = Data(:,i)-A; end disp('2. Compute the eigenvectors and eigenvalues of the covariance matrix') disp(' to get the eigenfaces. ') disp(' Hit any key to continue.'), pause tic if 0 % For this data set, this method is twice as fast as calculating the dvs % below % % Calculate the eigenvalues and eigenvectors of the covariance matrix % The covariance matrix is Data*Data'/(N_training-1), which is % Dim1*Dim2^2!! Instead, we work with the following matrix, which is % on the order the number of individuals (64), much smaller than the size of % Dim1=Dim2=112^2 % Data'*Data has the same evals as Data*Data', but if the eigenvectors % of Data'*Data are W, the Data*W are the evecs of covariance = Data*Data'. C=1/N_training*Data'*Data; [W power]=eig(C); power=diag(power); power=power(length(power):-1:1); U=Data*W(:,length(power):-1:1); % The eigenvectors of the covariance = eigenfaces. for i=1:N_training U(:,i)=U(:,i)/norm(U(:,i)); end % The 'conventional' way to get the covariance, but its too big, inefficient way %C=1/N_training*Data*Data'; %[W power]=eig(C); %power=diag(power); %power=power(length(power):-1:1) %U=W(:,length(power):-1:1); %------------------------------------------------------------------------- % The eigenvectors of the covariance are X*W = X*(right singular vectors) % = scaled (by the appropriate singular value) left singular vectors! % % Thus, the eigenfaces are then the left singular vectors Data. %------------------------------------------------------------------------- else [U,S,V] = svd(Data,0); power = diag(S).^2/(N_training-1); end toc total_power = sum(power); disp('3. Now, we compress the data by taking a subset of the eigenvectors (left singular vectors)') disp(' determined by a choice for the percentage of total variance (or power) wanted in the basis.') alpha=0; while isempty(alpha) | alpha>100 | alpha<1 alpha = input('Percentage of total variance/power = '); if isempty(alpha) | alpha>100 | alpha<1 fprintf('\nInput a value between 1 and 100\n') end end figure(2) r = 0; ipower = 0; while ipower <= alpha & r < N_training r = r + 1; ipower = ipower + 100*power(r)/total_power; end plot(power), hold on, plot(power(r)*ones(size(power)),'r'), hold off legend('PCA spectrum','truncation level') fprintf('Number of eigenpairs saved = %d\n',r) % Eigenfaces/Compressed basis. Ur = U(:,1:r); %------------------------------------------------------------------------- % Note what needs to be stored in order to reconstruct the faces over the % PCA basis is the matrix Ur and the reconstruction coefficients Ur'*Data. % New faces can be tested against the library by looking at ||Ur'*face||. % If this norm is large enough, presumably the face corresponds to one in % the library. We now plot the eigenfaces and the projections of the faces % onto the PCA basis. The reduction is storage is as follows: without % compression (nxp) where n=112^2 and p=64; with compression Ur (nxr) and % Ur'*Data (rxp). If r<