/
eigenfaces.m
142 lines (114 loc) · 3.21 KB
/
eigenfaces.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
% EIGENFACES.m - Eigenfaces algorithm
%
% This code is an implementation of the eigenfaces algorithm.
% It uses a training and test set that can be found in github.
% Results a bit unsuccessful since only 16 images are used in the
% training set, but it shows how it works.
%
% You can do with this code whatever you want. The main purpose is help
% people learning about this. Also, there is no warranty of any kind.
%
% Juan Miguel Valverde Martinez
% http://laid.delanover.com
%
clear;clc;
ts.name = {'im1.png', 'im2.png', 'im3.png', 'im4.png','im5.png', 'im6.png', 'im7.png' 'im8.png','im9.png', 'im10.png', 'im11.png' 'im12.png', 'im13.png', 'im14.png', 'im15.png' 'im16.png'};
ts.rows = 235;
ts.columns = 235;
ts.length = length(ts.name);
% Read images and vectorize them
for a=1:ts.length
ts.image{a} = reshape(double(imread(ts.name{a})),1,ts.rows*ts.columns);
end
% Calculate the mean
ts.mean = zeros(1,ts.rows*ts.columns);
for a=1:ts.length
ts.mean = ts.mean + (1/ts.length)*ts.image{a};
end
% Normalize vectors
for a=1:ts.length
ts.norm{a} = ts.image{a}-ts.mean;
end
% Generate A matrix
A = zeros(ts.length,ts.rows*ts.columns);
for a=1:ts.length
A(a,:) = ts.norm{a};
end
% MxM matrix
Cov = A*A';
[eigenvectors,eigenvalues]=eig(Cov);
% Eigenfaces 1. The first is the best because they are (supposed to be
% sorted)
for a=0:ts.length-1
eigenfaces.image{a+1} = eigenvectors(:,end-a)'*A;
end
% Normalize eigenfaces
%
for a=1:ts.length
eigenfaces.image{a} = eigenfaces.image{a}./norm(eigenfaces.image{a},2);
end
%
% Eigenfaces 2
%{
Vlarge = A'*eigenvalues;
for a=1:ts.length
eigenfaces.image{a} = Vlarge(:,a)';
end
%}
% Heuristics to select certain amount of eigenvectors
% 1: Select those until the cumulative sum is around 95%
% eigval = diag(eigenvectors);
% eigval = eigval(end:-1:1);
% eigsum = sum(eigval);
% csum = 0;
% for i = 1:size(eigval,1)
% csum = csum + eigval(i);
% tv = csum/eigsum;
% if tv > 0.95
% k95 = i;
% break
% end ;
% end;
% 2: Select those eigenvectors whose eigenvalues are 1 or greater
% L_eig_vec = [];
% for i = 1 : size(V,2)
% if( D(i,i) > 1 )
% L_eig_vec = [L_eig_vec V(:,i)];
% end
% end
% We can adjust manually to use the Nth best eigenvectors
eigenfaces.used = 8;
% Weights
for a=1:ts.length
for b=1:eigenfaces.used
ts.w(a,b) = eigenfaces.image{b}*ts.norm{a}';
end
end
% <<Classification>>
test.name = {'im1.png', 'test1.png', 'test2.png', 'test3.png','test4.png', 'test5.png', 'test6.png','test7.png', 'test8.png', 'test9.png'};
test.rows = 235;
test.columns = 235;
test.length = length(test.name);
% Read images and vectorize them
for a=1:test.length
test.image{a} = reshape(double(imread(test.name{a})),1,test.rows*test.columns);
end
% Normalize vectors with respect to the training set mean
for a=1:test.length
test.norm{a} = test.image{a}-ts.mean;
end
% Weights
for a=1:test.length
for b=1:eigenfaces.used
test.w(a,b) = eigenfaces.image{b}*test.norm{a}';
end
end
% Calculate the distances
for a=1:test.length
for b=1:ts.length
test.dist(a,b) = sqrt(sum((test.w(a,:)-ts.w(b,:)).^2));
end
end
for a=1:test.length
fprintf('%s: %i\n',test.name{a},sum(test.dist(a,:)));
end