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
47 #include "opencv2/core.hpp"
57 /* use clock() function insted of time() */
58 #define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
65 typedef struct HidCascade
71 typedef struct ObjectPos
76 int found; /* for reference */
80 int main( int argc, char* argv[] )
83 char* classifierdir = NULL;
84 //char* samplesdir = NULL;
87 double scale_factor = 1.2;
88 float maxSizeDiff = 1.5F;
89 float maxPosDiff = 0.3F;
91 /* number of stages. if <=0 all stages are used */
101 char fullname[PATH_MAX];
102 char detfilename[PATH_MAX];
104 char detname[] = "det-";
106 CvHaarClassifierCascade* cascade;
107 CvMemStorage* storage;
112 infoname = (char*)"";
116 printf( "Usage: %s\n -data <classifier_directory_name>\n"
117 " -info <collection_file_name>\n"
118 " [-maxSizeDiff <max_size_difference = %f>]\n"
119 " [-maxPosDiff <max_position_difference = %f>]\n"
120 " [-sf <scale_factor = %f>]\n"
122 " [-nos <number_of_stages = %d>]\n"
123 " [-rs <roc_size = %d>]\n"
124 " [-w <sample_width = %d>]\n"
125 " [-h <sample_height = %d>]\n",
126 argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
132 for( i = 1; i < argc; i++ )
134 if( !strcmp( argv[i], "-data" ) )
136 classifierdir = argv[++i];
138 else if( !strcmp( argv[i], "-info" ) )
140 infoname = argv[++i];
142 else if( !strcmp( argv[i], "-maxSizeDiff" ) )
144 maxSizeDiff = (float) atof( argv[++i] );
146 else if( !strcmp( argv[i], "-maxPosDiff" ) )
148 maxPosDiff = (float) atof( argv[++i] );
150 else if( !strcmp( argv[i], "-sf" ) )
152 scale_factor = atof( argv[++i] );
154 else if( !strcmp( argv[i], "-ni" ) )
158 else if( !strcmp( argv[i], "-nos" ) )
160 nos = atoi( argv[++i] );
162 else if( !strcmp( argv[i], "-rs" ) )
164 rocsize = atoi( argv[++i] );
166 else if( !strcmp( argv[i], "-w" ) )
168 width = atoi( argv[++i] );
170 else if( !strcmp( argv[i], "-h" ) )
172 height = atoi( argv[++i] );
176 cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
177 if( cascade == NULL )
179 printf( "Unable to load classifier from %s\n", classifierdir );
184 int* numclassifiers = new int[cascade->count];
185 numclassifiers[0] = cascade->stage_classifier[0].count;
186 for( i = 1; i < cascade->count; i++ )
188 numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
191 storage = cvCreateMemStorage();
193 nos0 = cascade->count;
197 strcpy( fullname, infoname );
198 filename = strrchr( fullname, '\\' );
199 if( filename == NULL )
201 filename = strrchr( fullname, '/' );
203 if( filename == NULL )
212 info = fopen( infoname, "r" );
218 int hits, missed, falseAlarms;
219 int totalHits, totalMissed, totalFalseAlarms;
232 pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
233 neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
234 for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
236 printf( "+================================+======+======+======+\n" );
237 printf( "| File Name | Hits |Missed| False|\n" );
238 printf( "+================================+======+======+======+\n" );
240 totalHits = totalMissed = totalFalseAlarms = 0;
241 while( !feof( info ) )
243 if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
245 img = cvLoadImage( fullname );
248 ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
249 for( i = 0; i < refcount; i++ )
252 error = (fscanf( info, "%d %d %d %d", &x, &y, &w, &h ) != 4);
254 ref[i].x = 0.5F * w + x;
255 ref[i].y = 0.5F * h + y;
256 ref[i].width = sqrtf( 0.5F * (w * w + h * h) );
262 cvClearMemStorage( storage );
264 cascade->count = nos;
265 totaltime -= time( 0 );
266 objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
267 totaltime += time( 0 );
268 cascade->count = nos0;
270 detcount = ( objects ? objects->total : 0);
271 det = (detcount > 0) ?
272 ( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
273 hits = missed = falseAlarms = 0;
274 for( i = 0; i < detcount; i++ )
276 CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
277 det[i].x = 0.5F * r.rect.width + r.rect.x;
278 det[i].y = 0.5F * r.rect.height + r.rect.y;
279 det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
280 r.rect.height * r.rect.height) );
281 det[i].neghbors = r.neighbors;
285 cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
286 cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
287 CV_RGB( 255, 0, 0 ), 3 );
291 for( j = 0; j < refcount; j++ )
293 distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
294 (det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
295 if( (distance < ref[j].width * maxPosDiff) &&
296 (det[i].width > ref[j].width / maxSizeDiff) &&
297 (det[i].width < ref[j].width * maxSizeDiff) )
300 ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
307 neg[MIN(det[i].neghbors, rocsize - 1)]++;
310 for( j = 0; j < refcount; j++ )
315 pos[MIN(ref[j].neghbors, rocsize - 1)]++;
324 totalMissed += missed;
325 totalFalseAlarms += falseAlarms;
326 printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
327 printf( "+--------------------------------+------+------+------+\n" );
332 strcpy( detfilename, detname );
333 strcat( detfilename, filename );
334 strcpy( filename, detfilename );
335 cvvSaveImage( fullname, img );
338 if( det ) { cvFree( &det ); det = NULL; }
341 cvReleaseImage( &img );
346 printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
347 totalHits, totalMissed, totalFalseAlarms );
348 printf( "+================================+======+======+======+\n" );
349 printf( "Number of stages: %d\n", nos );
350 printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
351 printf( "Total time: %f\n", totaltime );
353 /* print ROC to stdout */
354 for( i = rocsize - 1; i > 0; i-- )
359 fprintf( stderr, "%d\n", nos );
360 for( i = 0; i < rocsize; i++ )
362 fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
363 ((float)pos[i]) / (totalHits + totalMissed),
364 ((float)neg[i]) / (totalHits + totalMissed) );
371 delete[] numclassifiers;
373 cvReleaseHaarClassifierCascade( &cascade );
374 cvReleaseMemStorage( &storage );