Package pyvision :: Package analysis :: Package FaceAnalysis :: Module FaceRecognitionTest
[hide private]
[frames] | no frames]

Source Code for Module pyvision.analysis.FaceAnalysis.FaceRecognitionTest

  1  # PyVision License 
  2  # 
  3  # Copyright (c) 2006-2008 David S. Bolme 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  #  
 10  # 1. Redistributions of source code must retain the above copyright 
 11  # notice, this list of conditions and the following disclaimer. 
 12  #  
 13  # 2. Redistributions in binary form must reproduce the above copyright 
 14  # notice, this list of conditions and the following disclaimer in the 
 15  # documentation and/or other materials provided with the distribution. 
 16  #  
 17  # 3. Neither name of copyright holders nor the names of its contributors 
 18  # may be used to endorse or promote products derived from this software 
 19  # without specific prior written permission. 
 20  #  
 21  #  
 22  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 23  # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 24  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 25  # A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR 
 26  # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 27  # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 28  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 29  # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 30  # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 31  # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 32  # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 33   
 34  from pyvision.analysis import Table 
 35  from pyvision.analysis.roc import ROC 
 36  from pyvision.analysis.stats import cibinom 
 37   
 38   
39 -def firstFive(im_id):
40 ''' 41 Parses the identity from the image id using the first five 42 charicters. This is a very common scheme for many face datasets. 43 44 This will work for: FERET or CSU_Scraps 45 ''' 46 return im_id[:5]
47 48 49 # SCORE_LOW is for distance like measures where low scores 50 # indicate a better match 51 SCORE_TYPE_LOW = 0 52 # SCORE_HIGH is for similarity like measures where high scores 53 # indicate a better match 54 SCORE_TYPE_HIGH = 1 55
56 -class FaceRecognitionTest:
57
58 - def __init__(self, name=None, id_func=firstFive, score_type=SCORE_TYPE_LOW):
59 ''' 60 Create a face recognition test object. 61 ''' 62 self.name = name 63 self.id_func = id_func 64 self.score_type = score_type 65 66 self.probes_table = Table.Table() 67 self.nonmatch_table = Table.Table() 68 self.rank_table = Table.Table() 69 70 self.total_probes = 0 71 self.total_gallery = 0 72 self.rank1_success = 0 73 74 self.positives = [] 75 self.negatives = []
76
77 - def getROCAnalysis(self):
78 return ROC(self.positives,self.negatives)
79
80 - def addSample(self,probe_id,scores):
81 ''' 82 Adds a sample to the test. The similarity scores is a list of 83 tuples that contain tuples of (gallery_id, score) 84 ''' 85 if self.score_type == SCORE_TYPE_LOW: 86 scores.sort( lambda x,y: cmp(x[1],y[1]) ) 87 elif self.score_type == SCORE_TYPE_HIGH: 88 scores.sort( lambda x,y: -cmp(x[1],y[1]) ) 89 else: 90 raise ValueError("Unknown score type: %s"%self.score_type) 91 92 best_match_id = None 93 best_match_score = None 94 best_match_rank = None 95 best_nonmatch_id = None 96 best_nonmatch_score = None 97 best_nonmatch_rank = None 98 99 pid = self.id_func(probe_id) 100 rank = 0 101 for gallery_id,score in scores: 102 if probe_id == gallery_id: 103 # Probe and gallery should not be the same image 104 continue 105 gid = self.id_func(gallery_id) 106 match = False 107 if pid == gid: 108 match = True 109 110 if match and best_match_id == None: 111 best_match_id = gallery_id 112 best_match_score = score 113 best_match_rank = rank 114 115 if not match and best_nonmatch_id == None: 116 best_nonmatch_id = gallery_id 117 best_nonmatch_score = score 118 best_nonmatch_rank = rank 119 120 if match: 121 self.positives.append(score) 122 else: 123 self.negatives.append(score) 124 125 rank += 1 126 127 self.total_probes += 1 128 self.total_gallery = max(self.total_gallery,rank) 129 130 if best_match_rank==0: 131 self.rank1_success += 1 132 133 self.probes_table.setElement(probe_id,'MatchId',best_match_id) 134 self.probes_table.setElement(probe_id,'MatchScore',best_match_score) 135 self.probes_table.setElement(probe_id,'MatchRank',best_match_rank) 136 self.probes_table.setElement(probe_id,'Success',best_match_rank==0) 137 self.probes_table.setElement(probe_id,'NonMatchId',best_nonmatch_id) 138 self.probes_table.setElement(probe_id,'NonMatchScore',best_nonmatch_score) 139 self.probes_table.setElement(probe_id,'NonMatchRank',best_nonmatch_rank) 140 141 self.rank1_rate = float(self.rank1_success)/float(self.total_probes) 142 self.rank1_bounds = cibinom(self.total_probes,self.rank1_success)
143