1.eigenface_example.m(主程序)
% load function files from subfolders aswell
addpath (genpath ('.'));
% load data
[X y width height names] =
read_images('E:/faces_rec/orl_faces');
% compute a model
eigenface = eigenfaces(X,y,100)
% plot the first (atmost) 16 eigenfaces
figure;
title('Eigenfaces (AT&T Facedatabase)');
hold on;
for i=1:min(16, size(eigenface.W,2))
subplot(4,4,i);
eigenface.W(:,i)
comp =
cvtGray(eigenface.W(:,i), width, height)
imshow(comp);
colormap(jet(256));
title(sprintf('Eigenface #%i', i));
end
%% 2D plot of projection (first three classes, add those you
want)
figure; hold on;
for i = findclasses(eigenface.y, [1,2,3])
% LineSpec: red dots 'r.'
plot3(eigenface.P(1,i), eigenface.P(2,i),
eigenface.P(3,i),'r.'), view(45,-45);
text(eigenface.P(1,i),
eigenface.P(2,i),eigenface.P(3,i), num2str(eigenface.y(i)));
end
pause;
以下为各部分子程序:
function model = eigenfaces(X, y, num_components)
%% Performs a PCA on X and
stores num_components principal components.
%%
%% Args:
%% X [dim x
num_data] input data
%% y [1 x
num_data] classes
%% num_components
[int] components to keep
%%
%% Out:
%% model
[struct] learned model
%% .name
[char] name
%% .mu
[dim x 1] sample mean of X
%% .num_components
[int] number of components in this model
%% .W
[dim x num_components] components identified by PCA
%% .P
[num_components x num_data] projection of X
%%
%% Example:
%% m_eigenface
= eigenfaces(X, y, 100)
if(nargin < 3)
num_components=size(X,2)-1;
end
% perform pca
Pca = pca(X,y,num_components);
% build model
model.name = 'eigenfaces';
model.W = Pca.W;
model.num_components = num_components;
model.mu = Pca.mu;
% project data
model.P = model.W'*(X - repmat(Pca.mu, 1,
size(X,2)));
% store classes
model.y = y;
end
function G = cvtGray(I, width, height)
%% Returns a greyscaled representation G of
I.
%%
%% Args:
%% I: Array with width*height
elements.
%% width: Width of G.
%% height: Height of G
%%
%% Returns:
%% Greyscaled (intensity 0-255)
and reshaped image I.
%%
%% Example:
%% cvtGray(I, 200, 100)
%%
G = reshape(normalize(I, 0, 255), height,
width);
G = uint8(G);
end
function N = normalize(I, l, h)
minI = min(I);
maxI = max(I);
%% Normalize to [0...1].
N = I - minI;
N = N ./ (maxI - minI);
%% Scale to [low...high].
N = N .* (h-l);
N = N + l;
end
function [X y width height names] = read_images(path)
%% Read images from a given path and return the
Imagematrix X.
%%
%% Returns:
%% X [numDim x numSamples]
Array with images given in columns -- [X1,X2,...,Xn]
%% y [1 x numSamples] Classes
corresponding to images of X. -- [y1,y2,...,yn]
%% width [int] width of the
images
%% height [int] height of the
images
%% names [cell array] folder
name of each class, so names{1} is the name of class 1
%%
%% Example:
%% [X y width height names] =
read_images("./data/yalefaces")
%%
folder = list_files(path);
X = [];
y = [];
names = {};
n = 1;
for i=1:length(folder)
subject = folder{i};
images = list_files([path,
filesep, subject]);%filesep 表示Directory separator for current
platform,images
if(length(images) == 0)
continue; %%
dismiss files or empty folder
end
added = 0;
names{n} = subject;
%% build image matrix and class
vector
for j=1:length(images)
%% absolute
path
filename =
[path, filesep, subject, filesep, images{j}];
%% Octave
crashes on reading non image files (uncomment this to be a bit more
robust)
%extension =
strsplit(images{j}, "."){end};
%if(~any(strcmpi(extension,
{"bmp", "gif", "jpg", "jpeg", "png", "tiff"})))
% continue;
%endif
% Quite a
pythonic way to handle failure.... May blow you up just like the
above.
try
T
= double(imread(filename));
catch
lerr
= lasterror;
fprintf(1,'Cannot
read image %s', filename)
end
[height width
channels] = size(T);
% greyscale
the image if we have 3 channels
if(channels
== 3)
T
= (T(:,:,1) + T(:,:,2) + T(:,:,3)) / 3;
end
%% finally
try to append data
try
X
= [X, reshape(T,width*height,1)];
y
= [y, n]
added
= added + 1;
catch
lerr
= lasterror;
fprintf(1,'Image
cannot be added to the Array. Wrong image size?\n')
end
end
% only increment class if
images were actually added!
if ~(added == 0)
n = n +
1;
end
end
end
function L = list_files(path)
%% List all files in a folder and return it as a
cell array.
%%
%% Args:
%% path: Path to list files
from.
%%
%% Returns:
%% L: Cell array with files in
this folder.
%%
%% Example:
%% L =
list_files("./data/yalefaces")
%%返回的结果
Columns 1 through 14
% 'README' 'at.txt' 's1' 's10' 's11' 's12' 's13' 's14' 's15' 's16' 's17' 's18' 's19' 's2'
% 's20' 's21' 's22' 's23' 's24' 's25' 's26' 's27' 's28' 's29' 's3' 's30' 's31' 's32' 's33'
% 's34' 's35' 's36' 's37' 's38' 's39' 's4' 's40' 's5' 's6' 's7' 's8' 's9'
L = dir(path);
L = L(3:length(L));
L = struct2cell(L);
L = L(1,:);
end
function idx = findclasses(y, list_of_classes)
min_class = min(y);
max_class = max(y);
idx = [];
for i = list_of_classes
if((i >=
min_class) || (i <= max_class))
idx = [idx,
find(y == i)];
end
end
end
function model = pca(X, y, num_components)
%% Performs a PCA on X and
stores num_components principal components.
%%
%% Args:
%% X [dim x
num_data] Input
%% y [1 x
num_data] Classes
%% num_components
[int] Number of components to use.
%%
%% Out:
%% model
[struct] learned model
%% .name
[char] name of this model
%% .W
[dim x num_components] components identified by PCA
%% .num_components
[int] mumber of components used in this model.
%% .mu
[dim x 1] sample mean of X
%%
%% Example:
%% pca(X, y,
struct('num_components',100))
%%
if(nargin < 3)
num_components=size(X,2)-1;
end
% center data
mu = mean(X,2);
X = X - repmat(mu, 1, size(X,2));
% svd on centered data == pca
[E,D,V] = svd(X ,'econ');
% build model
model.name = 'pca';
model.W = E(:,1:num_components);
model.num_components = num_components;
model.mu = mu;
end