1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
45 * Measure performance of classifier
54 /* use clock() function insted of time() */
55 #define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
62 typedef struct HidCascade
68 typedef struct ObjectPos
73 int found; /* for reference */
77 int main( int argc, char* argv[] )
80 char* classifierdir = NULL;
81 char* samplesdir = NULL;
84 double scale_factor = 1.2;
85 float maxSizeDiff = 1.5F;
86 float maxPosDiff = 0.3F;
88 /* number of stages. if <=0 all stages are used */
98 char fullname[PATH_MAX];
99 char detfilename[PATH_MAX];
101 char detname[] = "det-";
103 CvHaarClassifierCascade* cascade;
104 CvMemStorage* storage;
113 printf( "Usage: %s\n -data <classifier_directory_name>\n"
114 " -info <collection_file_name>\n"
115 " [-maxSizeDiff <max_size_difference = %f>]\n"
116 " [-maxPosDiff <max_position_difference = %f>]\n"
117 " [-sf <scale_factor = %f>]\n"
119 " [-nos <number_of_stages = %d>]\n"
120 " [-rs <roc_size = %d>]\n"
121 " [-w <sample_width = %d>]\n"
122 " [-h <sample_height = %d>]\n",
123 argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
129 for( i = 1; i < argc; i++ )
131 if( !strcmp( argv[i], "-data" ) )
133 classifierdir = argv[++i];
135 else if( !strcmp( argv[i], "-info" ) )
137 infoname = argv[++i];
139 else if( !strcmp( argv[i], "-maxSizeDiff" ) )
141 maxSizeDiff = (float) atof( argv[++i] );
143 else if( !strcmp( argv[i], "-maxPosDiff" ) )
145 maxPosDiff = (float) atof( argv[++i] );
147 else if( !strcmp( argv[i], "-sf" ) )
149 scale_factor = atof( argv[++i] );
151 else if( !strcmp( argv[i], "-ni" ) )
155 else if( !strcmp( argv[i], "-nos" ) )
157 nos = atoi( argv[++i] );
159 else if( !strcmp( argv[i], "-rs" ) )
161 rocsize = atoi( argv[++i] );
163 else if( !strcmp( argv[i], "-w" ) )
165 width = atoi( argv[++i] );
167 else if( !strcmp( argv[i], "-h" ) )
169 height = atoi( argv[++i] );
173 cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
174 if( cascade == NULL )
176 printf( "Unable to load classifier from %s\n", classifierdir );
181 int* numclassifiers = new int[cascade->count];
182 numclassifiers[0] = cascade->stage_classifier[0].count;
183 for( i = 1; i < cascade->count; i++ )
185 numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
188 storage = cvCreateMemStorage();
190 nos0 = cascade->count;
194 strcpy( fullname, infoname );
195 filename = strrchr( fullname, '\\' );
196 if( filename == NULL )
198 filename = strrchr( fullname, '/' );
200 if( filename == NULL )
209 info = fopen( infoname, "r" );
213 int x, y, width, height;
215 int hits, missed, falseAlarms;
216 int totalHits, totalMissed, totalFalseAlarms;
229 pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
230 neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
231 for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
233 printf( "+================================+======+======+======+\n" );
234 printf( "| File Name | Hits |Missed| False|\n" );
235 printf( "+================================+======+======+======+\n" );
237 totalHits = totalMissed = totalFalseAlarms = 0;
238 while( !feof( info ) )
240 if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
242 img = cvLoadImage( fullname );
245 ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
246 for( i = 0; i < refcount; i++ )
248 error = (fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4);
250 ref[i].x = 0.5F * width + x;
251 ref[i].y = 0.5F * height + y;
252 ref[i].width = sqrtf( 0.5F * (width * width + height * height) );
258 cvClearMemStorage( storage );
260 cascade->count = nos;
261 totaltime -= time( 0 );
262 objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
263 totaltime += time( 0 );
264 cascade->count = nos0;
266 detcount = ( objects ? objects->total : 0);
267 det = (detcount > 0) ?
268 ( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
269 hits = missed = falseAlarms = 0;
270 for( i = 0; i < detcount; i++ )
272 CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
273 det[i].x = 0.5F * r.rect.width + r.rect.x;
274 det[i].y = 0.5F * r.rect.height + r.rect.y;
275 det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
276 r.rect.height * r.rect.height) );
277 det[i].neghbors = r.neighbors;
281 cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
282 cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
283 CV_RGB( 255, 0, 0 ), 3 );
287 for( j = 0; j < refcount; j++ )
289 distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
290 (det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
291 if( (distance < ref[j].width * maxPosDiff) &&
292 (det[i].width > ref[j].width / maxSizeDiff) &&
293 (det[i].width < ref[j].width * maxSizeDiff) )
296 ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
303 neg[MIN(det[i].neghbors, rocsize - 1)]++;
306 for( j = 0; j < refcount; j++ )
311 pos[MIN(ref[j].neghbors, rocsize - 1)]++;
320 totalMissed += missed;
321 totalFalseAlarms += falseAlarms;
322 printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
323 printf( "+--------------------------------+------+------+------+\n" );
328 strcpy( detfilename, detname );
329 strcat( detfilename, filename );
330 strcpy( filename, detfilename );
331 cvvSaveImage( fullname, img );
334 if( det ) { cvFree( &det ); det = NULL; }
337 cvReleaseImage( &img );
342 printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
343 totalHits, totalMissed, totalFalseAlarms );
344 printf( "+================================+======+======+======+\n" );
345 printf( "Number of stages: %d\n", nos );
346 printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
347 printf( "Total time: %f\n", totaltime );
349 /* print ROC to stdout */
350 for( i = rocsize - 1; i > 0; i-- )
355 fprintf( stderr, "%d\n", nos );
356 for( i = 0; i < rocsize; i++ )
358 fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
359 ((float)pos[i]) / (totalHits + totalMissed),
360 ((float)neg[i]) / (totalHits + totalMissed) );
367 delete[] numclassifiers;
369 cvReleaseHaarClassifierCascade( &cascade );
370 cvReleaseMemStorage( &storage );