jesorsky.cc

  1 const char *help = "\
  2 progname: jesorsky.cc\n\
  3 code2html: This program computes the face detection results using the Jesorsky measure.\n\
  4 version: Torch3 vision2.0, 2004-2005\n\
  5 (c) Christine Alves (alves@idiap.ch)\n";
  6 
  7 // face model (more to be added)
  8 #include "FrontalFace19x19.h"
  9 
 10 // GT measurer
 11 #include "jesorskyGTMeasurer.h"
 12 
 13 // geometry
 14 #include "Rectangle2D.h"
 15 
 16 // misc
 17 #include "CmdLine.h"
 18 #include "DiskXFile.h"
 19 
 20 using namespace Torch;
 21 
 22 int main(int argc, char *argv[])
 23 {
 24 	// Cmdline variables
 25    	char *gtlistposfilename;
 26    	char *inlistposfilename;
 27    	real threshold;
 28    	int postype;
 29    	bool oneface;
 30    	bool gtoneface;
 31 	bool verbose;
 32    	bool rect;
 33 	
 34 	CmdLine cmd;
 35 	cmd.info(help);
 36 	cmd.setBOption("write log", false);
 37 	
 38 	cmd.addText("\nArguments:");
 39 	cmd.addSCmdArg("gtlistposfile", &gtlistposfilename, "list of ground truth pos file");
 40 	cmd.addSCmdArg("inlistposfile", &inlistposfilename, "list of input pos file");
 41 	cmd.addText("\nOptions:");
 42 	cmd.addRCmdOption("-threshold", &threshold, 0.25, "threshold");
 43 	cmd.addICmdOption("-postype", &postype, 1, "pos type");
 44 	cmd.addBCmdOption("-gtoneface", &gtoneface, false, "gt one face");
 45 	cmd.addBCmdOption("-oneface", &oneface, false, "one face");
 46 	cmd.addBCmdOption("-rect", &rect, false, "the file contains rectangles coordinates");
 47 	cmd.addBCmdOption("-verbose", &verbose, false, "verbose");
 48 	
 49 	cmd.read(argc, argv);
 50   
 51 	//
 52 	Allocator *allocator = new Allocator;
 53 	char inposfilename[200];
 54 	char gtposfilename[200];
 55 	Point2D l_eye;
 56 	Point2D r_eye;
 57 	sPoint2D eyes[2];
 58 	bool found = true;
 59 	int ngt, nin;
 60 	real x1, y1, x2, y2;
 61 	int n_detected_faces;
 62 	int n_match_faces = 0;
 63 	int n_gt_faces = 0;
 64 	int s_n_gt_faces = 0;
 65 	int missed = 0;
 66 	int smissed = 0;
 67 	int fa = 0;
 68 	int sfa = 0;
 69 	real detect = 0;
 70 	real sdetect = 0;
 71 	
 72 
 73 	//
 74 	DiskXFile *inlistposfile = new DiskXFile(inlistposfilename, "r");
 75 	DiskXFile *gtlistposfile = new DiskXFile(gtlistposfilename, "r");
 76 	
 77 	gtlistposfile->scanf("%d", &ngt);
 78 	inlistposfile->scanf("%d", &nin);
 79 	
 80 	for (int i = 1; i <= ngt; i++) 
 81 	{
 82 		gtlistposfile->scanf("%s", gtposfilename);
 83 	   	inlistposfile->scanf("%s", inposfilename);
 84 		
 85 		if(verbose) message("   Comparing %s to %s", inposfilename, gtposfilename);
 86    
 87    		//-------------------------------------------------------------------	
 88    		//------------------- MATCHING --------------------------------------	
 89    		//-------------------------------------------------------------------
 90 		
 91 		DiskXFile *inposfile = NULL;
 92 	   	inposfile = new DiskXFile(inposfilename, "r");
 93 		if (oneface) n_detected_faces = 1;
 94 		else inposfile->scanf("%d", &n_detected_faces);
 95 	
 96 		//
 97 		if(verbose) message("Using 19x19 face model.");
 98 		FaceModel *face_model = NULL;
 99 		face_model = new(allocator) FrontalFace19x19(postype);
100 				 
101 		// Read the input file and for all detections, compare with the groundtruth 
102 		n_match_faces = 0;
103 		if (n_detected_faces != 0) 
104 		{
105 			for (int i=1;i<=n_detected_faces;i++) 
106 			{
107 			      inposfile->scanf("%f", &x1);
108 			      inposfile->scanf("%f", &y1);
109 			      inposfile->scanf("%f", &x2);
110 			      inposfile->scanf("%f", &y2);
111 				
112 			      // If the input file contains rectangles and not eyes: convert to eyes coordinates
113 			      if (rect) 
114 			      {
115 				 //
116 				 sPoint2D bbx[4];
117 				
118 				 //
119 				 bbx[0].x = x1;
120 				 bbx[0].y = y1;
121 				 bbx[1].x = x1 + x2;
122 				 bbx[1].y = y1;
123 				 bbx[2].x = x1 + x2;
124 				 bbx[2].y = y1 + y2;
125 				 bbx[3].x = x1;
126 				 bbx[3].y = y1 + y2;
127 	
128 		    		 // Jesorsky measurer: load the gt file, get the number of faces
129 				 jesorskyGTMeasurer *jesorsky = new(allocator) jesorskyGTMeasurer(face_model, gtoneface, threshold);
130 				 jesorsky->setBOption("verbose", verbose);
131 				 jesorsky->load(gtposfilename);
132 				 n_gt_faces = jesorsky->n_faces;
133 				
134 				 //
135 				 if(verbose) message("Jesorsky measure");
136 				 
137 				 found = jesorsky->measure(4, bbx);
138 				 
139 				 allocator->free(jesorsky);
140 			      } 
141 			      else 
142 			      {
143 	   			l_eye.x = x1; 
144 	   			l_eye.y = y1;
145 	   			r_eye.x = x2; 
146 	   			r_eye.y = y2;
147 				eyes[0].x = l_eye.x;
148 		   		eyes[0].y = l_eye.y;
149 				eyes[1].x = r_eye.x;
150 		   		eyes[1].y = r_eye.y;
151 
152 		    		// Jesorsky measurer: load the gt file, get the number of faces
153 				jesorskyGTMeasurer *jesorsky = new(allocator) jesorskyGTMeasurer(face_model, gtoneface, threshold);
154 				jesorsky->setBOption("verbose", verbose);
155 				jesorsky->load(gtposfilename);
156 				n_gt_faces = jesorsky->n_faces;
157    
158 				//
159 				if(verbose) message("Jesorsky measure");
160 
161     		    		found = jesorsky->measure(2, eyes);
162 
163 				allocator->free(jesorsky);
164 			      }
165 			
166 			      // Count the number of faces correctly detected in the input file
167 			      if (found) n_match_faces ++;	
168 			}
169 			
170 		} 
171 		else 
172 		{
173 		   l_eye.x = 0;
174 		   l_eye.y = 0;
175 		   r_eye.x = 0;
176 		   r_eye.y = 0;
177 
178 		   // Jesorsky measurer: load the gt file, get the number of faces
179 		   jesorskyGTMeasurer *jesorsky = new(allocator) jesorskyGTMeasurer(face_model, gtoneface, threshold);
180 		   jesorsky->setBOption("verbose", verbose);
181 		   jesorsky->load(gtposfilename);
182 		   n_gt_faces = jesorsky->n_faces;
183 		   
184 		   missed = n_gt_faces;
185 		   fa = 0;
186 				
187 		   allocator->free(jesorsky);
188 		}
189 
190 		// Delete the input file
191 		delete inposfile;
192 	 
193    		//-------------------------------------------------------------------	
194    		//------------------- EVALUATION ------------------------------------	
195    		//-------------------------------------------------------------------
196 	
197 	   	if (n_detected_faces == n_gt_faces) {
198 	      		if (n_match_faces == n_gt_faces) {
199 	  			missed = 0;
200 				fa = 0;
201 	       		} else if (n_match_faces < n_gt_faces) {
202 		  		missed = n_gt_faces - n_match_faces;
203 				fa = 0;
204        			}
205 		} else if (n_detected_faces > n_gt_faces) {
206 	       		if (n_match_faces == n_gt_faces) {
207 	  			missed = 0;
208 				fa = n_detected_faces - n_match_faces;
209 	       		} else if (n_match_faces < n_gt_faces) {
210 		  		missed = n_gt_faces - n_match_faces;
211 	 			fa = n_detected_faces - n_gt_faces;
212 	       		}
213 		} else {
214 	      		if (n_match_faces == n_detected_faces) {
215 	  			missed = n_gt_faces - n_match_faces;
216 				fa = 0;
217 	       		} else if (n_match_faces < n_detected_faces) {
218 		  		missed = n_gt_faces - n_match_faces;
219 				fa = n_detected_faces -  n_match_faces;
220        			}
221 		}
222 	
223 	     
224 		detect = n_match_faces;
225 		s_n_gt_faces += n_gt_faces;
226 		sdetect += detect;
227 		smissed += missed;
228 		sfa += fa;
229 	
230 		if(verbose)
231 		{
232 			print("   Detection : %f\n", detect);	  
233 			print("   Missed : %d\n", missed);	  
234 			print("   FA : %d\n\n", fa);	  
235 		}
236 	}
237 	
238 	print("Final result:\n");
239 	print("   GT Faces : %d\n", s_n_gt_faces);	  
240 	print("   Detected Faces : %f\n", sdetect);	  
241 	sdetect = (sdetect / s_n_gt_faces) * 100;
242 	print("   Percentage of detections : %f\n", sdetect);	  
243 	print("   Number of GT faces non detected (missed) : %d\n", smissed);	  
244 	print("   Number of non-faces detected as faces (FA) : %d\n", sfa);
245 
246 	delete inlistposfile;
247 	delete gtlistposfile;
248 	delete allocator;
249 
250 	return(0);
251 	
252 }