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 * support functions for training and test samples creation.
48 #include "cvhaartraining.h"
49 #include "_cvhaartraining.h"
51 /* if ipl.h file is included then iplWarpPerspectiveQ function
52 is used for image transformation during samples creation;
53 otherwise internal cvWarpPerspective function is used */
60 /* Calculates coefficients of perspective transformation
61 * which maps <quad> into rectangle ((0,0), (w,0), (w,h), (h,0)):
63 * c00*xi + c01*yi + c02
64 * ui = ---------------------
65 * c20*xi + c21*yi + c22
67 * c10*xi + c11*yi + c12
68 * vi = ---------------------
69 * c20*xi + c21*yi + c22
71 * Coefficients are calculated by solving linear system:
72 * / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\
73 * | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1|
74 * | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2|
75 * | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|,
76 * | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0|
77 * | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1|
78 * | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2|
79 * \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/
82 * (xi, yi) = (quad[i][0], quad[i][1])
83 * cij - coeffs[i][j], coeffs[2][2] = 1
84 * (ui, vi) - rectangle vertices
86 void cvGetPerspectiveTransform( CvSize src_size, double quad[4][2],
89 //CV_FUNCNAME( "cvWarpPerspective" );
96 CvMat A = cvMat( 8, 8, CV_64FC1, a );
97 CvMat B = cvMat( 8, 1, CV_64FC1, b );
98 CvMat X = cvMat( 8, 1, CV_64FC1, coeffs );
101 for( i = 0; i < 4; ++i )
103 a[i][0] = quad[i][0]; a[i][1] = quad[i][1]; a[i][2] = 1;
104 a[i][3] = a[i][4] = a[i][5] = a[i][6] = a[i][7] = 0;
107 for( i = 4; i < 8; ++i )
109 a[i][3] = quad[i-4][0]; a[i][4] = quad[i-4][1]; a[i][5] = 1;
110 a[i][0] = a[i][1] = a[i][2] = a[i][6] = a[i][7] = 0;
114 int u = src_size.width - 1;
115 int v = src_size.height - 1;
117 a[1][6] = -quad[1][0] * u; a[1][7] = -quad[1][1] * u;
118 a[2][6] = -quad[2][0] * u; a[2][7] = -quad[2][1] * u;
121 a[6][6] = -quad[2][0] * v; a[6][7] = -quad[2][1] * v;
122 a[7][6] = -quad[3][0] * v; a[7][7] = -quad[3][1] * v;
125 cvSolve( &A, &B, &X );
132 /* Warps source into destination by a perspective transform */
133 void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
135 CV_FUNCNAME( "cvWarpPerspective" );
140 IplImage src_stub, dst_stub;
143 CV_CALL( src_img = cvGetImage( src, &src_stub ) );
144 CV_CALL( dst_img = cvGetImage( dst, &dst_stub ) );
145 iplWarpPerspectiveQ( src_img, dst_img, quad, IPL_WARP_R_TO_Q,
146 IPL_INTER_CUBIC | IPL_SMOOTH_EDGE );
151 double c[3][3]; /* transformation coefficients */
152 double q[4][2]; /* rearranged quad */
160 double k_left, b_left, k_right, b_right;
174 if( !src || (!CV_IS_IMAGE( src ) && !CV_IS_MAT( src )) ||
175 cvGetElemType( src ) != CV_8UC1 ||
176 cvGetDims( src ) != 2 )
178 CV_ERROR( CV_StsBadArg,
179 "Source must be two-dimensional array of CV_8UC1 type." );
181 if( !dst || (!CV_IS_IMAGE( dst ) && !CV_IS_MAT( dst )) ||
182 cvGetElemType( dst ) != CV_8UC1 ||
183 cvGetDims( dst ) != 2 )
185 CV_ERROR( CV_StsBadArg,
186 "Destination must be two-dimensional array of CV_8UC1 type." );
189 CV_CALL( cvGetRawData( src, &src_data, &src_step, &src_size ) );
190 CV_CALL( cvGetRawData( dst, &dst_data, &dst_step, &dst_size ) );
192 CV_CALL( cvGetPerspectiveTransform( src_size, quad, c ) );
194 /* if direction > 0 then vertices in quad follow in a CW direction,
195 otherwise they follow in a CCW direction */
197 for( i = 0; i < 4; ++i )
199 int ni = i + 1; if( ni == 4 ) ni = 0;
200 int pi = i - 1; if( pi == -1 ) pi = 3;
202 d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) -
203 (quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]);
204 int cur_direction = CV_SIGN(d);
207 direction = cur_direction;
209 else if( direction * cur_direction < 0 )
217 CV_ERROR( CV_StsBadArg, "Quadrangle is nonconvex or degenerated." );
220 /* <left> is the index of the topmost quad vertice
221 if there are two such vertices <left> is the leftmost one */
223 for( i = 1; i < 4; ++i )
225 if( (quad[i][1] < quad[left][1]) ||
226 ((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) )
231 /* rearrange <quad> vertices in such way that they follow in a CW
232 direction and the first vertice is the topmost one and put them
236 for( i = left; i < 4; ++i )
238 q[i-left][0] = quad[i][0];
239 q[i-left][1] = quad[i][1];
241 for( i = 0; i < left; ++i )
243 q[4-left+i][0] = quad[i][0];
244 q[4-left+i][1] = quad[i][1];
249 for( i = left; i >= 0; --i )
251 q[left-i][0] = quad[i][0];
252 q[left-i][1] = quad[i][1];
254 for( i = 3; i > left; --i )
256 q[4+left-i][0] = quad[i][0];
257 q[4+left-i][1] = quad[i][1];
262 /* if there are two topmost points, <right> is the index of the rightmost one
264 if( q[left][1] == q[left+1][1] )
269 /* <next_left> follows <left> in a CCW direction */
271 /* <next_right> follows <right> in a CW direction */
272 next_right = right + 1;
274 /* subtraction of 1 prevents skipping of the first row */
275 y_min = q[left][1] - 1;
277 /* left edge equation: y = k_left * x + b_left */
278 k_left = (q[left][0] - q[next_left][0]) /
279 (q[left][1] - q[next_left][1]);
280 b_left = (q[left][1] * q[next_left][0] -
281 q[left][0] * q[next_left][1]) /
282 (q[left][1] - q[next_left][1]);
284 /* right edge equation: y = k_right * x + b_right */
285 k_right = (q[right][0] - q[next_right][0]) /
286 (q[right][1] - q[next_right][1]);
287 b_right = (q[right][1] * q[next_right][0] -
288 q[right][0] * q[next_right][1]) /
289 (q[right][1] - q[next_right][1]);
295 y_max = MIN( q[next_left][1], q[next_right][1] );
297 int iy_min = MAX( cvRound(y_min), 0 ) + 1;
298 int iy_max = MIN( cvRound(y_max), dst_size.height - 1 );
300 double x_min = k_left * iy_min + b_left;
301 double x_max = k_right * iy_min + b_right;
303 /* walk through the destination quadrangle row by row */
304 for( y = iy_min; y <= iy_max; ++y )
306 int ix_min = MAX( cvRound( x_min ), 0 );
307 int ix_max = MIN( cvRound( x_max ), dst_size.width - 1 );
309 for( x = ix_min; x <= ix_max; ++x )
311 /* calculate coordinates of the corresponding source array point */
312 double div = (c[2][0] * x + c[2][1] * y + c[2][2]);
313 double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div;
314 double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div;
316 int isrc_x = cvFloor( src_x );
317 int isrc_y = cvFloor( src_y );
318 double delta_x = src_x - isrc_x;
319 double delta_y = src_y - isrc_y;
321 uchar* s = src_data + isrc_y * src_step + isrc_x;
323 int i00, i10, i01, i11;
324 i00 = i10 = i01 = i11 = (int) fill_value;
326 double i = fill_value;
328 /* linear interpolation using 2x2 neighborhood */
329 if( isrc_x >= 0 && isrc_x <= src_size.width &&
330 isrc_y >= 0 && isrc_y <= src_size.height )
334 if( isrc_x >= -1 && isrc_x < src_size.width &&
335 isrc_y >= 0 && isrc_y <= src_size.height )
339 if( isrc_x >= 0 && isrc_x <= src_size.width &&
340 isrc_y >= -1 && isrc_y < src_size.height )
344 if( isrc_x >= -1 && isrc_x < src_size.width &&
345 isrc_y >= -1 && isrc_y < src_size.height )
350 double i0 = i00 + (i10 - i00)*delta_x;
351 double i1 = i01 + (i11 - i01)*delta_x;
352 i = i0 + (i1 - i0)*delta_y;
354 ((uchar*)(dst_data + y * dst_step))[x] = (uchar) i;
360 if( (next_left == next_right) ||
361 (next_left+1 == next_right && q[next_left][1] == q[next_right][1]) )
366 if( y_max == q[next_left][1] )
369 next_left = left - 1;
371 k_left = (q[left][0] - q[next_left][0]) /
372 (q[left][1] - q[next_left][1]);
373 b_left = (q[left][1] * q[next_left][0] -
374 q[left][0] * q[next_left][1]) /
375 (q[left][1] - q[next_left][1]);
377 if( y_max == q[next_right][1] )
380 next_right = right + 1;
382 k_right = (q[right][0] - q[next_right][0]) /
383 (q[right][1] - q[next_right][1]);
384 b_right = (q[right][1] * q[next_right][0] -
385 q[right][0] * q[next_right][1]) /
386 (q[right][1] - q[next_right][1]);
390 #endif /* #ifndef __IPL_H__ */
396 void icvRandomQuad( int width, int height, double quad[4][2],
401 double distfactor = 3.0;
402 double distfactor2 = 1.0;
407 double rotVectData[3];
409 double rotMatData[9];
417 rotVect = cvMat( 3, 1, CV_64FC1, &rotVectData[0] );
418 rotMat = cvMat( 3, 3, CV_64FC1, &rotMatData[0] );
419 vect = cvMat( 3, 1, CV_64FC1, &vectData[0] );
421 rotVectData[0] = maxxangle * (2.0 * rand() / RAND_MAX - 1.0);
422 rotVectData[1] = ( maxyangle - fabs( rotVectData[0] ) )
423 * (2.0 * rand() / RAND_MAX - 1.0);
424 rotVectData[2] = maxzangle * (2.0 * rand() / RAND_MAX - 1.0);
425 d = (distfactor + distfactor2 * (2.0 * rand() / RAND_MAX - 1.0)) * width;
428 rotVectData[0] = maxxangle;
429 rotVectData[1] = maxyangle;
430 rotVectData[2] = maxzangle;
432 d = distfactor * width;
435 cvRodrigues( &rotMat, &rotVect, NULL, CV_RODRIGUES_V2M );
438 halfh = 0.5 * height;
449 for( i = 0; i < 4; i++ )
451 rotVectData[0] = quad[i][0];
452 rotVectData[1] = quad[i][1];
453 rotVectData[2] = 0.0;
454 cvMatMulAdd( &rotMat, &rotVect, 0, &vect );
455 quad[i][0] = vectData[0] * d / (d + vectData[2]) + halfw;
456 quad[i][1] = vectData[1] * d / (d + vectData[2]) + halfh;
466 int icvStartSampleDistortion( const char* imgfilename, int bgcolor, int bgthreshold,
467 CvSampleDistortionData* data )
469 memset( data, 0, sizeof( *data ) );
470 data->src = cvLoadImage( imgfilename, 0 );
471 if( data->src != NULL && data->src->nChannels == 1
472 && data->src->depth == IPL_DEPTH_8U )
481 data->dx = data->src->width / 2;
482 data->dy = data->src->height / 2;
483 data->bgcolor = bgcolor;
485 data->mask = cvCloneImage( data->src );
486 data->erode = cvCloneImage( data->src );
487 data->dilate = cvCloneImage( data->src );
489 /* make mask image */
490 for( r = 0; r < data->mask->height; r++ )
492 for( c = 0; c < data->mask->width; c++ )
494 pmask = ( (uchar*) (data->mask->imageData + r * data->mask->widthStep)
496 if( bgcolor - bgthreshold <= (int) (*pmask) &&
497 (int) (*pmask) <= bgcolor + bgthreshold )
503 *pmask = (uchar) 255;
508 /* extend borders of source image */
509 cvErode( data->src, data->erode, 0, 1 );
510 cvDilate( data->src, data->dilate, 0, 1 );
511 for( r = 0; r < data->mask->height; r++ )
513 for( c = 0; c < data->mask->width; c++ )
515 pmask = ( (uchar*) (data->mask->imageData + r * data->mask->widthStep)
519 psrc = ( (uchar*) (data->src->imageData + r * data->src->widthStep)
522 ( (uchar*) (data->erode->imageData + r * data->erode->widthStep)
525 ( (uchar*)(data->dilate->imageData + r * data->dilate->widthStep)
527 de = (uchar)(bgcolor - (*perode));
528 dd = (uchar)((*pdilate) - bgcolor);
529 if( de >= dd && de > bgthreshold )
533 if( dd > de && dd > bgthreshold )
535 (*psrc) = (*pdilate);
541 data->img = cvCreateImage( cvSize( data->src->width + 2 * data->dx,
542 data->src->height + 2 * data->dy ),
544 data->maskimg = cvCloneImage( data->img );
552 void icvPlaceDistortedSample( CvArr* background,
553 int inverse, int maxintensitydev,
554 double maxxangle, double maxyangle, double maxzangle,
555 int inscribe, double maxshiftf, double maxscalef,
556 CvSampleDistortionData* data )
574 double xshift, yshift, randscale;
576 icvRandomQuad( data->src->width, data->src->height, quad,
577 maxxangle, maxyangle, maxzangle );
578 quad[0][0] += (double) data->dx;
579 quad[0][1] += (double) data->dy;
580 quad[1][0] += (double) data->dx;
581 quad[1][1] += (double) data->dy;
582 quad[2][0] += (double) data->dx;
583 quad[2][1] += (double) data->dy;
584 quad[3][0] += (double) data->dx;
585 quad[3][1] += (double) data->dy;
587 cvSet( data->img, cvScalar( data->bgcolor ) );
588 cvSet( data->maskimg, cvScalar( 0.0 ) );
590 cvWarpPerspective( data->src, data->img, quad );
591 cvWarpPerspective( data->mask, data->maskimg, quad );
593 cvSmooth( data->maskimg, data->maskimg, CV_GAUSSIAN, 3, 3 );
595 bgimg = cvGetMat( background, &stub );
599 cr.width = data->src->width;
600 cr.height = data->src->height;
604 /* quad's circumscribing rectangle */
605 cr.x = (int) MIN( quad[0][0], quad[3][0] );
606 cr.y = (int) MIN( quad[0][1], quad[1][1] );
607 cr.width = (int) (MAX( quad[1][0], quad[2][0] ) + 0.5F ) - cr.x;
608 cr.height = (int) (MAX( quad[2][1], quad[3][1] ) + 0.5F ) - cr.y;
611 xshift = maxshiftf * rand() / RAND_MAX;
612 yshift = maxshiftf * rand() / RAND_MAX;
614 cr.x -= (int) ( xshift * cr.width );
615 cr.y -= (int) ( yshift * cr.height );
616 cr.width = (int) ((1.0 + maxshiftf) * cr.width );
617 cr.height = (int) ((1.0 + maxshiftf) * cr.height);
619 randscale = maxscalef * rand() / RAND_MAX;
620 cr.x -= (int) ( 0.5 * randscale * cr.width );
621 cr.y -= (int) ( 0.5 * randscale * cr.height );
622 cr.width = (int) ((1.0 + randscale) * cr.width );
623 cr.height = (int) ((1.0 + randscale) * cr.height);
625 scale = MAX( ((float) cr.width) / bgimg->cols, ((float) cr.height) / bgimg->rows );
627 roi.x = (int) (-0.5F * (scale * bgimg->cols - cr.width) + cr.x);
628 roi.y = (int) (-0.5F * (scale * bgimg->rows - cr.height) + cr.y);
629 roi.width = (int) (scale * bgimg->cols);
630 roi.height = (int) (scale * bgimg->rows);
632 img = cvCreateImage( cvSize( bgimg->cols, bgimg->rows ), IPL_DEPTH_8U, 1 );
633 maskimg = cvCreateImage( cvSize( bgimg->cols, bgimg->rows ), IPL_DEPTH_8U, 1 );
635 cvSetImageROI( data->img, roi );
636 cvResize( data->img, img );
637 cvResetImageROI( data->img );
638 cvSetImageROI( data->maskimg, roi );
639 cvResize( data->maskimg, maskimg );
640 cvResetImageROI( data->maskimg );
642 forecolordev = (int) (maxintensitydev * (2.0 * rand() / RAND_MAX - 1.0));
644 for( r = 0; r < img->height; r++ )
646 for( c = 0; c < img->width; c++ )
648 pimg = (uchar*) img->imageData + r * img->widthStep + c;
649 pbg = (uchar*) bgimg->data.ptr + r * bgimg->step + c;
650 palpha = (uchar*) maskimg->imageData + r * maskimg->widthStep + c;
651 chartmp = (uchar) MAX( 0, MIN( 255, forecolordev + (*pimg) ) );
656 *pbg = (uchar) (( chartmp*(*palpha )+(255 - (*palpha) )*(*pbg) ) / 255);
660 cvReleaseImage( &img );
661 cvReleaseImage( &maskimg );
664 void icvEndSampleDistortion( CvSampleDistortionData* data )
668 cvReleaseImage( &data->src );
672 cvReleaseImage( &data->mask );
676 cvReleaseImage( &data->erode );
680 cvReleaseImage( &data->dilate );
684 cvReleaseImage( &data->img );
688 cvReleaseImage( &data->maskimg );
692 void icvWriteVecHeader( FILE* file, int count, int width, int height )
697 /* number of samples */
698 fwrite( &count, sizeof( count ), 1, file );
700 vecsize = width * height;
701 fwrite( &vecsize, sizeof( vecsize ), 1, file );
704 fwrite( &tmp, sizeof( tmp ), 1, file );
705 fwrite( &tmp, sizeof( tmp ), 1, file );
708 void icvWriteVecSample( FILE* file, CvArr* sample )
715 mat = cvGetMat( sample, &stub );
717 fwrite( &chartmp, sizeof( chartmp ), 1, file );
718 for( r = 0; r < mat->rows; r++ )
720 for( c = 0; c < mat->cols; c++ )
722 tmp = (short) (CV_MAT_ELEM( *mat, uchar, r, c ));
723 fwrite( &tmp, sizeof( tmp ), 1, file );
729 int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
732 int winwidth, int winheight )
734 char fullname[PATH_MAX];
744 int x, y, width, height;
747 assert( infoname != NULL );
748 assert( vecfilename != NULL );
751 if( !icvMkDir( vecfilename ) )
755 fprintf( stderr, "Unable to create directory hierarchy: %s\n", vecfilename );
756 #endif /* CV_VERBOSE */
761 info = fopen( infoname, "r" );
766 fprintf( stderr, "Unable to open file: %s\n", infoname );
767 #endif /* CV_VERBOSE */
772 vec = fopen( vecfilename, "wb" );
777 fprintf( stderr, "Unable to open file: %s\n", vecfilename );
778 #endif /* CV_VERBOSE */
785 sample = cvCreateImage( cvSize( winwidth, winheight ), IPL_DEPTH_8U, 1 );
787 icvWriteVecHeader( vec, num, sample->width, sample->height );
791 cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
794 strcpy( fullname, infoname );
795 filename = strrchr( fullname, '\\' );
796 if( filename == NULL )
798 filename = strrchr( fullname, '/' );
800 if( filename == NULL )
809 for( line = 1, error = 0, total = 0; total < num ;line++ )
813 error = ( fscanf( info, "%s %d", filename, &count ) != 2 );
816 src = cvLoadImage( fullname, 0 );
817 error = ( src == NULL );
822 fprintf( stderr, "Unable to open image: %s\n", fullname );
823 #endif /* CV_VERBOSE */
827 for( i = 0; (i < count) && (total < num); i++, total++ )
829 error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 );
831 cvSetImageROI( src, cvRect( x, y, width, height ) );
832 cvResize( src, sample, width >= sample->width &&
833 height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR );
837 cvShowImage( "Sample", sample );
838 if( cvWaitKey( 0 ) == 27 )
843 icvWriteVecSample( vec, sample );
848 cvReleaseImage( &src );
855 fprintf( stderr, "%s(%d) : parse error", infoname, line );
856 #endif /* CV_VERBOSE */
864 cvReleaseImage( &sample );
874 void cvShowVecSamples( const char* filename, int winwidth, int winheight,
883 file.input = fopen( filename, "rb" );
885 if( file.input != NULL )
887 fread( &file.count, sizeof( file.count ), 1, file.input );
888 fread( &file.vecsize, sizeof( file.vecsize ), 1, file.input );
889 fread( &tmp, sizeof( tmp ), 1, file.input );
890 fread( &tmp, sizeof( tmp ), 1, file.input );
892 if( file.vecsize != winwidth * winheight )
897 fprintf( stderr, "Warning: specified sample width=%d and height=%d "
898 "does not correspond to .vec file vector size=%d.\n",
899 winwidth, winheight, file.vecsize );
900 if( file.vecsize > 0 )
902 guessed_w = cvFloor( sqrt( (float) file.vecsize ) );
905 guessed_h = file.vecsize / guessed_w;
909 if( guessed_w <= 0 || guessed_h <= 0 || guessed_w * guessed_h != file.vecsize)
911 fprintf( stderr, "Error: failed to guess sample width and height\n" );
912 fclose( file.input );
918 winwidth = guessed_w;
919 winheight = guessed_h;
920 fprintf( stderr, "Guessed width=%d, guessed height=%d\n",
921 winwidth, winheight );
925 if( !feof( file.input ) && scale > 0 )
927 CvMat* scaled_sample = 0;
930 file.vector = (short*) cvAlloc( sizeof( *file.vector ) * file.vecsize );
931 sample = scaled_sample = cvCreateMat( winheight, winwidth, CV_8UC1 );
934 scaled_sample = cvCreateMat( MAX( 1, cvCeil( scale * winheight ) ),
935 MAX( 1, cvCeil( scale * winwidth ) ),
938 cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
939 for( i = 0; i < file.count; i++ )
941 icvGetHaarTraininDataFromVecCallback( sample, &file );
942 if( scale != 1.0 ) cvResize( sample, scaled_sample, CV_INTER_LINEAR);
943 cvShowImage( "Sample", scaled_sample );
944 if( cvWaitKey( 0 ) == 27 ) break;
946 if( scaled_sample && scaled_sample != sample ) cvReleaseMat( &scaled_sample );
947 cvReleaseMat( &sample );
948 cvFree( &file.vector );
950 fclose( file.input );