📄 entire.txt
字号:
%Given an array of images, will allow the user to select the center of the face, and will cut it out. This allows all the images to be the same size, and to be focused on the correct area of interest.
%F = function centerfaces(F, windowX, windowY)
function F = centerfaces(F, windowX, windowY)
if( nargin < 2 )
windowX = 80;
windowY = 80;
end;
fields = fieldnames(F);
for i = 1:length(F),
for j = 1:length(fields);
X = F(i).(fields{j});
figure(1);
truesize;
imagesc(X);
colormap(Gray);
while(1),
[y x ] = ginput(1);
if( x > windowX && x < size(X,1) - windowX && ...
y > windowY && y < size(X,2) - windowY )
break;
else
fprintf('Error, point (%d %d) with window size %d too close to edge', x, y, windowX);
end;
end;
x = round(x);
y = round(y);
Y = X( x - windowX + 1: x + windowX - 1, y - windowY + 1 : y + windowY - 1 );
figure(2);
imagesc(Y);
truesize;
drawnow;
F(i).(fields{j}) = Y;
end;
end;
%Main routine that performs Eigenface analysis and shows a bunch of figures, as presented above.
allextensions = {'centerlight', 'glasses', 'happy', 'leftlight', 'noglasses', 'normal', 'rightlight', 'sad', 'sleepy', 'surprised', 'wink' };
bestextensions = {'happy', 'noglasses', 'normal', 'sad', 'sleepy', 'surprised', 'wink' };
noglassesextensions = {'centerlight', 'happy', 'leftlight', 'noglasses', 'normal', 'rightlight', 'sad', 'sleepy', 'surprised', 'wink' };
lightextensions = {'centerlight', 'leftlight', 'normal', 'rightlight' };
expressionextensions = {'happy', 'normal', 'sad', 'sleepy', 'surprised', 'wink' };
extensions = allextensions;
clear train;
clear test;
clear M;
%First, extract the faces into training and test faces
trainidx = 1;
testidx = 1;
for i = 1:length(Faces),
for j = 1:length(extensions);
X = double(Faces(i).(extensions{j}));
if( rand > 0.3 )
train(trainidx).data = X;
trainidx = trainidx + 1;
else
test(testidx).data = X;
testidx = testidx + 1;
end;
end;
end;
%Take the average of the training faces
avg = meanface(train);
%Put all of the training faces into one big matrix and do svd
idx = 1;
for i = 1:length(train),
X = double(train(i).data);
W = X - avg;
M(:, idx) = W(:);
idx = idx + 1;
end;
[U, W, V] = svd(M,0);
Result = U * W * V';
%Show the variance produced by the top eigenvectors
cvalues = zeros(1,size(W,1)-3);
cvalues(1) = W(1,1);
valsum = W(1,1);
for i = 2:length(cvalues);
cvalues(i) = cvalues(i-1) + W(i,i);
valsum = valsum + W(i,i);
end;
cvalues = cvalues / valsum;
figure;
set(gcf, 'Name', 'Eigenvalue Variance');
plot(cvalues);
fprintf('10 PC Variance: %f\n25 PC Variance %f\n', cvalues(10), cvalues(25));
%Show the top k eigenfaces
k = 25;
dim = ceil(sqrt(k));
eigenfaceFigure = figure;
axis off;
for i = 1:k,
tightsubplot(dim, i, reshape(U(:,i), size(avg)));
end;
colormap(gray);
set(gcf, 'Name', 'Top 25 Eigenfaces');
%Pick a random sample of the training input and reconstruct
reconstructFigure = figure;
axis off;
set(gcf, 'Name', 'Reconstruction using 25 eigenfaces');
idx = 1;
reconstruct = zeros(size(avg));
for i = 1:25
%reconstruct = reconstruct + reshape( V(idx, i) * W(i,i) * U(:,idx), size(avg) );
% WRecon = zeros(size(W));
% WRecon(1:i, 1:i) = W(1:i, 1:i);
% reconstruct = U * WRecon * V';
reconstruct = U(:,1:i) * W(1:i,1:i) * V(:,1:i)';
recon = reshape( reconstruct(:,1), size(avg) ) + avg;
tightsubplot( 5, idx, recon );
idx = idx + 1;
imagesc(recon);
colormap(gray);
axis off;
drawnow;
end;
%Put all of the training faces into one big matrix and project
idx = 1;
for i = 1:length(test),
X = double(test(i).data);
Wh = X - avg;
T(:, idx) = Wh(:);
idx = idx + 1;
end;
%For each test example, find best match in training data
%trainweights = W(1:k,:)*V(:, 1:k)';
clear trainweights;
clear distances;
for i = 1:length(train)
trainweights(:,i) = U(:,1:k)' * M(:,i);
end;
recognitionFigure = figure;
axis off;
colormap(gray);
set(gcf, 'Name', 'Recognition Results');
idx = 1;
for i = 1:length(test)
testweights = U(:,1:k)' * T(:,i);
for j = 1:length(train),
distances(j) = sum((trainweights(:,j) - testweights(:)).^2);
end;
[val, best] = min(distances);
tightsubplot(8, idx, test(i).data );
axis off;
tightsubplot(8, idx+1, train(best).data ); axis off;
idx = idx + 2;
%subplot(1,2,1); imagesc(test(i).data);
%subplot(1,2,2); imagesc(train(best).data);
drawnow;
end;
%Now load three images and project them to both the eigenfaces,
% and to the orthogonal complement
nonfaces = {'face.gif', 'face2.gif', 'nonface1.jpg', 'nonface2.jpg', 'nonface3.jpg'};
for j=1:length(nonfaces),
face = double(imread(nonfaces{j}));
faceweights = U(:,1:k)' * face(:);
reconstruct = U(:,1:k) * faceweights(:) + avg(:);
reconstruct = reshape(reconstruct, [199, 199]);
figure;
imagesc(reconstruct);
recon2 = face - reconstruct;
normA = norm(face - reconstruct)
normB = norm(face - recon2);
ratio = normA / normB;
%diff1 = sqrt((face(:) - reconstruct(:)) .^2);
%diff2 = sqrt((face(:) - (face(:) - reconstruct(:))) .^ 2);
fprintf('Ratio: %d\n' , ratio);
% fprintf('Distance to reconstruction: %f, Distance to complement: %f \n', diff1, diff2);
end;
%Reads the Yale face dataset from a directory, and puts then into a structure labeled by their types.
function F = readyalefaces()
extensions = {'centerlight', 'glasses', 'happy', 'leftlight', 'noglasses', 'normal', 'rightlight', 'sad', 'sleepy', 'surprised', 'wink' };
for i = 1 : 15,
basename = 'yalefaces/subject';
if( i < 10 )
basename = [basename, '0', num2str(i)];
else
basename = [basename, num2str(i)];
end;
for j = 1:length(extensions),
fullname = [basename, '.', extensions{j}];
X = imread(fullname);
F(i).(extensions{j}) = X;
end;
end;
% A simple image viewer that allows scrolling through the Yale dataset in 2 dimensions
function viewfaces(faces)
extensions = {'centerlight', 'glasses', 'happy', 'leftlight', 'noglasses', 'normal', 'rightlight', 'sad', 'sleepy', 'surprised', 'wink' };
if( nargin < 1 )
faces = Faces;
end;
faceviewer = figure;
imagesc(faces(1).(extensions{1}));
drawnow;
row = 1;
col = 1;
while(1)
waitforbuttonpress;
key = double(get(gcf, 'CurrentCharacter'));
if( key == 30 ) %up
if( row > 1 )
row = row - 1;
else
continue;
end;
elseif( key == 31 ) %down
if( row < length(faces) )
row = row + 1;
else
continue;
end;
elseif( key == 28 ) %left
if( col > 1 )
col = col - 1;
else
continue;
end;
elseif( key == 29 ) %right
if( col < length(extensions) )
col = col + 1;
else
continue;
end;
elseif( key == 27 ) %esc
break;
else
continue;
end;
imagesc(faces(row).(extensions{col}));
set(gcf, 'Name', sprintf('Person %d/%d, Pose %d/%d (%s)', ...
row, length(faces), col, length(extensions), extensions{col}));
drawnow;
end;
%function viewfaces(faces)
extensions = {'centerlight', 'glasses', 'happy', 'leftlight', 'noglasses', 'normal', 'rightlight', 'sad', 'sleepy', 'surprised', 'wink' };
if( nargin < 1 )
faces = Faces;
end;
faceviewer = figure;
imagesc(faces(1).(extensions{1}));
drawnow;
row = 1;
col = 1;
while(1)
waitforbuttonpress;
key = double(get(gcf, 'CurrentCharacter'));
if( key == 30 ) %up
if( row > 1 )
row = row - 1;
else
continue;
end;
elseif( key == 31 ) %down
if( row < length(faces) )
row = row + 1;
else
continue;
end;
elseif( key == 28 ) %left
if( col > 1 )
col = col - 1;
else
continue;
end;
elseif( key == 29 ) %right
if( col < length(extensions) )
col = col + 1;
else
continue;
end;
elseif( key == 27 ) %esc
break;
else
continue;
end;
imagesc(faces(row).(extensions{col}));
set(gcf, 'Name', sprintf('Person %d/%d, Pose %d/%d (%s)', ...
row, length(faces), col, length(extensions), extensions{col}));
drawnow;
end;
%A helper routine that makes subplot lie immediatly next to each other, without borders.
function tightsubplot(dim, i, data)
row = mod(i-1, dim);
col = floor((i-1) / dim);
subplot('position', [row*(1/dim), (dim-col-1)*(1/dim), 1/dim-.001, 1/dim-0.001 ]);
imagesc(data);
axis off;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -