PageRenderTime 66ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/HaarTraining/src/performance.cpp

https://gitlab.com/zharfi/tutorial-haartraining
C++ | 374 lines | 281 code | 45 blank | 48 comment | 52 complexity | 2a7537bab87394e5aed85c3ee9dfd908 MD5 | raw file
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  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.
  8. //
  9. //
  10. // Intel License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2000, Intel Corporation, all rights reserved.
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  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.
  25. //
  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.
  28. //
  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.
  39. //
  40. //M*/
  41. /*
  42. * performance.cpp
  43. *
  44. * Measure performance of classifier
  45. */
  46. #include "cv.h"
  47. #include <stdio.h>
  48. #include <math.h>
  49. #include <highgui.h>
  50. #include <time.h>
  51. #ifdef _WIN32
  52. /* use clock() function insted of time() */
  53. #define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
  54. #endif /* _WIN32 */
  55. #ifndef PATH_MAX
  56. #define PATH_MAX 512
  57. #endif /* PATH_MAX */
  58. typedef struct HidCascade
  59. {
  60. int size;
  61. int count;
  62. } HidCascade;
  63. typedef struct ObjectPos
  64. {
  65. float x;
  66. float y;
  67. float width;
  68. int found; /* for reference */
  69. int neghbors;
  70. } ObjectPos;
  71. int main( int argc, char* argv[] )
  72. {
  73. int i, j;
  74. char* classifierdir = NULL;
  75. char* samplesdir = NULL;
  76. int saveDetected = 1;
  77. double scale_factor = 1.2;
  78. float maxSizeDiff = 1.5F;
  79. float maxPosDiff = 0.3F;
  80. /* number of stages. if <=0 all stages are used */
  81. int nos = -1, nos0;
  82. int width = 24;
  83. int height = 24;
  84. int rocsize;
  85. FILE* info;
  86. char* infoname;
  87. char fullname[PATH_MAX];
  88. char detfilename[PATH_MAX];
  89. char* filename;
  90. char detname[] = "det-";
  91. CvHaarClassifierCascade* cascade;
  92. CvMemStorage* storage;
  93. CvSeq* objects;
  94. double totaltime;
  95. infoname = "";
  96. rocsize = 40;
  97. if( argc == 1 )
  98. {
  99. printf( "Usage: %s\n -data <classifier_directory_name>\n"
  100. " -info <collection_file_name>\n"
  101. " [-maxSizeDiff <max_size_difference = %f>]\n"
  102. " [-maxPosDiff <max_position_difference = %f>]\n"
  103. " [-sf <scale_factor = %f>]\n"
  104. " [-ni]\n"
  105. " [-nos <number_of_stages = %d>]\n"
  106. " [-rs <roc_size = %d>]\n"
  107. " [-w <sample_width = %d>]\n"
  108. " [-h <sample_height = %d>]\n",
  109. argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
  110. width, height );
  111. return 0;
  112. }
  113. for( i = 1; i < argc; i++ )
  114. {
  115. if( !strcmp( argv[i], "-data" ) )
  116. {
  117. classifierdir = argv[++i];
  118. }
  119. else if( !strcmp( argv[i], "-info" ) )
  120. {
  121. infoname = argv[++i];
  122. }
  123. else if( !strcmp( argv[i], "-maxSizeDiff" ) )
  124. {
  125. maxSizeDiff = (float) atof( argv[++i] );
  126. }
  127. else if( !strcmp( argv[i], "-maxPosDiff" ) )
  128. {
  129. maxPosDiff = (float) atof( argv[++i] );
  130. }
  131. else if( !strcmp( argv[i], "-sf" ) )
  132. {
  133. scale_factor = atof( argv[++i] );
  134. }
  135. else if( !strcmp( argv[i], "-ni" ) )
  136. {
  137. saveDetected = 0;
  138. }
  139. else if( !strcmp( argv[i], "-nos" ) )
  140. {
  141. nos = atoi( argv[++i] );
  142. }
  143. else if( !strcmp( argv[i], "-rs" ) )
  144. {
  145. rocsize = atoi( argv[++i] );
  146. }
  147. else if( !strcmp( argv[i], "-w" ) )
  148. {
  149. width = atoi( argv[++i] );
  150. }
  151. else if( !strcmp( argv[i], "-h" ) )
  152. {
  153. height = atoi( argv[++i] );
  154. }
  155. }
  156. cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
  157. if( cascade == NULL )
  158. {
  159. printf( "Unable to load classifier from %s\n", classifierdir );
  160. return 1;
  161. }
  162. int* numclassifiers = new int[cascade->count];
  163. numclassifiers[0] = cascade->stage_classifier[0].count;
  164. for( i = 1; i < cascade->count; i++ )
  165. {
  166. numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
  167. }
  168. storage = cvCreateMemStorage();
  169. nos0 = cascade->count;
  170. if( nos <= 0 )
  171. nos = nos0;
  172. strcpy( fullname, infoname );
  173. filename = strrchr( fullname, '\\' );
  174. if( filename == NULL )
  175. {
  176. filename = strrchr( fullname, '/' );
  177. }
  178. if( filename == NULL )
  179. {
  180. filename = fullname;
  181. }
  182. else
  183. {
  184. filename++;
  185. }
  186. info = fopen( infoname, "r" );
  187. totaltime = 0.0;
  188. if( info != NULL )
  189. {
  190. int x, y, width, height;
  191. IplImage* img;
  192. int hits, missed, falseAlarms;
  193. int totalHits, totalMissed, totalFalseAlarms;
  194. int found;
  195. float distance;
  196. int refcount;
  197. ObjectPos* ref;
  198. int detcount;
  199. ObjectPos* det;
  200. int error;
  201. int* pos;
  202. int* neg;
  203. pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
  204. neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
  205. for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
  206. printf( "+================================+======+======+======+\n" );
  207. printf( "| File Name | Hits |Missed| False|\n" );
  208. printf( "+================================+======+======+======+\n" );
  209. totalHits = totalMissed = totalFalseAlarms = 0;
  210. while( !feof( info ) )
  211. {
  212. if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
  213. img = cvLoadImage( fullname );
  214. if( !img ) continue;
  215. ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
  216. for( i = 0; i < refcount; i++ )
  217. {
  218. error = (fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4);
  219. if( error ) break;
  220. ref[i].x = 0.5F * width + x;
  221. ref[i].y = 0.5F * height + y;
  222. ref[i].width = sqrtf( 0.5F * (width * width + height * height) );
  223. ref[i].found = 0;
  224. ref[i].neghbors = 0;
  225. }
  226. if( !error )
  227. {
  228. cvClearMemStorage( storage );
  229. cascade->count = nos;
  230. totaltime -= time( 0 );
  231. objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
  232. totaltime += time( 0 );
  233. cascade->count = nos0;
  234. detcount = ( objects ? objects->total : 0);
  235. det = (detcount > 0) ?
  236. ( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
  237. hits = missed = falseAlarms = 0;
  238. for( i = 0; i < detcount; i++ )
  239. {
  240. CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
  241. det[i].x = 0.5F * r.rect.width + r.rect.x;
  242. det[i].y = 0.5F * r.rect.height + r.rect.y;
  243. det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
  244. r.rect.height * r.rect.height) );
  245. det[i].neghbors = r.neighbors;
  246. if( saveDetected )
  247. {
  248. cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
  249. cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
  250. CV_RGB( 255, 0, 0 ), 3 );
  251. }
  252. found = 0;
  253. for( j = 0; j < refcount; j++ )
  254. {
  255. distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
  256. (det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
  257. if( (distance < ref[j].width * maxPosDiff) &&
  258. (det[i].width > ref[j].width / maxSizeDiff) &&
  259. (det[i].width < ref[j].width * maxSizeDiff) )
  260. {
  261. ref[j].found = 1;
  262. ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
  263. found = 1;
  264. }
  265. }
  266. if( !found )
  267. {
  268. falseAlarms++;
  269. neg[MIN(det[i].neghbors, rocsize - 1)]++;
  270. }
  271. }
  272. for( j = 0; j < refcount; j++ )
  273. {
  274. if( ref[j].found )
  275. {
  276. hits++;
  277. pos[MIN(ref[j].neghbors, rocsize - 1)]++;
  278. }
  279. else
  280. {
  281. missed++;
  282. }
  283. }
  284. totalHits += hits;
  285. totalMissed += missed;
  286. totalFalseAlarms += falseAlarms;
  287. printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
  288. printf( "+--------------------------------+------+------+------+\n" );
  289. fflush( stdout );
  290. if( saveDetected )
  291. {
  292. strcpy( detfilename, detname );
  293. strcat( detfilename, filename );
  294. strcpy( filename, detfilename );
  295. cvvSaveImage( fullname, img );
  296. }
  297. if( det ) { cvFree( &det ); det = NULL; }
  298. } /* if( !error ) */
  299. cvReleaseImage( &img );
  300. cvFree( &ref );
  301. }
  302. fclose( info );
  303. printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
  304. totalHits, totalMissed, totalFalseAlarms );
  305. printf( "+================================+======+======+======+\n" );
  306. printf( "Number of stages: %d\n", nos );
  307. printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
  308. printf( "Total time: %f\n", totaltime );
  309. /* print ROC to stdout */
  310. for( i = rocsize - 1; i > 0; i-- )
  311. {
  312. pos[i-1] += pos[i];
  313. neg[i-1] += neg[i];
  314. }
  315. fprintf( stderr, "%d\n", nos );
  316. for( i = 0; i < rocsize; i++ )
  317. {
  318. fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
  319. ((float)pos[i]) / (totalHits + totalMissed),
  320. ((float)neg[i]) / (totalHits + totalMissed) );
  321. }
  322. cvFree( &pos );
  323. cvFree( &neg );
  324. }
  325. delete[] numclassifiers;
  326. cvReleaseHaarClassifierCascade( &cascade );
  327. cvReleaseMemStorage( &storage );
  328. return 0;
  329. }