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 Created on May 15, 2009
37
38 @author: bolme
39 '''
40
41
42 from FaceDatabase import FaceDatabase
43
44 import os
45 import copy
46 import pyvision as pv
47 import xml.etree.cElementTree as et
48 import shutil
49 import time
50
51
52 REDUCED_LEYE = pv.Point(128+64,256-20)
53 REDUCED_REYE = pv.Point(256+128-64,256-20)
54 REDUCED_SIZE = (512,512)
55
56 '''
57 This is a training set that does not include any overlap with the good bad and ugly.
58 '''
59 GOOD_BAD_UGLY_TRAINING = ['nd1S04201','nd1S04207','nd1S04211','nd1S04212','nd1S04213','nd1S04217','nd1S04219','nd1S04222',
60 'nd1S04226','nd1S04227','nd1S04228','nd1S04229','nd1S04243','nd1S04256','nd1S04265','nd1S04273',
61 'nd1S04274','nd1S04279','nd1S04282','nd1S04288','nd1S04295','nd1S04300','nd1S04305','nd1S04308',
62 'nd1S04315','nd1S04316','nd1S04320','nd1S04322','nd1S04323','nd1S04326','nd1S04331','nd1S04335',
63 'nd1S04337','nd1S04339','nd1S04344','nd1S04352','nd1S04358','nd1S04360','nd1S04361','nd1S04365',
64 'nd1S04366','nd1S04367','nd1S04368','nd1S04369','nd1S04371','nd1S04372','nd1S04374','nd1S04376',
65 'nd1S04378','nd1S04380','nd1S04381','nd1S04382','nd1S04386','nd1S04388','nd1S04392','nd1S04395',
66 'nd1S04402','nd1S04403','nd1S04409','nd1S04410','nd1S04411','nd1S04412','nd1S04414','nd1S04415',
67 'nd1S04418','nd1S04423','nd1S04424','nd1S04425','nd1S04428','nd1S04430','nd1S04431','nd1S04432',
68 'nd1S04433','nd1S04435','nd1S04437','nd1S04442','nd1S04444','nd1S04454','nd1S04460','nd1S04467',
69 'nd1S04471','nd1S04479','nd1S04487','nd1S04489','nd1S04495','nd1S04500','nd1S04513','nd1S04515',
70 'nd1S04516','nd1S04519','nd1S04520','nd1S04522','nd1S04523','nd1S04524','nd1S04525','nd1S04527',
71 'nd1S04529','nd1S04530','nd1S04533','nd1S04539','nd1S04540','nd1S04545','nd1S04548','nd1S04549',
72 'nd1S04551','nd1S04558','nd1S04559','nd1S04561','nd1S04563','nd1S04564','nd1S04572','nd1S04573',
73 'nd1S04577','nd1S04579','nd1S04582','nd1S04584','nd1S04585','nd1S04589','nd1S04598','nd1S04599',
74 'nd1S04600','nd1S04610','nd1S04618','nd1S04619','nd1S04624','nd1S04637','nd1S04638','nd1S04641',
75 'nd1S04644','nd1S04657','nd1S04675',]
76
80
81
83 '''
84 FRGC Experiment 1 is a controlled to controlled scenario
85 '''
86
89
91 '''
92 FRGC Experiment 4 is a controled to uncontrolled scenario
93
94 Note: The left and right eye in the metadata is relative to the
95 person. For the face structure this is reversed and follows
96 the pyvision convention which is relative to the image.
97 '''
98
100 self.location = location
101
102 self.data_path = os.path.join(location,"nd1")
103 self.metadata_path = os.path.join(location,"BEE_DIST","FRGC2.0","metadata","FRGC_2.0_Metadata.xml")
104
105 self.readSigsets()
106 self.readEyeData()
107
108
110 self.orig_sigset_path = os.path.join(self.location,"BEE_DIST","FRGC2.0","signature_sets","experiments","FRGC_Exp_2.0.4_Orig.xml")
111 self.query_sigset_path = os.path.join(self.location,"BEE_DIST","FRGC2.0","signature_sets","experiments","FRGC_Exp_2.0.4_Query.xml")
112 self.target_sigset_path = os.path.join(self.location,"BEE_DIST","FRGC2.0","signature_sets","experiments","FRGC_Exp_2.0.4_Target.xml")
113 self.training_sigset_path = os.path.join(self.location,"BEE_DIST","FRGC2.0","signature_sets","experiments","FRGC_Exp_2.0.4_Training.xml")
114
115 self.orig_sigset = pv.parseSigSet(self.orig_sigset_path)
116 self.query_sigset = pv.parseSigSet(self.query_sigset_path)
117 self.target_sigset = pv.parseSigSet(self.target_sigset_path)
118 self.training_sigset = pv.parseSigSet(self.training_sigset_path)
119
120 self.orig_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.orig_sigset ])
121 self.query_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.query_sigset ])
122 self.target_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.target_sigset ])
123 self.training_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.training_sigset ])
124
125 self.orig_keys = [ data[0]['name'] for key,data in self.orig_sigset ]
126 self.query_keys = [ data[0]['name'] for key,data in self.query_sigset ]
127 self.target_keys = [ data[0]['name'] for key,data in self.target_sigset ]
128 self.training_keys = [ data[0]['name'] for key,data in self.training_sigset ]
129
130
131 assert len(set(self.orig_keys)) == len(self.orig_keys)
132 assert len(set(self.query_keys + self.target_keys + self.training_keys)) == len(self.orig_keys)
133 assert len(set(self.query_keys + self.target_keys + self.training_keys)) == len(self.query_keys) + len(self.target_keys) + len(self.training_keys)
134
136 f = open(self.metadata_path,'rb')
137 xml = et.parse(f)
138
139 self.metadata = {}
140
141 for recording in xml.findall('Recording'):
142 md = FRGCMetadata()
143 md.rec_id = recording.get('recording_id')
144 md.sub_id = recording.get('subject_id')
145 md.capture_date = recording.get('capturedate')
146
147 md.left_eye = None
148 md.right_eye = None
149 md.nose = None
150 md.mouth = None
151
152 for leye_center in recording.findall('LeftEyeCenter'):
153 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
154 md.left_eye = pv.Point(x,y)
155
156 for leye_center in recording.findall('RightEyeCenter'):
157 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
158 md.right_eye = pv.Point(x,y)
159
160 for leye_center in recording.findall('Nose'):
161 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
162 md.nose = pv.Point(x,y)
163
164 for leye_center in recording.findall('Mouth'):
165 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
166 md.mouth = pv.Point(x,y)
167
168 self.metadata[md.rec_id] = md
169
170
173
176
179
181 return copy.copy(self.training_keys)
182
187
188
190 entry = self.orig_sigset_map[key]
191
192 face_obj = FaceDatabase.FaceObject()
193
194 face_obj.key = key
195 face_obj.person_id = entry[0]
196 face_obj.entry = entry
197 face_obj.metadata = self.metadata[key]
198
199
200
201 face_obj.left_eye = face_obj.metadata.right_eye
202 face_obj.right_eye = face_obj.metadata.left_eye
203
204 im_name = os.path.join(self.location,entry[1][0]['file-name'])
205 im = pv.Image(im_name)
206 face_obj.image = im
207
208 return face_obj
209
210
212 '''
213 FRGC Experiment 4 is a controled to uncontrolled scenario
214
215 Note: The left and right eye in the metadata is relative to the
216 person. For the face structure this is reversed and follows
217 the pyvision convention which is relative to the image.
218 '''
219
221 self.location = location
222
223 self.data_path = os.path.join(location,"nd1")
224 self.metadata_path = os.path.join(location,"BEE_DIST","FRGC1.0","metadata","FRGC_1.0_Metadata.xml")
225
226 self.readSigsets()
227 self.readEyeData()
228
229
231 self.orig_sigset_path = os.path.join(self.location,"BEE_DIST","FRGC1.0","signature_sets","all.xml")
232
233 self.orig_sigset = pv.parseSigSet(self.orig_sigset_path)
234
235
236 self.orig_sigset = filter(lambda x: len(x[1]) > 0, self.orig_sigset)
237
238 self.orig_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.orig_sigset ])
239
240 self.orig_keys = [ data[0]['name'] for key,data in self.orig_sigset ]
241
242
244 f = open(self.metadata_path,'rb')
245 xml = et.parse(f)
246
247 self.metadata = {}
248
249 for recording in xml.findall('Recording'):
250 md = FRGCMetadata()
251 md.rec_id = recording.get('recording_id')
252 md.sub_id = recording.get('subject_id')
253 md.capture_date = recording.get('capturedate')
254
255 md.left_eye = None
256 md.right_eye = None
257 md.nose = None
258 md.mouth = None
259
260 for leye_center in recording.findall('LeftEyeCenter'):
261 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
262 md.left_eye = pv.Point(x,y)
263
264 for leye_center in recording.findall('RightEyeCenter'):
265 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
266 md.right_eye = pv.Point(x,y)
267
268 for leye_center in recording.findall('Nose'):
269 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
270 md.nose = pv.Point(x,y)
271
272 for leye_center in recording.findall('Mouth'):
273 x,y = float(leye_center.get('x')),float(leye_center.get('y'))
274 md.mouth = pv.Point(x,y)
275
276 self.metadata[md.rec_id] = md
277
278
281
286
287
289 entry = self.orig_sigset_map[key]
290
291 face_obj = FaceDatabase.FaceObject()
292
293 face_obj.key = key
294 face_obj.person_id = entry[0]
295 face_obj.entry = entry
296 face_obj.metadata = self.metadata[key]
297
298
299
300 face_obj.left_eye = face_obj.metadata.right_eye
301 face_obj.right_eye = face_obj.metadata.left_eye
302
303 im_name = os.path.join(self.location,entry[1][0]['file-name'])
304 im = pv.Image(im_name)
305 face_obj.image = im
306
307 return face_obj
308
309
311 '''
312 FRGC Experiment 4 is a controled to uncontrolled scenario
313
314 Note: The left and right eye in the metadata is relative to the
315 person. For the face structure this is reversed and follows
316 the pyvision convention which is relative to the image.
317 '''
318
320 self.location = location
321
322 self.data_path = os.path.join(location,"nd1")
323
324 self.readSigsets()
325
326
328 self.sigset_dir = os.path.join(self.location,"sigsets")
329
330 self.orig_sigset_path = os.path.join(self.location,"sigsets","FRGC_Exp_2.0.4_Orig.xml")
331 self.query_sigset_path = os.path.join(self.location,"sigsets","FRGC_Exp_2.0.4_Query.xml")
332 self.target_sigset_path = os.path.join(self.location,"sigsets","FRGC_Exp_2.0.4_Target.xml")
333 self.training_sigset_path = os.path.join(self.location,"sigsets","FRGC_Exp_2.0.4_Training.xml")
334
335 self.orig_sigset = pv.parseSigSet(self.orig_sigset_path)
336 self.query_sigset = pv.parseSigSet(self.query_sigset_path)
337 self.target_sigset = pv.parseSigSet(self.target_sigset_path)
338 self.training_sigset = pv.parseSigSet(self.training_sigset_path)
339
340 self.orig_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.orig_sigset ])
341 self.query_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.query_sigset ])
342 self.target_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.target_sigset ])
343 self.training_sigset_map = dict([ (data[0]['name'],[key,data]) for key,data in self.training_sigset ])
344
345 self.orig_keys = [ data[0]['name'] for key,data in self.orig_sigset ]
346 self.query_keys = [ data[0]['name'] for key,data in self.query_sigset ]
347 self.target_keys = [ data[0]['name'] for key,data in self.target_sigset ]
348 self.training_keys = [ data[0]['name'] for key,data in self.training_sigset ]
349
350
351 assert len(set(self.orig_keys)) == len(self.orig_keys)
352 assert len(set(self.query_keys + self.target_keys + self.training_keys)) == len(self.orig_keys)
353 assert len(set(self.query_keys + self.target_keys + self.training_keys)) == len(self.query_keys) + len(self.target_keys) + len(self.training_keys)
354
355
358
361
364
366 return copy.copy(self.training_keys)
367
369 entry = self.orig_sigset_map[key]
370
371 face_obj = FaceDatabase.FaceObject()
372
373 face_obj.key = key
374 face_obj.person_id = entry[0]
375 face_obj.entry = entry
376
377
378
379 face_obj.left_eye = REDUCED_LEYE
380 face_obj.right_eye = REDUCED_REYE
381
382 im_name = os.path.join(self.location,'recordings',key+".jpg")
383 im = pv.Image(im_name)
384 face_obj.image = im
385
386 return face_obj
387
388
390 ''''''
391 print "Creating directories."
392 try:
393 os.makedirs(os.path.join(dest_dir,'recordings'))
394 except:
395 pass
396
397 try:
398 os.makedirs(os.path.join(dest_dir,'sigsets'))
399 except:
400 pass
401
402 print "Loading FRGC Information."
403 frgc = FRGC_Exp4(source_dir)
404
405 print "Processing Images."
406 keys = frgc.keys()
407 for i in xrange(len(keys)):
408 key = keys[i]
409 face = frgc[key]
410 print "Processing %d of %d:"%(i+1,len(keys)), key,face.person_id
411
412 affine = pv.AffineFromPoints(face.left_eye,face.right_eye,REDUCED_LEYE,REDUCED_REYE,REDUCED_SIZE)
413 tile = affine.transformImage(face.image)
414 tile.asPIL().save(os.path.join(dest_dir,'recordings',key+".jpg"),quality=95)
415
416
417
418
419 print "Copying sigsets."
420 shutil.copy(frgc.orig_sigset_path, os.path.join(dest_dir,'sigsets'))
421 shutil.copy(frgc.query_sigset_path, os.path.join(dest_dir,'sigsets'))
422 shutil.copy(frgc.target_sigset_path, os.path.join(dest_dir,'sigsets'))
423 shutil.copy(frgc.training_sigset_path, os.path.join(dest_dir,'sigsets'))
424
425 print "Copying metadata."
426 shutil.copy(frgc.metadata_path, os.path.join(dest_dir,'sigsets'))
427
428
429 -def FRGCExp4Test(database, algorithm, face_detector=None, eye_locator=None, n=None,verbose=10.0,ilog=None):
430 '''
431 Run the FRGC Experiment 4 Test
432
433 On completion this will produce a BEE distance matrix.
434 '''
435 message_time = time.time()
436 timer = pv.Timer()
437
438
439 query_keys = database.query()
440 if n != None:
441 query_keys = query_keys[:n]
442 query_recs = []
443 timer.mark("QueryStart")
444 i = 0
445 for key in query_keys:
446 i += 1
447 face = database[key]
448
449 face_rec = algorithm.getFaceRecord(face.image,None,face.left_eye,face.right_eye)
450 query_recs.append(face_rec)
451 if verbose:
452 if time.time() - message_time > verbose:
453 message_time = time.time()
454 print "Processed query image %d of %d"%(i,len(query_keys))
455
456 timer.mark("QueryStop",notes="Processed %d images."%len(query_keys))
457
458
459
460 message_time = time.time()
461 target_keys = database.target()
462 if n != None:
463 target_keys = target_keys[:n]
464 target_recs = []
465 timer.mark("TargetStart")
466 i = 0
467 for key in target_keys:
468 i += 1
469 face = database[key]
470
471 face_rec = algorithm.getFaceRecord(face.image,None,face.left_eye,face.right_eye)
472 target_recs.append(face_rec)
473 if verbose:
474 if time.time() - message_time > verbose:
475 message_time = time.time()
476 print "Processed target image %d of %d"%(i,len(target_keys))
477
478 timer.mark("TargetStop",notes="Processed %d images."%len(target_keys))
479
480 print "Finished processing FaceRecs (%d query, %d target)"%(len(query_keys),len(target_keys))
481
482
483 print "Computing similarity matrix..."
484 timer.mark("SimilarityStart")
485 mat = algorithm.similarityMatrix(query_recs,target_recs)
486 timer.mark("SimilarityStop",notes="Processed %d comparisons."%(mat.shape[0]*mat.shape[1],))
487
488 print "Completing task..."
489 print mat.shape
490
491 bee_mat = pv.BEEDistanceMatrix(mat,"FRGC_Exp_2.0.4_Query.xml", "FRGC_Exp_2.0.4_Target.xml", sigset_dir=database.sigset_dir, is_distance=False)
492
493 if ilog != None:
494 ilog(timer)
495
496 return bee_mat, timer
497