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 import numpy as np
38 import os
39 import unittest
40
41
42 from pyvision.face.FaceRecognizer import FaceRecognizer
43 from pyvision.analysis.FaceAnalysis import FaceRecognitionTest
44 import pyvision.vector.PCA
45
46
47
48 from pyvision.analysis.face import EyesFile
49
50
51
52 import pyvision as pv
53
54 PCA_L1 = 1
55 PCA_L2 = 2
56 PCA_COS = 3
57
58 PCA_NO_NORM = 1
59 PCA_MEAN_STD_NORM = 2
60 PCA_MEAN_UNIT_NORM = 3
61 PCA_UNIT_NORM = 4
62
63 -class PCA(FaceRecognizer):
64 ''' This is a basic implementation of PCA'''
65
66 - def __init__(self, face_size=(128,128), left_eye=pv.Point(32,52), right_eye=pv.Point(96,52), normalize=PCA_MEAN_STD_NORM, measure=PCA_COS, whiten=True, drop_front=2, basis_vectors=100):
67 '''Crate a PCA classifier'''
68 FaceRecognizer.__init__(self)
69
70 self.face_size = face_size
71 self.pca = pyvision.vector.PCA.PCA()
72 self.norm = normalize
73 self.trained = False
74
75 self.whiten = whiten
76 self.drop_front = drop_front
77 self.basis_vectors = basis_vectors
78 self.measure = measure
79 self.left_eye = left_eye
80 self.right_eye = right_eye
81
83 left,right = eyes
84 affine = pv.AffineFromPoints(left,right,self.left_eye,self.right_eye,self.face_size)
85 im = affine.transformImage(im)
86 return im
87
88
89
90
91
92
93
94
95
97 '''Given an image and face detection box, compute a face identification record'''
98 assert self.trained
99
100 img = self.cropFace(img,eyes)
101 vec = self.computeVector(img)
102 fir = self.pca.project(vec,whiten=True)
103 if self.measure == PCA_COS:
104 scale = np.sqrt((fir*fir).sum())
105 fir = (1.0/scale)*fir
106 return fir
107
121
123 '''Train the PCA classifier'''
124 assert self.trained == False
125
126 for img,_,eyes,_ in self.training_data:
127 img = self.cropFace(img,eyes)
128 vec = self.computeVector(img)
129 self.pca.addFeature(vec)
130
131 self.pca.train( drop_front=self.drop_front, number=self.basis_vectors)
132
133 self.trained = True
134
135
137 '''Compute the similarity of two faces'''
138 assert self.trained == True
139
140 if self.measure == PCA_L1:
141 return (np.abs(fir1-fir2)).sum()
142
143 if self.measure == PCA_L2:
144 return np.sqrt(((fir1-fir2)*(fir1-fir2)).sum())
145
146 if self.measure == PCA_COS:
147 return (fir1*fir2).sum()
148
149 raise NotImplementedError("Unknown distance measure: %d"%self.measure)
150
151
153 basis = self.pca.getBasis()
154 images = []
155
156 print basis.shape
157 r,_ = basis.shape
158 for i in range(r):
159 im = basis[i,:]
160 im = im.reshape(self.face_size)
161 im = pv.Image(im)
162 images.append(im)
163 print len(images)
164 return images
165
166
167
168 SCRAPS_FACE_DATA = os.path.join(pyvision.__path__[0],"data","csuScrapShots")
169
170 PCA_SIZE = (64,64)
171
173
175 self.images = []
176 self.names = []
177
178 self.eyes = EyesFile(os.path.join(SCRAPS_FACE_DATA,"coords.txt"))
179 for filename in self.eyes.files():
180 img = pv.Image(os.path.join(SCRAPS_FACE_DATA, filename + ".pgm"))
181 self.images.append(img)
182 self.names.append(filename)
183
184 self.assert_( len(self.images) == 173 )
185
186
188 face_test = FaceRecognitionTest.FaceRecognitionTest(name='PCA_CSUScraps',score_type=FaceRecognitionTest.SCORE_TYPE_HIGH)
189 pca = PCA(drop_front=2,basis_vectors=55)
190
191 for im_name in self.eyes.files():
192 im = pv.Image(os.path.join(SCRAPS_FACE_DATA, im_name + ".pgm"))
193 rect = self.eyes.getFaces(im_name)
194 eyes = self.eyes.getEyes(im_name)
195 pca.addTraining(im,rect=rect[0],eyes=eyes[0])
196
197 pca.train()
198
199 face_records = {}
200 for im_name in self.eyes.files():
201 im = pv.Image(os.path.join(SCRAPS_FACE_DATA, im_name + ".pgm"))
202 rect = self.eyes.getFaces(im_name)
203 eyes = self.eyes.getEyes(im_name)
204 fr = pca.computeFaceRecord(im,rect=rect[0],eyes=eyes[0])
205 face_records[im_name] = fr
206
207 for i_name in face_records.keys():
208 scores = []
209 for j_name in face_records.keys():
210 similarity = pca.similarity(face_records[i_name],face_records[j_name])
211 scores.append((j_name,similarity))
212 face_test.addSample(i_name,scores)
213
214
215 self.assertAlmostEqual(face_test.rank1_rate,0.43930635838150289)
216 self.assertAlmostEqual(face_test.rank1_bounds[0],0.3640772723094895)
217 self.assertAlmostEqual(face_test.rank1_bounds[1],0.51665118592791259)
218
219 roc = face_test.getROCAnalysis()
220
221
222 _ = roc.getFAR(far=0.01)
223
224
225
226
227
228
229