/source/3rd_party/opencv/sources/apps/haartraining/performance.cpp
C++ | 378 lines | 283 code | 46 blank | 49 comment | 52 complexity | 0f29d2009b72aa401dfabf83b1f3547f MD5 | raw file
- /*M///////////////////////////////////////////////////////////////////////////////////////
- //
- // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
- //
- // By downloading, copying, installing or using the software you agree to this license.
- // If you do not agree to this license, do not download, install,
- // copy or use the software.
- //
- //
- // Intel License Agreement
- // For Open Source Computer Vision Library
- //
- // Copyright (C) 2000, Intel Corporation, all rights reserved.
- // Third party copyrights are property of their respective owners.
- //
- // Redistribution and use in source and binary forms, with or without modification,
- // are permitted provided that the following conditions are met:
- //
- // * Redistribution's of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // * Redistribution's in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // * The name of Intel Corporation may not be used to endorse or promote products
- // derived from this software without specific prior written permission.
- //
- // This software is provided by the copyright holders and contributors "as is" and
- // any express or implied warranties, including, but not limited to, the implied
- // warranties of merchantability and fitness for a particular purpose are disclaimed.
- // In no event shall the Intel Corporation or contributors be liable for any direct,
- // indirect, incidental, special, exemplary, or consequential damages
- // (including, but not limited to, procurement of substitute goods or services;
- // loss of use, data, or profits; or business interruption) however caused
- // and on any theory of liability, whether in contract, strict liability,
- // or tort (including negligence or otherwise) arising in any way out of
- // the use of this software, even if advised of the possibility of such damage.
- //
- //M*/
- /*
- * performance.cpp
- *
- * Measure performance of classifier
- */
- #include "opencv2/core/core.hpp"
- #include "opencv2/core/internal.hpp"
- #include "cv.h"
- #include "highgui.h"
- #include <cstdio>
- #include <cmath>
- #include <ctime>
- #ifdef _WIN32
- /* use clock() function insted of time() */
- #define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
- #endif /* _WIN32 */
- #ifndef PATH_MAX
- #define PATH_MAX 512
- #endif /* PATH_MAX */
- typedef struct HidCascade
- {
- int size;
- int count;
- } HidCascade;
- typedef struct ObjectPos
- {
- float x;
- float y;
- float width;
- int found; /* for reference */
- int neghbors;
- } ObjectPos;
- int main( int argc, char* argv[] )
- {
- int i, j;
- char* classifierdir = NULL;
- //char* samplesdir = NULL;
- int saveDetected = 1;
- double scale_factor = 1.2;
- float maxSizeDiff = 1.5F;
- float maxPosDiff = 0.3F;
- /* number of stages. if <=0 all stages are used */
- int nos = -1, nos0;
- int width = 24;
- int height = 24;
- int rocsize;
- FILE* info;
- char* infoname;
- char fullname[PATH_MAX];
- char detfilename[PATH_MAX];
- char* filename;
- char detname[] = "det-";
- CvHaarClassifierCascade* cascade;
- CvMemStorage* storage;
- CvSeq* objects;
- double totaltime;
- infoname = (char*)"";
- rocsize = 40;
- if( argc == 1 )
- {
- printf( "Usage: %s\n -data <classifier_directory_name>\n"
- " -info <collection_file_name>\n"
- " [-maxSizeDiff <max_size_difference = %f>]\n"
- " [-maxPosDiff <max_position_difference = %f>]\n"
- " [-sf <scale_factor = %f>]\n"
- " [-ni]\n"
- " [-nos <number_of_stages = %d>]\n"
- " [-rs <roc_size = %d>]\n"
- " [-w <sample_width = %d>]\n"
- " [-h <sample_height = %d>]\n",
- argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
- width, height );
- return 0;
- }
- for( i = 1; i < argc; i++ )
- {
- if( !strcmp( argv[i], "-data" ) )
- {
- classifierdir = argv[++i];
- }
- else if( !strcmp( argv[i], "-info" ) )
- {
- infoname = argv[++i];
- }
- else if( !strcmp( argv[i], "-maxSizeDiff" ) )
- {
- maxSizeDiff = (float) atof( argv[++i] );
- }
- else if( !strcmp( argv[i], "-maxPosDiff" ) )
- {
- maxPosDiff = (float) atof( argv[++i] );
- }
- else if( !strcmp( argv[i], "-sf" ) )
- {
- scale_factor = atof( argv[++i] );
- }
- else if( !strcmp( argv[i], "-ni" ) )
- {
- saveDetected = 0;
- }
- else if( !strcmp( argv[i], "-nos" ) )
- {
- nos = atoi( argv[++i] );
- }
- else if( !strcmp( argv[i], "-rs" ) )
- {
- rocsize = atoi( argv[++i] );
- }
- else if( !strcmp( argv[i], "-w" ) )
- {
- width = atoi( argv[++i] );
- }
- else if( !strcmp( argv[i], "-h" ) )
- {
- height = atoi( argv[++i] );
- }
- }
- cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
- if( cascade == NULL )
- {
- printf( "Unable to load classifier from %s\n", classifierdir );
- return 1;
- }
- int* numclassifiers = new int[cascade->count];
- numclassifiers[0] = cascade->stage_classifier[0].count;
- for( i = 1; i < cascade->count; i++ )
- {
- numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
- }
- storage = cvCreateMemStorage();
- nos0 = cascade->count;
- if( nos <= 0 )
- nos = nos0;
- strcpy( fullname, infoname );
- filename = strrchr( fullname, '\\' );
- if( filename == NULL )
- {
- filename = strrchr( fullname, '/' );
- }
- if( filename == NULL )
- {
- filename = fullname;
- }
- else
- {
- filename++;
- }
- info = fopen( infoname, "r" );
- totaltime = 0.0;
- if( info != NULL )
- {
- int x, y;
- IplImage* img;
- int hits, missed, falseAlarms;
- int totalHits, totalMissed, totalFalseAlarms;
- int found;
- float distance;
- int refcount;
- ObjectPos* ref;
- int detcount;
- ObjectPos* det;
- int error=0;
- int* pos;
- int* neg;
- pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
- neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
- for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
- printf( "+================================+======+======+======+\n" );
- printf( "| File Name | Hits |Missed| False|\n" );
- printf( "+================================+======+======+======+\n" );
- totalHits = totalMissed = totalFalseAlarms = 0;
- while( !feof( info ) )
- {
- if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
- img = cvLoadImage( fullname );
- if( !img ) continue;
- ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
- for( i = 0; i < refcount; i++ )
- {
- int w, h;
- error = (fscanf( info, "%d %d %d %d", &x, &y, &w, &h ) != 4);
- if( error ) break;
- ref[i].x = 0.5F * w + x;
- ref[i].y = 0.5F * h + y;
- ref[i].width = sqrtf( 0.5F * (w * w + h * h) );
- ref[i].found = 0;
- ref[i].neghbors = 0;
- }
- if( !error )
- {
- cvClearMemStorage( storage );
- cascade->count = nos;
- totaltime -= time( 0 );
- objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
- totaltime += time( 0 );
- cascade->count = nos0;
- detcount = ( objects ? objects->total : 0);
- det = (detcount > 0) ?
- ( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
- hits = missed = falseAlarms = 0;
- for( i = 0; i < detcount; i++ )
- {
- CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
- det[i].x = 0.5F * r.rect.width + r.rect.x;
- det[i].y = 0.5F * r.rect.height + r.rect.y;
- det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
- r.rect.height * r.rect.height) );
- det[i].neghbors = r.neighbors;
- if( saveDetected )
- {
- cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
- cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
- CV_RGB( 255, 0, 0 ), 3 );
- }
- found = 0;
- for( j = 0; j < refcount; j++ )
- {
- distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
- (det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
- if( (distance < ref[j].width * maxPosDiff) &&
- (det[i].width > ref[j].width / maxSizeDiff) &&
- (det[i].width < ref[j].width * maxSizeDiff) )
- {
- ref[j].found = 1;
- ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
- found = 1;
- }
- }
- if( !found )
- {
- falseAlarms++;
- neg[MIN(det[i].neghbors, rocsize - 1)]++;
- }
- }
- for( j = 0; j < refcount; j++ )
- {
- if( ref[j].found )
- {
- hits++;
- pos[MIN(ref[j].neghbors, rocsize - 1)]++;
- }
- else
- {
- missed++;
- }
- }
- totalHits += hits;
- totalMissed += missed;
- totalFalseAlarms += falseAlarms;
- printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
- printf( "+--------------------------------+------+------+------+\n" );
- fflush( stdout );
- if( saveDetected )
- {
- strcpy( detfilename, detname );
- strcat( detfilename, filename );
- strcpy( filename, detfilename );
- cvvSaveImage( fullname, img );
- }
- if( det ) { cvFree( &det ); det = NULL; }
- } /* if( !error ) */
- cvReleaseImage( &img );
- cvFree( &ref );
- }
- fclose( info );
- printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
- totalHits, totalMissed, totalFalseAlarms );
- printf( "+================================+======+======+======+\n" );
- printf( "Number of stages: %d\n", nos );
- printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
- printf( "Total time: %f\n", totaltime );
- /* print ROC to stdout */
- for( i = rocsize - 1; i > 0; i-- )
- {
- pos[i-1] += pos[i];
- neg[i-1] += neg[i];
- }
- fprintf( stderr, "%d\n", nos );
- for( i = 0; i < rocsize; i++ )
- {
- fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
- ((float)pos[i]) / (totalHits + totalMissed),
- ((float)neg[i]) / (totalHits + totalMissed) );
- }
- cvFree( &pos );
- cvFree( &neg );
- }
- delete[] numclassifiers;
- cvReleaseHaarClassifierCascade( &cascade );
- cvReleaseMemStorage( &storage );
- return 0;
- }