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
55 /* use clock() function insted of time() */
56 #define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
63 typedef struct HidCascade
69 typedef struct ObjectPos
74 int found; /* for reference */
78 int main( int argc, char* argv[] )
81 char* classifierdir = NULL;
82 //char* samplesdir = NULL;
85 double scale_factor = 1.2;
86 float maxSizeDiff = 1.5F;
87 float maxPosDiff = 0.3F;
89 /* number of stages. if <=0 all stages are used */
99 char fullname[PATH_MAX];
100 char detfilename[PATH_MAX];
102 char detname[] = "det-";
104 CvHaarClassifierCascade* cascade;
105 CvMemStorage* storage;
110 infoname = (char*)"";
114 printf( "Usage: %s\n -data <classifier_directory_name>\n"
115 " -info <collection_file_name>\n"
116 " [-maxSizeDiff <max_size_difference = %f>]\n"
117 " [-maxPosDiff <max_position_difference = %f>]\n"
118 " [-sf <scale_factor = %f>]\n"
120 " [-nos <number_of_stages = %d>]\n"
121 " [-rs <roc_size = %d>]\n"
122 " [-w <sample_width = %d>]\n"
123 " [-h <sample_height = %d>]\n",
124 argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
130 for( i = 1; i < argc; i++ )
132 if( !strcmp( argv[i], "-data" ) )
134 classifierdir = argv[++i];
136 else if( !strcmp( argv[i], "-info" ) )
138 infoname = argv[++i];
140 else if( !strcmp( argv[i], "-maxSizeDiff" ) )
142 maxSizeDiff = (float) atof( argv[++i] );
144 else if( !strcmp( argv[i], "-maxPosDiff" ) )
146 maxPosDiff = (float) atof( argv[++i] );
148 else if( !strcmp( argv[i], "-sf" ) )
150 scale_factor = atof( argv[++i] );
152 else if( !strcmp( argv[i], "-ni" ) )
156 else if( !strcmp( argv[i], "-nos" ) )
158 nos = atoi( argv[++i] );
160 else if( !strcmp( argv[i], "-rs" ) )
162 rocsize = atoi( argv[++i] );
164 else if( !strcmp( argv[i], "-w" ) )
166 width = atoi( argv[++i] );
168 else if( !strcmp( argv[i], "-h" ) )
170 height = atoi( argv[++i] );
174 cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
175 if( cascade == NULL )
177 printf( "Unable to load classifier from %s\n", classifierdir );
182 int* numclassifiers = new int[cascade->count];
183 numclassifiers[0] = cascade->stage_classifier[0].count;
184 for( i = 1; i < cascade->count; i++ )
186 numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
189 storage = cvCreateMemStorage();
191 nos0 = cascade->count;
195 strcpy( fullname, infoname );
196 filename = strrchr( fullname, '\\' );
197 if( filename == NULL )
199 filename = strrchr( fullname, '/' );
201 if( filename == NULL )
210 info = fopen( infoname, "r" );
214 int x, y, width, height;
216 int hits, missed, falseAlarms;
217 int totalHits, totalMissed, totalFalseAlarms;
230 pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
231 neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
232 for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
234 printf( "+================================+======+======+======+\n" );
235 printf( "| File Name | Hits |Missed| False|\n" );
236 printf( "+================================+======+======+======+\n" );
238 totalHits = totalMissed = totalFalseAlarms = 0;
239 while( !feof( info ) )
241 if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
243 img = cvLoadImage( fullname );
246 ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
247 for( i = 0; i < refcount; i++ )
249 error = (fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4);
251 ref[i].x = 0.5F * width + x;
252 ref[i].y = 0.5F * height + y;
253 ref[i].width = sqrtf( 0.5F * (width * width + height * height) );
259 cvClearMemStorage( storage );
261 cascade->count = nos;
262 totaltime -= time( 0 );
263 objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
264 totaltime += time( 0 );
265 cascade->count = nos0;
267 detcount = ( objects ? objects->total : 0);
268 det = (detcount > 0) ?
269 ( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
270 hits = missed = falseAlarms = 0;
271 for( i = 0; i < detcount; i++ )
273 CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
274 det[i].x = 0.5F * r.rect.width + r.rect.x;
275 det[i].y = 0.5F * r.rect.height + r.rect.y;
276 det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
277 r.rect.height * r.rect.height) );
278 det[i].neghbors = r.neighbors;
282 cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
283 cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
284 CV_RGB( 255, 0, 0 ), 3 );
288 for( j = 0; j < refcount; j++ )
290 distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
291 (det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
292 if( (distance < ref[j].width * maxPosDiff) &&
293 (det[i].width > ref[j].width / maxSizeDiff) &&
294 (det[i].width < ref[j].width * maxSizeDiff) )
297 ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
304 neg[MIN(det[i].neghbors, rocsize - 1)]++;
307 for( j = 0; j < refcount; j++ )
312 pos[MIN(ref[j].neghbors, rocsize - 1)]++;
321 totalMissed += missed;
322 totalFalseAlarms += falseAlarms;
323 printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
324 printf( "+--------------------------------+------+------+------+\n" );
329 strcpy( detfilename, detname );
330 strcat( detfilename, filename );
331 strcpy( filename, detfilename );
332 cvvSaveImage( fullname, img );
335 if( det ) { cvFree( &det ); det = NULL; }
338 cvReleaseImage( &img );
343 printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
344 totalHits, totalMissed, totalFalseAlarms );
345 printf( "+================================+======+======+======+\n" );
346 printf( "Number of stages: %d\n", nos );
347 printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
348 printf( "Total time: %f\n", totaltime );
350 /* print ROC to stdout */
351 for( i = rocsize - 1; i > 0; i-- )
356 fprintf( stderr, "%d\n", nos );
357 for( i = 0; i < rocsize; i++ )
359 fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
360 ((float)pos[i]) / (totalHits + totalMissed),
361 ((float)neg[i]) / (totalHits + totalMissed) );
368 delete[] numclassifiers;
370 cvReleaseHaarClassifierCascade( &cascade );
371 cvReleaseMemStorage( &storage );