-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPCA.py
More file actions
109 lines (96 loc) · 4.55 KB
/
PCA.py
File metadata and controls
109 lines (96 loc) · 4.55 KB
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
# -*- coding: utf-8 -*
import numpy as np
import os
import matplotlib.image as mpimg
from scipy import misc
import argparse
# initialize parameters
parser = argparse.ArgumentParser(description='PCA ORL')
parser.add_argument('--image-scale', type=float, default=0.5, metavar='scale',
help='scale rate for image (default: 0.5)')
parser.add_argument('--train-per-person', type=int, default=4, metavar='k',
help='training number per-person minimal to 1, maximum to 9 (default: 4)')
parser.add_argument('--print-feature-face', type=bool, default=False, metavar='feature_face',
help='print feature face (default: False)')
parser.add_argument('--principal-rate', type=float, default=1, metavar='principal_percent',
help='random seed (default: 1)')
args = parser.parse_args()
scale = args.image_scale
k = args.train_per_person
feature_face = args.print_feature_face
principal_percent = args.principal_rate
# covert image to sole vector
def img2vector(filename):
imgVector = (mpimg.imread(filename)).flatten()
return imgVector.astype(np.float)
# load image from diretion
def loadimage(dataSetDir):
train_face = np.zeros((40 * k, int(112 * scale) * int(92 * scale))) # image size:112*92
train_face_number = np.zeros(40 * k).astype(np.int8)
test_face = np.zeros((40 * (10 - k), int(112 * scale) * int(92 * scale)))
test_face_number = np.zeros(40 * (10 - k)).astype(np.int8)
for i in np.linspace(1, 40, 40).astype(np.int8): #40 sample people
people_num = i
for j in np.linspace(1, 10, 10).astype(np.int8): #everyone has 10 different face
if j <= k:
filename = dataSetDir+'/s'+str(people_num)+'/'+str(j)+'.jpg'
img = img2vector(filename)
img = np.resize(img, (56, 46)).flatten().transpose()
train_face[(i-1)*k+(j-1),:] = img
train_face_number[(i-1)*k+(j-1)] = people_num
else:
filename = dataSetDir+'/s'+str(people_num)+'/'+str(j)+'.jpg'
img = img2vector(filename)
img = np.resize(img, (56, 46)).flatten().transpose()
test_face[(i-1)*(10-k)+(j-k)-1,:] = img
test_face_number[(i-1)*(10-k)+(j-k)-1] = people_num
return train_face,train_face_number,test_face,test_face_number #tuple
# subtract a vector from a matrex
def subvector(target_matrix, target_vector):
vector4matrix = np.repeat(target_vector, target_matrix.shape[0],axis = 0)
target_matrix = target_matrix - vector4matrix
return target_matrix
# both data subtract mean data of train data
def submean(train_data, test_data):
mean_data = train_data.mean(axis = 0).reshape(1, train_data.shape[1])
train_data = subvector(train_data, mean_data)
test_data = subvector(test_data, mean_data)
return train_data,test_data
# main program
train_face,train_face_number,test_face,test_face_number = loadimage(os.getcwd()+'/att_faces')
train_face, test_face = submean(train_face, test_face)
# math calculate: the relevant mathematical formula can be found in the doc document
# build high-dimensional space
cov = np.dot(train_face.T, train_face)
# calculate eigenvalues & eigenvectors
l, v = np.linalg.eig(cov)
# sort eigenvectors by the value of eigenvalues
mix = np.vstack((l,v))
mix = mix.T[np.lexsort(mix[::-1,:])].T[:,::-1]
v = np.delete(mix, 0, axis = 0)
# select the principal components and map face images into high dimensional space
v = v[:,0:int(v.shape[1]*principal_percent)]
train_face = np.dot(train_face, v)
test_face = np.dot(test_face , v)
# recognise via measuring educlidean distance in high dimentional space
count = 0
for i in np.linspace(0, test_face.shape[0] - 1, test_face.shape[0]).astype(np.int64):
sub = subvector(train_face,test_face[i, :].reshape((1,test_face.shape[1])))
dis = np.linalg.norm(sub, axis = 1)
fig = np.argmin(dis)
if train_face_number[fig] == test_face_number[i]:
count = count + 1
correct_rate = count / test_face.shape[0]
# show the parameters and results
print("Principal rate=", principal_percent * 100, "%, count for", int(v.shape[1]*principal_percent), "principal eigenvectors")
print("Correct rate =", correct_rate * 100 , "%")
#show feature maps
if feature_face == True:
import matplotlib.pyplot as plt
plt.figure('Feature Maps')
r, c = (4, 10)
for i in range(r * c):
plt.subplot(r,c,i+1)
plt.imshow(v[:, i].real.reshape(int(112 * scale), int(92 * scale)), cmap='gray')
plt.axis('off')
plt.show()