1
|
|
|
# -*- coding: utf-8 -* |
2
|
|
|
import numpy as np |
3
|
|
|
import os |
4
|
|
|
import matplotlib.pyplot as plt |
5
|
|
|
from scipy import misc |
6
|
|
|
|
7
|
|
|
scale = 0.4 |
8
|
|
|
k = 4 |
9
|
|
|
feature_face = 0 |
10
|
|
|
principal_percent = 0.3 |
11
|
|
|
|
12
|
|
|
# covert image to sole vector |
13
|
|
|
def img2vector(filename): |
14
|
|
|
imgVector = misc.imresize(plt.imread(filename), scale).flatten() |
15
|
|
|
#imgVector = plt.imread(filename).flatten() |
16
|
|
|
return imgVector.astype(np.float) |
17
|
|
|
|
18
|
|
|
# load image from diretion |
19
|
|
|
def loadimage(dataSetDir): |
20
|
|
|
train_face = np.zeros((40 * k, int(112 * scale) * int(92 * scale))) # image size:112*92 |
21
|
|
|
train_face_number = np.zeros(40 * k).astype(np.int8) |
22
|
|
|
test_face = np.zeros((40 * (10 - k), int(112 * scale) * int(92 * scale))) |
23
|
|
|
test_face_number = np.zeros(40 * (10 - k)).astype(np.int8) |
24
|
|
|
for i in np.linspace(1, 40, 40).astype(np.int8): #40 sample people |
25
|
|
|
people_num = i |
26
|
|
|
for j in np.linspace(1, 10, 10).astype(np.int8): #everyone has 10 different face |
27
|
|
|
if j <= k: |
28
|
|
|
filename = dataSetDir+'/s'+str(people_num)+'/'+str(j)+'.pgm' |
29
|
|
|
img = img2vector(filename) |
30
|
|
|
train_face[(i-1)*k+(j-1),:] = img |
31
|
|
|
train_face_number[(i-1)*k+(j-1)] = people_num |
32
|
|
|
else: |
33
|
|
|
filename = dataSetDir+'/s'+str(people_num)+'/'+str(j)+'.pgm' |
34
|
|
|
img = img2vector(filename) |
35
|
|
|
test_face[(i-1)*(10-k)+(j-k)-1,:] = img |
36
|
|
|
test_face_number[(i-1)*(10-k)+(j-k)-1] = people_num |
37
|
|
|
|
38
|
|
|
return train_face,train_face_number,test_face,test_face_number |
39
|
|
|
|
40
|
|
|
# subtract a vector from a matrex |
41
|
|
|
def subvector(target_matrex, target_vector): |
42
|
|
|
vector4matrex = np.repeat(target_vector, target_matrex.shape[0],axis = 0) |
43
|
|
|
target_matrex = target_matrex - vector4matrex |
44
|
|
|
return target_matrex |
45
|
|
|
|
46
|
|
|
# both data subtract mean data of train data |
47
|
|
|
def submean(train_data, test_data): |
48
|
|
|
mean_data = train_data.mean(axis = 0).reshape(1, train_data.shape[1]) |
49
|
|
|
train_data = subvector(train_data, mean_data) |
50
|
|
|
test_data = subvector(test_data, mean_data) |
51
|
|
|
return train_data,test_data |
52
|
|
|
|
53
|
|
|
# main program |
54
|
|
|
train_face,train_face_number,test_face,test_face_number = loadimage(os.getcwd()+'/att_faces') |
55
|
|
|
train_face, test_face = submean(train_face, test_face) |
56
|
|
|
|
57
|
|
|
cov = np.dot(train_face.T, train_face) |
58
|
|
|
print("Calculate eigenvalues & eigenvectors") |
59
|
|
|
l, v = np.linalg.eig(cov) |
60
|
|
|
|
61
|
|
|
print("Sort eigenvectors by the value of eigenvalues") |
62
|
|
|
mix = np.vstack((l,v)) |
63
|
|
|
mix = mix.T[np.lexsort(mix[::-1,:])].T[:,::-1] |
64
|
|
|
v = np.delete(mix, 0, axis = 0) |
65
|
|
|
|
66
|
|
|
#show feature maps |
67
|
|
|
if feature_face == 1: |
68
|
|
|
plt.figure('Feature Map') |
69
|
|
|
r, c = (4, 10) |
70
|
|
|
for i in np.linspace(1, r * c, r * c).astype(np.int8): |
71
|
|
|
plt.subplot(r,c,i) |
72
|
|
|
plt.imshow(v[:, i-1].real.reshape(int(112 * scale), int(92 * scale)), cmap='gray') |
73
|
|
|
plt.axis('off') |
74
|
|
|
|
75
|
|
|
|
76
|
|
|
v = v[:,0:int(v.shape[1]*principal_percent)] |
77
|
|
|
train_face = np.dot(train_face, v) |
78
|
|
|
test_face = np.dot(test_face , v) |
79
|
|
|
|
80
|
|
|
count = 0 |
81
|
|
|
|
82
|
|
|
for i in np.linspace(0, test_face.shape[0] - 1, test_face.shape[0]).astype(np.int64): |
83
|
|
|
sub = subvector(train_face,test_face[i, :].reshape((1,test_face.shape[1]))) |
84
|
|
|
dis = np.linalg.norm(sub, axis = 1) |
85
|
|
|
fig = np.argmin(dis) |
86
|
|
|
if train_face_number[fig] == test_face_number[i]: |
87
|
|
|
count = count + 1 |
88
|
|
|
correct_rate = count / test_face.shape[0] |
89
|
|
|
print("Principal =", principal_percent * 100, "%, count for", int(v.shape[1]*principal_percent), "principal eigenvectors") |
90
|
|
|
print("Correct rate =", correct_rate * 100 , "%") |
91
|
|
|
print("Finish...") |
92
|
|
|
|