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.
64 #include "_cvcommon.h"
65 #include "cvclassifier.h"
70 typedef struct CvValArray
76 #define CMP_VALUES( idx1, idx2 ) \
77 ( *( (float*) (aux->data + ((int) (idx1)) * aux->step ) ) < \
78 *( (float*) (aux->data + ((int) (idx2)) * aux->step ) ) )
80 CV_IMPLEMENT_QSORT_EX( icvSortIndexedValArray_16s, short, CMP_VALUES, CvValArray* )
82 CV_IMPLEMENT_QSORT_EX( icvSortIndexedValArray_32s, int, CMP_VALUES, CvValArray* )
84 CV_IMPLEMENT_QSORT_EX( icvSortIndexedValArray_32f, float, CMP_VALUES, CvValArray* )
87 void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols )
98 CV_Assert( idx != NULL );
99 CV_Assert( val != NULL );
101 idxtype = CV_MAT_TYPE( idx->type );
102 CV_Assert( idxtype == CV_16SC1 || idxtype == CV_32SC1 || idxtype == CV_32FC1 );
103 CV_Assert( CV_MAT_TYPE( val->type ) == CV_32FC1 );
106 CV_Assert( idx->rows == val->cols );
107 CV_Assert( idx->cols == val->rows );
108 istep = CV_ELEM_SIZE( val->type );
113 CV_Assert( idx->rows == val->rows );
114 CV_Assert( idx->cols == val->cols );
116 jstep = CV_ELEM_SIZE( val->type );
119 va.data = val->data.ptr;
124 for( i = 0; i < idx->rows; i++ )
126 for( j = 0; j < idx->cols; j++ )
128 CV_MAT_ELEM( *idx, short, i, j ) = (short) j;
130 icvSortIndexedValArray_16s( (short*) (idx->data.ptr + i * idx->step),
137 for( i = 0; i < idx->rows; i++ )
139 for( j = 0; j < idx->cols; j++ )
141 CV_MAT_ELEM( *idx, int, i, j ) = j;
143 icvSortIndexedValArray_32s( (int*) (idx->data.ptr + i * idx->step),
150 for( i = 0; i < idx->rows; i++ )
152 for( j = 0; j < idx->cols; j++ )
154 CV_MAT_ELEM( *idx, float, i, j ) = (float) j;
156 icvSortIndexedValArray_32f( (float*) (idx->data.ptr + i * idx->step),
169 void cvReleaseStumpClassifier( CvClassifier** classifier )
171 cvFree( classifier );
176 float cvEvalStumpClassifier( CvClassifier* classifier, CvMat* sample )
178 assert( classifier != NULL );
179 assert( sample != NULL );
180 assert( CV_MAT_TYPE( sample->type ) == CV_32FC1 );
182 if( (CV_MAT_ELEM( (*sample), float, 0,
183 ((CvStumpClassifier*) classifier)->compidx )) <
184 ((CvStumpClassifier*) classifier)->threshold )
185 return ((CvStumpClassifier*) classifier)->left;
186 return ((CvStumpClassifier*) classifier)->right;
189 #define ICV_DEF_FIND_STUMP_THRESHOLD( suffix, type, error ) \
190 CV_BOOST_IMPL int icvFindStumpThreshold_##suffix( \
191 uchar* data, size_t datastep, \
192 uchar* wdata, size_t wstep, \
193 uchar* ydata, size_t ystep, \
194 uchar* idxdata, size_t idxstep, int num, \
197 float* threshold, float* left, float* right, \
198 float* sumw, float* sumwy, float* sumwyy ) \
207 float curleft = 0.0F; \
208 float curright = 0.0F; \
209 float* prevval = NULL; \
210 float* curval = NULL; \
211 float curlerror = 0.0F; \
212 float currerror = 0.0F; \
219 wposl = wposr = 0.0F; \
220 if( *sumw == FLT_MAX ) \
222 /* calculate sums */ \
230 for( i = 0; i < num; i++ ) \
232 idx = (int) ( *((type*) (idxdata + i*idxstep)) ); \
233 w = (float*) (wdata + idx * wstep); \
235 y = (float*) (ydata + idx * ystep); \
238 *sumwyy += wy * (*y); \
242 for( i = 0; i < num; i++ ) \
244 idx = (int) ( *((type*) (idxdata + i*idxstep)) ); \
245 curval = (float*) (data + idx * datastep); \
246 /* for debug purpose */ \
247 if( i > 0 ) assert( (*prevval) <= (*curval) ); \
249 wyr = *sumwy - wyl; \
252 if( wl > 0.0 ) curleft = wyl / wl; \
253 else curleft = 0.0F; \
255 if( wr > 0.0 ) curright = wyr / wr; \
256 else curright = 0.0F; \
260 if( curlerror + currerror < (*lerror) + (*rerror) ) \
262 (*lerror) = curlerror; \
263 (*rerror) = currerror; \
264 *threshold = *curval; \
266 *threshold = 0.5F * (*threshold + *prevval); \
275 wl += *((float*) (wdata + idx * wstep)); \
276 wyl += (*((float*) (wdata + idx * wstep))) \
277 * (*((float*) (ydata + idx * ystep))); \
278 wyyl += *((float*) (wdata + idx * wstep)) \
279 * (*((float*) (ydata + idx * ystep))) \
280 * (*((float*) (ydata + idx * ystep))); \
282 while( (++i) < num && \
283 ( *((float*) (data + (idx = \
284 (int) ( *((type*) (idxdata + i*idxstep))) ) * datastep)) \
288 } /* for each value */ \
293 /* misclassification error
294 * err = MIN( wpos, wneg );
296 #define ICV_DEF_FIND_STUMP_THRESHOLD_MISC( suffix, type ) \
297 ICV_DEF_FIND_STUMP_THRESHOLD( misc_##suffix, type, \
298 wposl = 0.5F * ( wl + wyl ); \
299 wposr = 0.5F * ( wr + wyr ); \
300 curleft = 0.5F * ( 1.0F + curleft ); \
301 curright = 0.5F * ( 1.0F + curright ); \
302 curlerror = MIN( wposl, wl - wposl ); \
303 currerror = MIN( wposr, wr - wposr ); \
307 * err = 2 * wpos * wneg /(wpos + wneg)
309 #define ICV_DEF_FIND_STUMP_THRESHOLD_GINI( suffix, type ) \
310 ICV_DEF_FIND_STUMP_THRESHOLD( gini_##suffix, type, \
311 wposl = 0.5F * ( wl + wyl ); \
312 wposr = 0.5F * ( wr + wyr ); \
313 curleft = 0.5F * ( 1.0F + curleft ); \
314 curright = 0.5F * ( 1.0F + curright ); \
315 curlerror = 2.0F * wposl * ( 1.0F - curleft ); \
316 currerror = 2.0F * wposr * ( 1.0F - curright ); \
319 #define CV_ENTROPY_THRESHOLD FLT_MIN
322 * err = - wpos * log(wpos / (wpos + wneg)) - wneg * log(wneg / (wpos + wneg))
324 #define ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( suffix, type ) \
325 ICV_DEF_FIND_STUMP_THRESHOLD( entropy_##suffix, type, \
326 wposl = 0.5F * ( wl + wyl ); \
327 wposr = 0.5F * ( wr + wyr ); \
328 curleft = 0.5F * ( 1.0F + curleft ); \
329 curright = 0.5F * ( 1.0F + curright ); \
330 curlerror = currerror = 0.0F; \
331 if( curleft > CV_ENTROPY_THRESHOLD ) \
332 curlerror -= wposl * logf( curleft ); \
333 if( curleft < 1.0F - CV_ENTROPY_THRESHOLD ) \
334 curlerror -= (wl - wposl) * logf( 1.0F - curleft ); \
336 if( curright > CV_ENTROPY_THRESHOLD ) \
337 currerror -= wposr * logf( curright ); \
338 if( curright < 1.0F - CV_ENTROPY_THRESHOLD ) \
339 currerror -= (wr - wposr) * logf( 1.0F - curright ); \
342 /* least sum of squares error */
343 #define ICV_DEF_FIND_STUMP_THRESHOLD_SQ( suffix, type ) \
344 ICV_DEF_FIND_STUMP_THRESHOLD( sq_##suffix, type, \
345 /* calculate error (sum of squares) */ \
346 /* err = sum( w * (y - left(rigt)Val)^2 ) */ \
347 curlerror = wyyl + curleft * curleft * wl - 2.0F * curleft * wyl; \
348 currerror = (*sumwyy) - wyyl + curright * curright * wr - 2.0F * curright * wyr; \
351 ICV_DEF_FIND_STUMP_THRESHOLD_MISC( 16s, short )
353 ICV_DEF_FIND_STUMP_THRESHOLD_MISC( 32s, int )
355 ICV_DEF_FIND_STUMP_THRESHOLD_MISC( 32f, float )
358 ICV_DEF_FIND_STUMP_THRESHOLD_GINI( 16s, short )
360 ICV_DEF_FIND_STUMP_THRESHOLD_GINI( 32s, int )
362 ICV_DEF_FIND_STUMP_THRESHOLD_GINI( 32f, float )
365 ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( 16s, short )
367 ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( 32s, int )
369 ICV_DEF_FIND_STUMP_THRESHOLD_ENTROPY( 32f, float )
372 ICV_DEF_FIND_STUMP_THRESHOLD_SQ( 16s, short )
374 ICV_DEF_FIND_STUMP_THRESHOLD_SQ( 32s, int )
376 ICV_DEF_FIND_STUMP_THRESHOLD_SQ( 32f, float )
378 typedef int (*CvFindThresholdFunc)( uchar* data, size_t datastep,
379 uchar* wdata, size_t wstep,
380 uchar* ydata, size_t ystep,
381 uchar* idxdata, size_t idxstep, int num,
384 float* threshold, float* left, float* right,
385 float* sumw, float* sumwy, float* sumwyy );
387 CvFindThresholdFunc findStumpThreshold_16s[4] = {
388 icvFindStumpThreshold_misc_16s,
389 icvFindStumpThreshold_gini_16s,
390 icvFindStumpThreshold_entropy_16s,
391 icvFindStumpThreshold_sq_16s
394 CvFindThresholdFunc findStumpThreshold_32s[4] = {
395 icvFindStumpThreshold_misc_32s,
396 icvFindStumpThreshold_gini_32s,
397 icvFindStumpThreshold_entropy_32s,
398 icvFindStumpThreshold_sq_32s
401 CvFindThresholdFunc findStumpThreshold_32f[4] = {
402 icvFindStumpThreshold_misc_32f,
403 icvFindStumpThreshold_gini_32f,
404 icvFindStumpThreshold_entropy_32f,
405 icvFindStumpThreshold_sq_32f
409 CvClassifier* cvCreateStumpClassifier( CvMat* trainData,
413 CvMat* missedMeasurementsMask,
417 CvClassifierTrainParams* trainParams
420 CvStumpClassifier* stump = NULL;
421 int m = 0; /* number of samples */
422 int n = 0; /* number of components */
428 uchar* idxdata = NULL;
430 int l = 0; /* number of indices */
437 float sumw = FLT_MAX;
438 float sumwy = FLT_MAX;
439 float sumwyy = FLT_MAX;
441 CV_Assert( trainData != NULL );
442 CV_Assert( CV_MAT_TYPE( trainData->type ) == CV_32FC1 );
443 CV_Assert( trainClasses != NULL );
444 CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
445 CV_Assert( missedMeasurementsMask == NULL );
446 CV_Assert( compIdx == NULL );
447 CV_Assert( weights != NULL );
448 CV_Assert( CV_MAT_TYPE( weights->type ) == CV_32FC1 );
449 CV_Assert( trainParams != NULL );
451 data = trainData->data.ptr;
452 if( CV_IS_ROW_SAMPLE( flags ) )
454 cstep = CV_ELEM_SIZE( trainData->type );
455 sstep = trainData->step;
461 sstep = CV_ELEM_SIZE( trainData->type );
462 cstep = trainData->step;
467 ydata = trainClasses->data.ptr;
468 if( trainClasses->rows == 1 )
470 assert( trainClasses->cols == m );
471 ystep = CV_ELEM_SIZE( trainClasses->type );
475 assert( trainClasses->rows == m );
476 ystep = trainClasses->step;
479 wdata = weights->data.ptr;
480 if( weights->rows == 1 )
482 assert( weights->cols == m );
483 wstep = CV_ELEM_SIZE( weights->type );
487 assert( weights->rows == m );
488 wstep = weights->step;
492 if( sampleIdx != NULL )
494 assert( CV_MAT_TYPE( sampleIdx->type ) == CV_32FC1 );
496 idxdata = sampleIdx->data.ptr;
497 if( sampleIdx->rows == 1 )
500 idxstep = CV_ELEM_SIZE( sampleIdx->type );
505 idxstep = sampleIdx->step;
510 idx = (int*) cvAlloc( l * sizeof( int ) );
511 stump = (CvStumpClassifier*) cvAlloc( sizeof( CvStumpClassifier) );
514 memset( (void*) stump, 0, sizeof( CvStumpClassifier ) );
516 stump->eval = cvEvalStumpClassifier;
519 stump->release = cvReleaseStumpClassifier;
521 stump->lerror = FLT_MAX;
522 stump->rerror = FLT_MAX;
527 if( sampleIdx != NULL )
529 for( i = 0; i < l; i++ )
531 idx[i] = (int) *((float*) (idxdata + i*idxstep));
536 for( i = 0; i < l; i++ )
542 for( i = 0; i < n; i++ )
546 va.data = data + i * ((size_t) cstep);
548 icvSortIndexedValArray_32s( idx, l, &va );
549 if( findStumpThreshold_32s[(int) ((CvStumpTrainParams*) trainParams)->error]
550 ( data + i * ((size_t) cstep), sstep,
551 wdata, wstep, ydata, ystep, (uchar*) idx, sizeof( int ), l,
552 &(stump->lerror), &(stump->rerror),
553 &(stump->threshold), &(stump->left), &(stump->right),
554 &sumw, &sumwy, &sumwyy ) )
558 } /* for each component */
564 if( ((CvStumpTrainParams*) trainParams)->type == CV_CLASSIFICATION_CLASS )
566 stump->left = 2.0F * (stump->left >= 0.5F) - 1.0F;
567 stump->right = 2.0F * (stump->right >= 0.5F) - 1.0F;
570 return (CvClassifier*) stump;
574 * cvCreateMTStumpClassifier
576 * Multithreaded stump classifier constructor
577 * Includes huge train data support through callback function
580 CvClassifier* cvCreateMTStumpClassifier( CvMat* trainData,
584 CvMat* missedMeasurementsMask,
588 CvClassifierTrainParams* trainParams )
590 CvStumpClassifier* stump = NULL;
591 int m = 0; /* number of samples */
592 int n = 0; /* number of components */
596 int datan = 0; /* num components */
599 uchar* idxdata = NULL;
601 int l = 0; /* number of indices */
605 uchar* sorteddata = NULL;
607 size_t sortedcstep = 0; /* component step */
608 size_t sortedsstep = 0; /* sample step */
609 int sortedn = 0; /* num components */
610 int sortedm = 0; /* num samples */
619 /* private variables */
648 /* end private variables */
650 CV_Assert( trainParams != NULL );
651 CV_Assert( trainClasses != NULL );
652 CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
653 CV_Assert( missedMeasurementsMask == NULL );
654 CV_Assert( compIdx == NULL );
656 stumperror = (int) ((CvMTStumpTrainParams*) trainParams)->error;
658 ydata = trainClasses->data.ptr;
659 if( trainClasses->rows == 1 )
661 m = trainClasses->cols;
662 ystep = CV_ELEM_SIZE( trainClasses->type );
666 m = trainClasses->rows;
667 ystep = trainClasses->step;
670 wdata = weights->data.ptr;
671 if( weights->rows == 1 )
673 CV_Assert( weights->cols == m );
674 wstep = CV_ELEM_SIZE( weights->type );
678 CV_Assert( weights->rows == m );
679 wstep = weights->step;
682 if( ((CvMTStumpTrainParams*) trainParams)->sortedIdx != NULL )
685 CV_MAT_TYPE( ((CvMTStumpTrainParams*) trainParams)->sortedIdx->type );
686 assert( sortedtype == CV_16SC1 || sortedtype == CV_32SC1
687 || sortedtype == CV_32FC1 );
688 sorteddata = ((CvMTStumpTrainParams*) trainParams)->sortedIdx->data.ptr;
689 sortedsstep = CV_ELEM_SIZE( sortedtype );
690 sortedcstep = ((CvMTStumpTrainParams*) trainParams)->sortedIdx->step;
691 sortedn = ((CvMTStumpTrainParams*) trainParams)->sortedIdx->rows;
692 sortedm = ((CvMTStumpTrainParams*) trainParams)->sortedIdx->cols;
695 if( trainData == NULL )
697 assert( ((CvMTStumpTrainParams*) trainParams)->getTrainData != NULL );
698 n = ((CvMTStumpTrainParams*) trainParams)->numcomp;
703 assert( CV_MAT_TYPE( trainData->type ) == CV_32FC1 );
704 data = trainData->data.ptr;
705 if( CV_IS_ROW_SAMPLE( flags ) )
707 cstep = CV_ELEM_SIZE( trainData->type );
708 sstep = trainData->step;
709 assert( m == trainData->rows );
710 datan = n = trainData->cols;
714 sstep = CV_ELEM_SIZE( trainData->type );
715 cstep = trainData->step;
716 assert( m == trainData->cols );
717 datan = n = trainData->rows;
719 if( ((CvMTStumpTrainParams*) trainParams)->getTrainData != NULL )
721 n = ((CvMTStumpTrainParams*) trainParams)->numcomp;
724 assert( datan <= n );
726 if( sampleIdx != NULL )
728 assert( CV_MAT_TYPE( sampleIdx->type ) == CV_32FC1 );
729 idxdata = sampleIdx->data.ptr;
730 idxstep = ( sampleIdx->rows == 1 )
731 ? CV_ELEM_SIZE( sampleIdx->type ) : sampleIdx->step;
732 l = ( sampleIdx->rows == 1 ) ? sampleIdx->cols : sampleIdx->rows;
734 if( sorteddata != NULL )
736 filter = (char*) cvAlloc( sizeof( char ) * m );
737 memset( (void*) filter, 0, sizeof( char ) * m );
738 for( i = 0; i < l; i++ )
740 filter[(int) *((float*) (idxdata + i * idxstep))] = (char) 1;
749 stump = (CvStumpClassifier*) cvAlloc( sizeof( CvStumpClassifier) );
752 memset( (void*) stump, 0, sizeof( CvStumpClassifier ) );
754 portion = ((CvMTStumpTrainParams*)trainParams)->portion;
761 portion /= omp_get_max_threads();
765 stump->eval = cvEvalStumpClassifier;
768 stump->release = cvReleaseStumpClassifier;
770 stump->lerror = FLT_MAX;
771 stump->rerror = FLT_MAX;
777 #pragma omp parallel private(mat, va, lerror, rerror, left, right, threshold, \
778 optcompidx, sumw, sumwy, sumwyy, t_compidx, t_n, \
779 ti, tj, tk, t_data, t_cstep, t_sstep, matcstep, \
814 /* prepare matrix for callback */
815 if( CV_IS_ROW_SAMPLE( flags ) )
817 mat = cvMat( m, portion, CV_32FC1, 0 );
818 matcstep = CV_ELEM_SIZE( mat.type );
823 mat = cvMat( portion, m, CV_32FC1, 0 );
825 matsstep = CV_ELEM_SIZE( mat.type );
827 mat.data.ptr = (uchar*) cvAlloc( sizeof( float ) * mat.rows * mat.cols );
830 if( filter != NULL || sortedn < n )
832 t_idx = (int*) cvAlloc( sizeof( int ) * m );
833 if( sortedn == 0 || filter == NULL )
835 if( idxdata != NULL )
837 for( ti = 0; ti < l; ti++ )
839 t_idx[ti] = (int) *((float*) (idxdata + ti * idxstep));
844 for( ti = 0; ti < l; ti++ )
853 #pragma omp critical(c_compidx)
859 while( t_compidx < n )
862 if( t_compidx < datan )
864 t_n = ( t_n < (datan - t_compidx) ) ? t_n : (datan - t_compidx);
871 t_n = ( t_n < (n - t_compidx) ) ? t_n : (n - t_compidx);
874 t_data = mat.data.ptr - t_compidx * ((size_t) t_cstep );
876 /* calculate components */
877 ((CvMTStumpTrainParams*)trainParams)->getTrainData( &mat,
878 sampleIdx, compIdx, t_compidx, t_n,
879 ((CvMTStumpTrainParams*)trainParams)->userdata );
882 if( sorteddata != NULL )
886 /* have sorted indices and filter */
890 for( ti = t_compidx; ti < MIN( sortedn, t_compidx + t_n ); ti++ )
893 for( tj = 0; tj < sortedm; tj++ )
895 int curidx = (int) ( *((short*) (sorteddata
896 + ti * sortedcstep + tj * sortedsstep)) );
897 if( filter[curidx] != 0 )
899 t_idx[tk++] = curidx;
902 if( findStumpThreshold_32s[stumperror](
903 t_data + ti * t_cstep, t_sstep,
904 wdata, wstep, ydata, ystep,
905 (uchar*) t_idx, sizeof( int ), tk,
907 &threshold, &left, &right,
908 &sumw, &sumwy, &sumwyy ) )
915 for( ti = t_compidx; ti < MIN( sortedn, t_compidx + t_n ); ti++ )
918 for( tj = 0; tj < sortedm; tj++ )
920 int curidx = (int) ( *((int*) (sorteddata
921 + ti * sortedcstep + tj * sortedsstep)) );
922 if( filter[curidx] != 0 )
924 t_idx[tk++] = curidx;
927 if( findStumpThreshold_32s[stumperror](
928 t_data + ti * t_cstep, t_sstep,
929 wdata, wstep, ydata, ystep,
930 (uchar*) t_idx, sizeof( int ), tk,
932 &threshold, &left, &right,
933 &sumw, &sumwy, &sumwyy ) )
940 for( ti = t_compidx; ti < MIN( sortedn, t_compidx + t_n ); ti++ )
943 for( tj = 0; tj < sortedm; tj++ )
945 int curidx = (int) ( *((float*) (sorteddata
946 + ti * sortedcstep + tj * sortedsstep)) );
947 if( filter[curidx] != 0 )
949 t_idx[tk++] = curidx;
952 if( findStumpThreshold_32s[stumperror](
953 t_data + ti * t_cstep, t_sstep,
954 wdata, wstep, ydata, ystep,
955 (uchar*) t_idx, sizeof( int ), tk,
957 &threshold, &left, &right,
958 &sumw, &sumwy, &sumwyy ) )
971 /* have sorted indices */
975 for( ti = t_compidx; ti < MIN( sortedn, t_compidx + t_n ); ti++ )
977 if( findStumpThreshold_16s[stumperror](
978 t_data + ti * t_cstep, t_sstep,
979 wdata, wstep, ydata, ystep,
980 sorteddata + ti * sortedcstep, sortedsstep, sortedm,
982 &threshold, &left, &right,
983 &sumw, &sumwy, &sumwyy ) )
990 for( ti = t_compidx; ti < MIN( sortedn, t_compidx + t_n ); ti++ )
992 if( findStumpThreshold_32s[stumperror](
993 t_data + ti * t_cstep, t_sstep,
994 wdata, wstep, ydata, ystep,
995 sorteddata + ti * sortedcstep, sortedsstep, sortedm,
997 &threshold, &left, &right,
998 &sumw, &sumwy, &sumwyy ) )
1005 for( ti = t_compidx; ti < MIN( sortedn, t_compidx + t_n ); ti++ )
1007 if( findStumpThreshold_32f[stumperror](
1008 t_data + ti * t_cstep, t_sstep,
1009 wdata, wstep, ydata, ystep,
1010 sorteddata + ti * sortedcstep, sortedsstep, sortedm,
1012 &threshold, &left, &right,
1013 &sumw, &sumwy, &sumwyy ) )
1026 ti = MAX( t_compidx, MIN( sortedn, t_compidx + t_n ) );
1027 for( ; ti < t_compidx + t_n; ti++ )
1029 va.data = t_data + ti * t_cstep;
1031 icvSortIndexedValArray_32s( t_idx, l, &va );
1032 if( findStumpThreshold_32s[stumperror](
1033 t_data + ti * t_cstep, t_sstep,
1034 wdata, wstep, ydata, ystep,
1035 (uchar*)t_idx, sizeof( int ), l,
1037 &threshold, &left, &right,
1038 &sumw, &sumwy, &sumwyy ) )
1044 #pragma omp critical(c_compidx)
1045 #endif /* _OPENMP */
1047 t_compidx = compidx;
1050 } /* while have training data */
1052 /* get the best classifier */
1054 #pragma omp critical(c_beststump)
1055 #endif /* _OPENMP */
1057 if( lerror + rerror < stump->lerror + stump->rerror )
1059 stump->lerror = lerror;
1060 stump->rerror = rerror;
1061 stump->compidx = optcompidx;
1062 stump->threshold = threshold;
1064 stump->right = right;
1068 /* free allocated memory */
1069 if( mat.data.ptr != NULL )
1071 cvFree( &(mat.data.ptr) );
1077 } /* end of parallel region */
1081 /* free allocated memory */
1082 if( filter != NULL )
1087 if( ((CvMTStumpTrainParams*) trainParams)->type == CV_CLASSIFICATION_CLASS )
1089 stump->left = 2.0F * (stump->left >= 0.5F) - 1.0F;
1090 stump->right = 2.0F * (stump->right >= 0.5F) - 1.0F;
1093 return (CvClassifier*) stump;
1097 float cvEvalCARTClassifier( CvClassifier* classifier, CvMat* sample )
1099 CV_FUNCNAME( "cvEvalCARTClassifier" );
1106 CV_ASSERT( classifier != NULL );
1107 CV_ASSERT( sample != NULL );
1108 CV_ASSERT( CV_MAT_TYPE( sample->type ) == CV_32FC1 );
1109 CV_ASSERT( sample->rows == 1 || sample->cols == 1 );
1111 if( sample->rows == 1 )
1115 if( (CV_MAT_ELEM( (*sample), float, 0,
1116 ((CvCARTClassifier*) classifier)->compidx[idx] )) <
1117 ((CvCARTClassifier*) classifier)->threshold[idx] )
1119 idx = ((CvCARTClassifier*) classifier)->left[idx];
1123 idx = ((CvCARTClassifier*) classifier)->right[idx];
1131 if( (CV_MAT_ELEM( (*sample), float,
1132 ((CvCARTClassifier*) classifier)->compidx[idx], 0 )) <
1133 ((CvCARTClassifier*) classifier)->threshold[idx] )
1135 idx = ((CvCARTClassifier*) classifier)->left[idx];
1139 idx = ((CvCARTClassifier*) classifier)->right[idx];
1146 return ((CvCARTClassifier*) classifier)->val[-idx];
1150 float cvEvalCARTClassifierIdx( CvClassifier* classifier, CvMat* sample )
1152 CV_FUNCNAME( "cvEvalCARTClassifierIdx" );
1159 CV_ASSERT( classifier != NULL );
1160 CV_ASSERT( sample != NULL );
1161 CV_ASSERT( CV_MAT_TYPE( sample->type ) == CV_32FC1 );
1162 CV_ASSERT( sample->rows == 1 || sample->cols == 1 );
1164 if( sample->rows == 1 )
1168 if( (CV_MAT_ELEM( (*sample), float, 0,
1169 ((CvCARTClassifier*) classifier)->compidx[idx] )) <
1170 ((CvCARTClassifier*) classifier)->threshold[idx] )
1172 idx = ((CvCARTClassifier*) classifier)->left[idx];
1176 idx = ((CvCARTClassifier*) classifier)->right[idx];
1184 if( (CV_MAT_ELEM( (*sample), float,
1185 ((CvCARTClassifier*) classifier)->compidx[idx], 0 )) <
1186 ((CvCARTClassifier*) classifier)->threshold[idx] )
1188 idx = ((CvCARTClassifier*) classifier)->left[idx];
1192 idx = ((CvCARTClassifier*) classifier)->right[idx];
1199 return (float) (-idx);
1203 void cvReleaseCARTClassifier( CvClassifier** classifier )
1205 cvFree( classifier );
1209 void CV_CDECL icvDefaultSplitIdx_R( int compidx, float threshold,
1210 CvMat* idx, CvMat** left, CvMat** right,
1213 CvMat* trainData = (CvMat*) userdata;
1216 *left = cvCreateMat( 1, trainData->rows, CV_32FC1 );
1217 *right = cvCreateMat( 1, trainData->rows, CV_32FC1 );
1218 (*left)->cols = (*right)->cols = 0;
1221 for( i = 0; i < trainData->rows; i++ )
1223 if( CV_MAT_ELEM( *trainData, float, i, compidx ) < threshold )
1225 (*left)->data.fl[(*left)->cols++] = (float) i;
1229 (*right)->data.fl[(*right)->cols++] = (float) i;
1240 idxdata = idx->data.ptr;
1241 idxnum = (idx->rows == 1) ? idx->cols : idx->rows;
1242 idxstep = (idx->rows == 1) ? CV_ELEM_SIZE( idx->type ) : idx->step;
1243 for( i = 0; i < idxnum; i++ )
1245 index = (int) *((float*) (idxdata + i * idxstep));
1246 if( CV_MAT_ELEM( *trainData, float, index, compidx ) < threshold )
1248 (*left)->data.fl[(*left)->cols++] = (float) index;
1252 (*right)->data.fl[(*right)->cols++] = (float) index;
1258 void CV_CDECL icvDefaultSplitIdx_C( int compidx, float threshold,
1259 CvMat* idx, CvMat** left, CvMat** right,
1262 CvMat* trainData = (CvMat*) userdata;
1265 *left = cvCreateMat( 1, trainData->cols, CV_32FC1 );
1266 *right = cvCreateMat( 1, trainData->cols, CV_32FC1 );
1267 (*left)->cols = (*right)->cols = 0;
1270 for( i = 0; i < trainData->cols; i++ )
1272 if( CV_MAT_ELEM( *trainData, float, compidx, i ) < threshold )
1274 (*left)->data.fl[(*left)->cols++] = (float) i;
1278 (*right)->data.fl[(*right)->cols++] = (float) i;
1289 idxdata = idx->data.ptr;
1290 idxnum = (idx->rows == 1) ? idx->cols : idx->rows;
1291 idxstep = (idx->rows == 1) ? CV_ELEM_SIZE( idx->type ) : idx->step;
1292 for( i = 0; i < idxnum; i++ )
1294 index = (int) *((float*) (idxdata + i * idxstep));
1295 if( CV_MAT_ELEM( *trainData, float, compidx, index ) < threshold )
1297 (*left)->data.fl[(*left)->cols++] = (float) index;
1301 (*right)->data.fl[(*right)->cols++] = (float) index;
1307 /* internal structure used in CART creation */
1308 typedef struct CvCARTNode
1311 CvStumpClassifier* stump;
1318 CvClassifier* cvCreateCARTClassifier( CvMat* trainData,
1320 CvMat* trainClasses,
1322 CvMat* missedMeasurementsMask,
1326 CvClassifierTrainParams* trainParams )
1328 CvCARTClassifier* cart = NULL;
1329 size_t datasize = 0;
1334 CvCARTNode* intnode = NULL;
1335 CvCARTNode* list = NULL;
1340 float maxerrdrop = 0.0F;
1343 void (*splitIdxCallback)( int compidx, float threshold,
1344 CvMat* idx, CvMat** left, CvMat** right,
1348 count = ((CvCARTTrainParams*) trainParams)->count;
1350 assert( count > 0 );
1352 datasize = sizeof( *cart ) + (sizeof( float ) + 3 * sizeof( int )) * count +
1353 sizeof( float ) * (count + 1);
1355 cart = (CvCARTClassifier*) cvAlloc( datasize );
1356 memset( cart, 0, datasize );
1358 cart->count = count;
1360 cart->eval = cvEvalCARTClassifier;
1362 cart->release = cvReleaseCARTClassifier;
1364 cart->compidx = (int*) (cart + 1);
1365 cart->threshold = (float*) (cart->compidx + count);
1366 cart->left = (int*) (cart->threshold + count);
1367 cart->right = (int*) (cart->left + count);
1368 cart->val = (float*) (cart->right + count);
1370 datasize = sizeof( CvCARTNode ) * (count + count);
1371 intnode = (CvCARTNode*) cvAlloc( datasize );
1372 memset( intnode, 0, datasize );
1373 list = (CvCARTNode*) (intnode + count);
1375 splitIdxCallback = ((CvCARTTrainParams*) trainParams)->splitIdx;
1376 userdata = ((CvCARTTrainParams*) trainParams)->userdata;
1377 if( splitIdxCallback == NULL )
1379 splitIdxCallback = ( CV_IS_ROW_SAMPLE( flags ) )
1380 ? icvDefaultSplitIdx_R : icvDefaultSplitIdx_C;
1381 userdata = trainData;
1384 /* create root of the tree */
1385 intnode[0].sampleIdx = sampleIdx;
1386 intnode[0].stump = (CvStumpClassifier*)
1387 ((CvCARTTrainParams*) trainParams)->stumpConstructor( trainData, flags,
1388 trainClasses, typeMask, missedMeasurementsMask, compIdx, sampleIdx, weights,
1389 ((CvCARTTrainParams*) trainParams)->stumpTrainParams );
1390 cart->left[0] = cart->right[0] = 0;
1394 for( i = 1; i < count; i++ )
1396 /* split last added node */
1397 splitIdxCallback( intnode[i-1].stump->compidx, intnode[i-1].stump->threshold,
1398 intnode[i-1].sampleIdx, &lidx, &ridx, userdata );
1400 if( intnode[i-1].stump->lerror != 0.0F )
1402 list[listcount].sampleIdx = lidx;
1403 list[listcount].stump = (CvStumpClassifier*)
1404 ((CvCARTTrainParams*) trainParams)->stumpConstructor( trainData, flags,
1405 trainClasses, typeMask, missedMeasurementsMask, compIdx,
1406 list[listcount].sampleIdx,
1407 weights, ((CvCARTTrainParams*) trainParams)->stumpTrainParams );
1408 list[listcount].errdrop = intnode[i-1].stump->lerror
1409 - (list[listcount].stump->lerror + list[listcount].stump->rerror);
1410 list[listcount].leftflag = 1;
1411 list[listcount].parent = i-1;
1416 cvReleaseMat( &lidx );
1418 if( intnode[i-1].stump->rerror != 0.0F )
1420 list[listcount].sampleIdx = ridx;
1421 list[listcount].stump = (CvStumpClassifier*)
1422 ((CvCARTTrainParams*) trainParams)->stumpConstructor( trainData, flags,
1423 trainClasses, typeMask, missedMeasurementsMask, compIdx,
1424 list[listcount].sampleIdx,
1425 weights, ((CvCARTTrainParams*) trainParams)->stumpTrainParams );
1426 list[listcount].errdrop = intnode[i-1].stump->rerror
1427 - (list[listcount].stump->lerror + list[listcount].stump->rerror);
1428 list[listcount].leftflag = 0;
1429 list[listcount].parent = i-1;
1434 cvReleaseMat( &ridx );
1437 if( listcount == 0 ) break;
1439 /* find the best node to be added to the tree */
1441 maxerrdrop = list[idx].errdrop;
1442 for( j = 1; j < listcount; j++ )
1444 if( list[j].errdrop > maxerrdrop )
1447 maxerrdrop = list[j].errdrop;
1450 intnode[i] = list[idx];
1451 if( list[idx].leftflag )
1453 cart->left[list[idx].parent] = i;
1457 cart->right[list[idx].parent] = i;
1459 if( idx != (listcount - 1) )
1461 list[idx] = list[listcount - 1];
1466 /* fill <cart> fields */
1469 for( i = 0; i < count && (intnode[i].stump != NULL); i++ )
1472 cart->compidx[i] = intnode[i].stump->compidx;
1473 cart->threshold[i] = intnode[i].stump->threshold;
1476 if( cart->left[i] <= 0 )
1479 cart->val[j] = intnode[i].stump->left;
1482 if( cart->right[i] <= 0 )
1484 cart->right[i] = -j;
1485 cart->val[j] = intnode[i].stump->right;
1491 for( i = 0; i < count && (intnode[i].stump != NULL); i++ )
1493 intnode[i].stump->release( (CvClassifier**) &(intnode[i].stump) );
1496 cvReleaseMat( &(intnode[i].sampleIdx) );
1499 for( i = 0; i < listcount; i++ )
1501 list[i].stump->release( (CvClassifier**) &(list[i].stump) );
1502 cvReleaseMat( &(list[i].sampleIdx) );
1507 return (CvClassifier*) cart;
1510 /****************************************************************************************\
1512 \****************************************************************************************/
1514 typedef struct CvBoostTrainer
1517 int count; /* (idx) ? number_of_indices : number_of_samples */
1523 * cvBoostStartTraining, cvBoostNextWeakClassifier, cvBoostEndTraining
1525 * These functions perform training of 2-class boosting classifier
1526 * using ANY appropriate weak classifier
1530 CvBoostTrainer* icvBoostStartTraining( CvMat* trainClasses,
1531 CvMat* weakTrainVals,
1546 CvBoostTrainer* ptr;
1552 assert( trainClasses != NULL );
1553 assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
1554 assert( weakTrainVals != NULL );
1555 assert( CV_MAT_TYPE( weakTrainVals->type ) == CV_32FC1 );
1557 CV_MAT2VEC( *trainClasses, ydata, ystep, m );
1558 CV_MAT2VEC( *weakTrainVals, traindata, trainstep, trainnum );
1560 assert( m == trainnum );
1567 CV_MAT2VEC( *sampleIdx, idxdata, idxstep, idxnum );
1570 datasize = sizeof( *ptr ) + sizeof( *ptr->idx ) * idxnum;
1571 ptr = (CvBoostTrainer*) cvAlloc( datasize );
1572 memset( ptr, 0, datasize );
1583 ptr->idx = (int*) (ptr + 1);
1584 ptr->count = idxnum;
1585 for( i = 0; i < ptr->count; i++ )
1587 cvRawDataToScalar( idxdata + i*idxstep, CV_MAT_TYPE( sampleIdx->type ), &s );
1588 ptr->idx[i] = (int) s.val[0];
1591 for( i = 0; i < ptr->count; i++ )
1593 idx = (ptr->idx) ? ptr->idx[i] : i;
1595 *((float*) (traindata + idx * trainstep)) =
1596 2.0F * (*((float*) (ydata + idx * ystep))) - 1.0F;
1604 * Discrete AdaBoost functions
1608 float icvBoostNextWeakClassifierDAB( CvMat* weakEvalVals,
1609 CvMat* trainClasses,
1610 CvMat* /*weakTrainVals*/,
1612 CvBoostTrainer* trainer )
1629 CV_Assert( weakEvalVals != NULL );
1630 CV_Assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 );
1631 CV_Assert( trainClasses != NULL );
1632 CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
1633 CV_Assert( weights != NULL );
1634 CV_Assert( CV_MAT_TYPE( weights ->type ) == CV_32FC1 );
1636 CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m );
1637 CV_MAT2VEC( *trainClasses, ydata, ystep, ynum );
1638 CV_MAT2VEC( *weights, wdata, wstep, wnum );
1640 assert( m == ynum );
1641 assert( m == wnum );
1645 for( i = 0; i < trainer->count; i++ )
1647 idx = (trainer->idx) ? trainer->idx[i] : i;
1649 sumw += *((float*) (wdata + idx*wstep));
1650 err += (*((float*) (wdata + idx*wstep))) *
1651 ( (*((float*) (evaldata + idx*evalstep))) !=
1652 2.0F * (*((float*) (ydata + idx*ystep))) - 1.0F );
1655 err = -cvLogRatio( err );
1657 for( i = 0; i < trainer->count; i++ )
1659 idx = (trainer->idx) ? trainer->idx[i] : i;
1661 *((float*) (wdata + idx*wstep)) *= expf( err *
1662 ((*((float*) (evaldata + idx*evalstep))) !=
1663 2.0F * (*((float*) (ydata + idx*ystep))) - 1.0F) );
1664 sumw += *((float*) (wdata + idx*wstep));
1666 for( i = 0; i < trainer->count; i++ )
1668 idx = (trainer->idx) ? trainer->idx[i] : i;
1670 *((float*) (wdata + idx * wstep)) /= sumw;
1678 * Real AdaBoost functions
1682 float icvBoostNextWeakClassifierRAB( CvMat* weakEvalVals,
1683 CvMat* trainClasses,
1684 CvMat* /*weakTrainVals*/,
1686 CvBoostTrainer* trainer )
1701 CV_Assert( weakEvalVals != NULL );
1702 CV_Assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 );
1703 CV_Assert( trainClasses != NULL );
1704 CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
1705 CV_Assert( weights != NULL );
1706 CV_Assert( CV_MAT_TYPE( weights ->type ) == CV_32FC1 );
1708 CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m );
1709 CV_MAT2VEC( *trainClasses, ydata, ystep, ynum );
1710 CV_MAT2VEC( *weights, wdata, wstep, wnum );
1712 CV_Assert( m == ynum );
1713 CV_Assert( m == wnum );
1717 for( i = 0; i < trainer->count; i++ )
1719 idx = (trainer->idx) ? trainer->idx[i] : i;
1721 *((float*) (wdata + idx*wstep)) *= expf( (-(*((float*) (ydata + idx*ystep))) + 0.5F)
1722 * cvLogRatio( *((float*) (evaldata + idx*evalstep)) ) );
1723 sumw += *((float*) (wdata + idx*wstep));
1725 for( i = 0; i < trainer->count; i++ )
1727 idx = (trainer->idx) ? trainer->idx[i] : i;
1729 *((float*) (wdata + idx*wstep)) /= sumw;
1737 * LogitBoost functions
1740 #define CV_LB_PROB_THRESH 0.01F
1741 #define CV_LB_WEIGHT_THRESHOLD 0.0001F
1744 void icvResponsesAndWeightsLB( int num, uchar* wdata, int wstep,
1745 uchar* ydata, int ystep,
1746 uchar* fdata, int fstep,
1747 uchar* traindata, int trainstep,
1753 for( i = 0; i < num; i++ )
1755 idx = (indices) ? indices[i] : i;
1757 p = 1.0F / (1.0F + expf( -(*((float*) (fdata + idx*fstep)))) );
1758 *((float*) (wdata + idx*wstep)) = MAX( p * (1.0F - p), CV_LB_WEIGHT_THRESHOLD );
1759 if( *((float*) (ydata + idx*ystep)) == 1.0F )
1761 *((float*) (traindata + idx*trainstep)) =
1762 1.0F / (MAX( p, CV_LB_PROB_THRESH ));
1766 *((float*) (traindata + idx*trainstep)) =
1767 -1.0F / (MAX( 1.0F - p, CV_LB_PROB_THRESH ));
1773 CvBoostTrainer* icvBoostStartTrainingLB( CvMat* trainClasses,
1774 CvMat* weakTrainVals,
1780 CvBoostTrainer* ptr;
1797 assert( trainClasses != NULL );
1798 assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
1799 assert( weakTrainVals != NULL );
1800 assert( CV_MAT_TYPE( weakTrainVals->type ) == CV_32FC1 );
1801 assert( weights != NULL );
1802 assert( CV_MAT_TYPE( weights->type ) == CV_32FC1 );
1804 CV_MAT2VEC( *trainClasses, ydata, ystep, m );
1805 CV_MAT2VEC( *weakTrainVals, traindata, trainstep, trainnum );
1806 CV_MAT2VEC( *weights, wdata, wstep, wnum );
1808 assert( m == trainnum );
1809 assert( m == wnum );
1817 CV_MAT2VEC( *sampleIdx, idxdata, idxstep, idxnum );
1820 datasize = sizeof( *ptr ) + sizeof( *ptr->F ) * m + sizeof( *ptr->idx ) * idxnum;
1821 ptr = (CvBoostTrainer*) cvAlloc( datasize );
1822 memset( ptr, 0, datasize );
1823 ptr->F = (float*) (ptr + 1);
1833 ptr->idx = (int*) (ptr->F + m);
1834 ptr->count = idxnum;
1835 for( i = 0; i < ptr->count; i++ )
1837 cvRawDataToScalar( idxdata + i*idxstep, CV_MAT_TYPE( sampleIdx->type ), &s );
1838 ptr->idx[i] = (int) s.val[0];
1842 for( i = 0; i < m; i++ )
1847 icvResponsesAndWeightsLB( ptr->count, wdata, wstep, ydata, ystep,
1848 (uchar*) ptr->F, sizeof( *ptr->F ),
1849 traindata, trainstep, ptr->idx );
1855 float icvBoostNextWeakClassifierLB( CvMat* weakEvalVals,
1856 CvMat* trainClasses,
1857 CvMat* weakTrainVals,
1859 CvBoostTrainer* trainer )
1875 assert( weakEvalVals != NULL );
1876 assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 );
1877 assert( trainClasses != NULL );
1878 assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
1879 assert( weakTrainVals != NULL );
1880 assert( CV_MAT_TYPE( weakTrainVals->type ) == CV_32FC1 );
1881 assert( weights != NULL );
1882 assert( CV_MAT_TYPE( weights ->type ) == CV_32FC1 );
1884 CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m );
1885 CV_MAT2VEC( *trainClasses, ydata, ystep, ynum );
1886 CV_MAT2VEC( *weakTrainVals, traindata, trainstep, trainnum );
1887 CV_MAT2VEC( *weights, wdata, wstep, wnum );
1889 assert( m == ynum );
1890 assert( m == wnum );
1891 assert( m == trainnum );
1892 //assert( m == trainer->count );
1894 for( i = 0; i < trainer->count; i++ )
1896 idx = (trainer->idx) ? trainer->idx[i] : i;
1898 trainer->F[idx] += *((float*) (evaldata + idx * evalstep));
1901 icvResponsesAndWeightsLB( trainer->count, wdata, wstep, ydata, ystep,
1902 (uchar*) trainer->F, sizeof( *trainer->F ),
1903 traindata, trainstep, trainer->idx );
1914 float icvBoostNextWeakClassifierGAB( CvMat* weakEvalVals,
1915 CvMat* trainClasses,
1916 CvMat* /*weakTrainVals*/,
1918 CvBoostTrainer* trainer )
1933 CV_Assert( weakEvalVals != NULL );
1934 CV_Assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 );
1935 CV_Assert( trainClasses != NULL );
1936 CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 );
1937 CV_Assert( weights != NULL );
1938 CV_Assert( CV_MAT_TYPE( weights->type ) == CV_32FC1 );
1940 CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m );
1941 CV_MAT2VEC( *trainClasses, ydata, ystep, ynum );
1942 CV_MAT2VEC( *weights, wdata, wstep, wnum );
1944 assert( m == ynum );
1945 assert( m == wnum );
1948 for( i = 0; i < trainer->count; i++ )
1950 idx = (trainer->idx) ? trainer->idx[i] : i;
1952 *((float*) (wdata + idx*wstep)) *=
1953 expf( -(*((float*) (evaldata + idx*evalstep)))
1954 * ( 2.0F * (*((float*) (ydata + idx*ystep))) - 1.0F ) );
1955 sumw += *((float*) (wdata + idx*wstep));
1958 for( i = 0; i < trainer->count; i++ )
1960 idx = (trainer->idx) ? trainer->idx[i] : i;
1962 *((float*) (wdata + idx*wstep)) /= sumw;
1968 typedef CvBoostTrainer* (*CvBoostStartTraining)( CvMat* trainClasses,
1969 CvMat* weakTrainVals,
1974 typedef float (*CvBoostNextWeakClassifier)( CvMat* weakEvalVals,
1975 CvMat* trainClasses,
1976 CvMat* weakTrainVals,
1978 CvBoostTrainer* data );
1980 CvBoostStartTraining startTraining[4] = {
1981 icvBoostStartTraining,
1982 icvBoostStartTraining,
1983 icvBoostStartTrainingLB,
1984 icvBoostStartTraining
1987 CvBoostNextWeakClassifier nextWeakClassifier[4] = {
1988 icvBoostNextWeakClassifierDAB,
1989 icvBoostNextWeakClassifierRAB,
1990 icvBoostNextWeakClassifierLB,
1991 icvBoostNextWeakClassifierGAB
2000 CvBoostTrainer* cvBoostStartTraining( CvMat* trainClasses,
2001 CvMat* weakTrainVals,
2006 return startTraining[type]( trainClasses, weakTrainVals, weights, sampleIdx, type );
2010 void cvBoostEndTraining( CvBoostTrainer** trainer )
2017 float cvBoostNextWeakClassifier( CvMat* weakEvalVals,
2018 CvMat* trainClasses,
2019 CvMat* weakTrainVals,
2021 CvBoostTrainer* trainer )
2023 return nextWeakClassifier[trainer->type]( weakEvalVals, trainClasses,
2024 weakTrainVals, weights, trainer );
2027 /****************************************************************************************\
2028 * Boosted tree models *
2029 \****************************************************************************************/
2031 typedef struct CvBtTrainer
2037 CvMat* trainClasses;
2050 CvMTStumpTrainParams stumpParams;
2051 CvCARTTrainParams cartParams;
2053 float* f; /* F_(m-1) */
2054 CvMat* y; /* yhat */
2056 CvBoostTrainer* boosttrainer;
2060 * cvBtStart, cvBtNext, cvBtEnd
2062 * These functions perform iterative training of
2063 * 2-class (CV_DABCLASS - CV_GABCLASS, CV_L2CLASS), K-class (CV_LKCLASS) classifier
2064 * or fit regression model (CV_LSREG, CV_LADREG, CV_MREG)
2065 * using decision tree as a weak classifier.
2068 typedef void (*CvZeroApproxFunc)( float* approx, CvBtTrainer* trainer );
2070 /* Mean zero approximation */
2071 void icvZeroApproxMean( float* approx, CvBtTrainer* trainer )
2077 for( i = 0; i < trainer->numsamples; i++ )
2079 idx = icvGetIdxAt( trainer->sampleIdx, i );
2080 approx[0] += *((float*) (trainer->ydata + idx * trainer->ystep));
2082 approx[0] /= (float) trainer->numsamples;
2086 * Median zero approximation
2088 void icvZeroApproxMed( float* approx, CvBtTrainer* trainer )
2093 for( i = 0; i < trainer->numsamples; i++ )
2095 idx = icvGetIdxAt( trainer->sampleIdx, i );
2096 trainer->f[i] = *((float*) (trainer->ydata + idx * trainer->ystep));
2099 icvSort_32f( trainer->f, trainer->numsamples, 0 );
2100 approx[0] = trainer->f[trainer->numsamples / 2];
2104 * 0.5 * log( mean(y) / (1 - mean(y)) ) where y in {0, 1}
2106 void icvZeroApproxLog( float* approx, CvBtTrainer* trainer )
2110 icvZeroApproxMean( &y_mean, trainer );
2111 approx[0] = 0.5F * cvLogRatio( y_mean );
2115 * 0 zero approximation
2117 void icvZeroApprox0( float* approx, CvBtTrainer* trainer )
2121 for( i = 0; i < trainer->numclasses; i++ )
2127 static CvZeroApproxFunc icvZeroApproxFunc[] =
2129 icvZeroApprox0, /* CV_DABCLASS */
2130 icvZeroApprox0, /* CV_RABCLASS */
2131 icvZeroApprox0, /* CV_LBCLASS */
2132 icvZeroApprox0, /* CV_GABCLASS */
2133 icvZeroApproxLog, /* CV_L2CLASS */
2134 icvZeroApprox0, /* CV_LKCLASS */
2135 icvZeroApproxMean, /* CV_LSREG */
2136 icvZeroApproxMed, /* CV_LADREG */
2137 icvZeroApproxMed, /* CV_MREG */
2141 void cvBtNext( CvCARTClassifier** trees, CvBtTrainer* trainer );
2144 CvBtTrainer* cvBtStart( CvCARTClassifier** trees,
2147 CvMat* trainClasses,
2154 CvBtTrainer* ptr = 0;
2156 CV_FUNCNAME( "cvBtStart" );
2167 CV_ERROR( CV_StsNullPtr, "Invalid trees parameter" );
2170 if( type < CV_DABCLASS || type > CV_MREG )
2172 CV_ERROR( CV_StsUnsupportedFormat, "Unsupported type parameter" );
2174 if( type == CV_LKCLASS )
2176 CV_ASSERT( numclasses >= 2 );
2183 m = MAX( trainClasses->rows, trainClasses->cols );
2185 data_size = sizeof( *ptr );
2186 if( type > CV_GABCLASS )
2188 data_size += m * numclasses * sizeof( *(ptr->f) );
2190 CV_CALL( ptr = (CvBtTrainer*) cvAlloc( data_size ) );
2191 memset( ptr, 0, data_size );
2192 ptr->f = (float*) (ptr + 1);
2194 ptr->trainData = trainData;
2196 ptr->trainClasses = trainClasses;
2197 CV_MAT2VEC( *trainClasses, ptr->ydata, ptr->ystep, ptr->m );
2199 memset( &(ptr->cartParams), 0, sizeof( ptr->cartParams ) );
2200 memset( &(ptr->stumpParams), 0, sizeof( ptr->stumpParams ) );
2205 ptr->stumpParams.error = CV_MISCLASSIFICATION;
2206 ptr->stumpParams.type = CV_CLASSIFICATION_CLASS;
2209 ptr->stumpParams.error = CV_GINI;
2210 ptr->stumpParams.type = CV_CLASSIFICATION;
2213 ptr->stumpParams.error = CV_SQUARE;
2214 ptr->stumpParams.type = CV_REGRESSION;
2216 ptr->cartParams.count = numsplits;
2217 ptr->cartParams.stumpTrainParams = (CvClassifierTrainParams*) &(ptr->stumpParams);
2218 ptr->cartParams.stumpConstructor = cvCreateMTStumpClassifier;
2220 ptr->param[0] = param[0];
2221 ptr->param[1] = param[1];
2223 ptr->numclasses = numclasses;
2225 CV_CALL( ptr->y = cvCreateMat( 1, m, CV_32FC1 ) );
2226 ptr->sampleIdx = sampleIdx;
2227 ptr->numsamples = ( sampleIdx == NULL ) ? ptr->m
2228 : MAX( sampleIdx->rows, sampleIdx->cols );
2230 ptr->weights = cvCreateMat( 1, m, CV_32FC1 );
2231 cvSet( ptr->weights, cvScalar( 1.0 ) );
2233 if( type <= CV_GABCLASS )
2235 ptr->boosttrainer = cvBoostStartTraining( ptr->trainClasses, ptr->y,
2236 ptr->weights, NULL, type );
2238 CV_CALL( cvBtNext( trees, ptr ) );
2242 data_size = sizeof( *zero_approx ) * numclasses;
2243 CV_CALL( zero_approx = (float*) cvAlloc( data_size ) );
2244 icvZeroApproxFunc[type]( zero_approx, ptr );
2245 for( i = 0; i < m; i++ )
2247 for( j = 0; j < numclasses; j++ )
2249 ptr->f[i * numclasses + j] = zero_approx[j];
2253 CV_CALL( cvBtNext( trees, ptr ) );
2255 for( i = 0; i < numclasses; i++ )
2257 for( j = 0; j <= trees[i]->count; j++ )
2259 trees[i]->val[j] += zero_approx[i];
2262 CV_CALL( cvFree( &zero_approx ) );
2270 void icvBtNext_LSREG( CvCARTClassifier** trees, CvBtTrainer* trainer )
2274 /* yhat_i = y_i - F_(m-1)(x_i) */
2275 for( i = 0; i < trainer->m; i++ )
2277 trainer->y->data.fl[i] =
2278 *((float*) (trainer->ydata + i * trainer->ystep)) - trainer->f[i];
2281 trees[0] = (CvCARTClassifier*) cvCreateCARTClassifier( trainer->trainData,
2283 trainer->y, NULL, NULL, NULL, trainer->sampleIdx, trainer->weights,
2284 (CvClassifierTrainParams*) &trainer->cartParams );
2288 void icvBtNext_LADREG( CvCARTClassifier** trees, CvBtTrainer* trainer )
2290 CvCARTClassifier* ptr;
2303 data_size = trainer->m * sizeof( *idx );
2304 idx = (int*) cvAlloc( data_size );
2305 data_size = trainer->m * sizeof( *resp );
2306 resp = (float*) cvAlloc( data_size );
2308 /* yhat_i = sign(y_i - F_(m-1)(x_i)) */
2309 for( i = 0; i < trainer->numsamples; i++ )
2311 index = icvGetIdxAt( trainer->sampleIdx, i );
2312 trainer->y->data.fl[index] = (float)
2313 CV_SIGN( *((float*) (trainer->ydata + index * trainer->ystep))
2314 - trainer->f[index] );
2317 ptr = (CvCARTClassifier*) cvCreateCARTClassifier( trainer->trainData, trainer->flags,
2318 trainer->y, NULL, NULL, NULL, trainer->sampleIdx, trainer->weights,
2319 (CvClassifierTrainParams*) &trainer->cartParams );
2321 CV_GET_SAMPLE( *trainer->trainData, trainer->flags, 0, sample );
2322 CV_GET_SAMPLE_STEP( *trainer->trainData, trainer->flags, sample_step );
2323 sample_data = sample.data.ptr;
2324 for( i = 0; i < trainer->numsamples; i++ )
2326 index = icvGetIdxAt( trainer->sampleIdx, i );
2327 sample.data.ptr = sample_data + index * sample_step;
2328 idx[index] = (int) cvEvalCARTClassifierIdx( (CvClassifier*) ptr, &sample );
2330 for( j = 0; j <= ptr->count; j++ )
2333 for( i = 0; i < trainer->numsamples; i++ )
2335 index = icvGetIdxAt( trainer->sampleIdx, i );
2336 if( idx[index] == j )
2338 resp[respnum++] = *((float*) (trainer->ydata + index * trainer->ystep))
2339 - trainer->f[index];
2344 icvSort_32f( resp, respnum, 0 );
2345 val = resp[respnum / 2];
2361 void icvBtNext_MREG( CvCARTClassifier** trees, CvBtTrainer* trainer )
2363 CvCARTClassifier* ptr;
2379 data_size = trainer->m * sizeof( *idx );
2380 idx = (int*) cvAlloc( data_size );
2381 data_size = trainer->m * sizeof( *resp );
2382 resp = (float*) cvAlloc( data_size );
2383 data_size = trainer->m * sizeof( *resid );
2384 resid = (float*) cvAlloc( data_size );
2386 /* resid_i = (y_i - F_(m-1)(x_i)) */
2387 for( i = 0; i < trainer->numsamples; i++ )
2389 index = icvGetIdxAt( trainer->sampleIdx, i );
2390 resid[index] = *((float*) (trainer->ydata + index * trainer->ystep))
2391 - trainer->f[index];
2393 resp[i] = (float) fabs( resid[index] );
2396 /* delta = quantile_alpha{abs(resid_i)} */
2397 icvSort_32f( resp, trainer->numsamples, 0 );
2398 delta = resp[(int)(trainer->param[1] * (trainer->numsamples - 1))];
2401 for( i = 0; i < trainer->numsamples; i++ )
2403 index = icvGetIdxAt( trainer->sampleIdx, i );
2404 trainer->y->data.fl[index] = MIN( delta, ((float) fabs( resid[index] )) ) *
2405 CV_SIGN( resid[index] );
2408 ptr = (CvCARTClassifier*) cvCreateCARTClassifier( trainer->trainData, trainer->flags,
2409 trainer->y, NULL, NULL, NULL, trainer->sampleIdx, trainer->weights,
2410 (CvClassifierTrainParams*) &trainer->cartParams );
2412 CV_GET_SAMPLE( *trainer->trainData, trainer->flags, 0, sample );
2413 CV_GET_SAMPLE_STEP( *trainer->trainData, trainer->flags, sample_step );
2414 sample_data = sample.data.ptr;
2415 for( i = 0; i < trainer->numsamples; i++ )
2417 index = icvGetIdxAt( trainer->sampleIdx, i );
2418 sample.data.ptr = sample_data + index * sample_step;
2419 idx[index] = (int) cvEvalCARTClassifierIdx( (CvClassifier*) ptr, &sample );
2421 for( j = 0; j <= ptr->count; j++ )
2425 for( i = 0; i < trainer->numsamples; i++ )
2427 index = icvGetIdxAt( trainer->sampleIdx, i );
2428 if( idx[index] == j )
2430 resp[respnum++] = *((float*) (trainer->ydata + index * trainer->ystep))
2431 - trainer->f[index];
2436 /* rhat = median(y_i - F_(m-1)(x_i)) */
2437 icvSort_32f( resp, respnum, 0 );
2438 rhat = resp[respnum / 2];
2440 /* val = sum{sign(r_i - rhat_i) * min(delta, abs(r_i - rhat_i)}
2441 * r_i = y_i - F_(m-1)(x_i)
2444 for( i = 0; i < respnum; i++ )
2446 val += CV_SIGN( resp[i] - rhat )
2447 * MIN( delta, (float) fabs( resp[i] - rhat ) );
2450 val = rhat + val / (float) respnum;
2468 //#define CV_VAL_MAX 1e304
2470 //#define CV_LOG_VAL_MAX 700.0
2472 #define CV_VAL_MAX 1e+8
2474 #define CV_LOG_VAL_MAX 18.0
2476 void icvBtNext_L2CLASS( CvCARTClassifier** trees, CvBtTrainer* trainer )
2478 CvCARTClassifier* ptr;
2492 float* sorted_weights;
2498 data_size = trainer->m * sizeof( *idx );
2499 idx = (int*) cvAlloc( data_size );
2501 data_size = trainer->m * sizeof( *weights );
2502 weights = (float*) cvAlloc( data_size );
2503 data_size = trainer->m * sizeof( *sorted_weights );
2504 sorted_weights = (float*) cvAlloc( data_size );
2506 /* yhat_i = (4 * y_i - 2) / ( 1 + exp( (4 * y_i - 2) * F_(m-1)(x_i) ) ).
2510 for( i = 0; i < trainer->numsamples; i++ )
2512 index = icvGetIdxAt( trainer->sampleIdx, i );
2513 val = 4.0F * (*((float*) (trainer->ydata + index * trainer->ystep))) - 2.0F;
2514 val_f = val * trainer->f[index];
2515 val_f = ( val_f < CV_LOG_VAL_MAX ) ? exp( val_f ) : CV_LOG_VAL_MAX;
2516 val = (float) ( (double) val / ( 1.0 + val_f ) );
2517 trainer->y->data.fl[index] = val;
2518 val = (float) fabs( val );
2519 weights[index] = val * (2.0F - val);
2520 sorted_weights[i] = weights[index];
2521 sum_weights += sorted_weights[i];
2525 sample_idx = trainer->sampleIdx;
2526 trimmed_num = trainer->numsamples;
2527 if( trainer->param[1] < 1.0F )
2529 /* perform weight trimming */
2534 icvSort_32f( sorted_weights, trainer->numsamples, 0 );
2536 sum_weights *= (1.0F - trainer->param[1]);
2539 do { sum_weights -= sorted_weights[++i]; }
2540 while( sum_weights > 0.0F && i < (trainer->numsamples - 1) );
2542 threshold = sorted_weights[i];
2544 while( i > 0 && sorted_weights[i-1] == threshold ) i--;
2548 trimmed_num = trainer->numsamples - i;
2549 trimmed_idx = cvCreateMat( 1, trimmed_num, CV_32FC1 );
2551 for( i = 0; i < trainer->numsamples; i++ )
2553 index = icvGetIdxAt( trainer->sampleIdx, i );
2554 if( weights[index] >= threshold )
2556 CV_MAT_ELEM( *trimmed_idx, float, 0, count ) = (float) index;
2561 assert( count == trimmed_num );
2563 sample_idx = trimmed_idx;
2565 printf( "Used samples %%: %g\n",
2566 (float) trimmed_num / (float) trainer->numsamples * 100.0F );
2570 ptr = (CvCARTClassifier*) cvCreateCARTClassifier( trainer->trainData, trainer->flags,
2571 trainer->y, NULL, NULL, NULL, sample_idx, trainer->weights,
2572 (CvClassifierTrainParams*) &trainer->cartParams );
2574 CV_GET_SAMPLE( *trainer->trainData, trainer->flags, 0, sample );
2575 CV_GET_SAMPLE_STEP( *trainer->trainData, trainer->flags, sample_step );
2576 sample_data = sample.data.ptr;
2577 for( i = 0; i < trimmed_num; i++ )
2579 index = icvGetIdxAt( sample_idx, i );
2580 sample.data.ptr = sample_data + index * sample_step;
2581 idx[index] = (int) cvEvalCARTClassifierIdx( (CvClassifier*) ptr, &sample );
2583 for( j = 0; j <= ptr->count; j++ )
2588 for( i = 0; i < trimmed_num; i++ )
2590 index = icvGetIdxAt( sample_idx, i );
2591 if( idx[index] == j )
2593 val += trainer->y->data.fl[index];
2594 sum_weights += weights[index];
2598 if( sum_weights > 0.0F )
2609 if( trimmed_idx != NULL ) cvReleaseMat( &trimmed_idx );
2610 cvFree( &sorted_weights );
2617 void icvBtNext_LKCLASS( CvCARTClassifier** trees, CvBtTrainer* trainer )
2619 int i, j, k, kk, num;
2631 float* sorted_weights;
2640 data_size = trainer->m * sizeof( *idx );
2641 idx = (int*) cvAlloc( data_size );
2642 data_size = trainer->m * sizeof( *weights );
2643 weights = (float*) cvAlloc( data_size );
2644 data_size = trainer->m * sizeof( *sorted_weights );
2645 sorted_weights = (float*) cvAlloc( data_size );
2646 trimmed_idx = cvCreateMat( 1, trainer->numsamples, CV_32FC1 );
2648 for( k = 0; k < trainer->numclasses; k++ )
2650 /* yhat_i = y_i - p_k(x_i), y_i in {0, 1} */
2651 /* p_k(x_i) = exp(f_k(x_i)) / (sum_exp_f(x_i)) */
2653 for( i = 0; i < trainer->numsamples; i++ )
2655 index = icvGetIdxAt( trainer->sampleIdx, i );
2656 /* p_k(x_i) = 1 / (1 + sum(exp(f_kk(x_i) - f_k(x_i)))), kk != k */
2657 num = index * trainer->numclasses;
2658 f_k = (double) trainer->f[num + k];
2660 for( kk = 0; kk < trainer->numclasses; kk++ )
2662 if( kk == k ) continue;
2663 exp_f = (double) trainer->f[num + kk] - f_k;
2664 exp_f = (exp_f < CV_LOG_VAL_MAX) ? exp( exp_f ) : CV_VAL_MAX;
2665 if( exp_f == CV_VAL_MAX || exp_f >= (CV_VAL_MAX - sum_exp_f) )
2667 sum_exp_f = CV_VAL_MAX;
2673 val = (float) ( (*((float*) (trainer->ydata + index * trainer->ystep)))
2675 val -= (float) ( (sum_exp_f == CV_VAL_MAX) ? 0.0 : ( 1.0 / sum_exp_f ) );
2677 assert( val >= -1.0F );
2678 assert( val <= 1.0F );
2680 trainer->y->data.fl[index] = val;
2681 val = (float) fabs( val );
2682 weights[index] = val * (1.0F - val);
2683 sorted_weights[i] = weights[index];
2684 sum_weights += sorted_weights[i];
2687 sample_idx = trainer->sampleIdx;
2688 trimmed_num = trainer->numsamples;
2689 if( trainer->param[1] < 1.0F )
2691 /* perform weight trimming */
2696 icvSort_32f( sorted_weights, trainer->numsamples, 0 );
2698 sum_weights *= (1.0F - trainer->param[1]);
2701 do { sum_weights -= sorted_weights[++i]; }
2702 while( sum_weights > 0.0F && i < (trainer->numsamples - 1) );
2704 threshold = sorted_weights[i];
2706 while( i > 0 && sorted_weights[i-1] == threshold ) i--;
2710 trimmed_num = trainer->numsamples - i;
2711 trimmed_idx->cols = trimmed_num;
2713 for( i = 0; i < trainer->numsamples; i++ )
2715 index = icvGetIdxAt( trainer->sampleIdx, i );
2716 if( weights[index] >= threshold )
2718 CV_MAT_ELEM( *trimmed_idx, float, 0, count ) = (float) index;
2723 assert( count == trimmed_num );
2725 sample_idx = trimmed_idx;
2727 printf( "k: %d Used samples %%: %g\n", k,
2728 (float) trimmed_num / (float) trainer->numsamples * 100.0F );
2730 } /* weight trimming */
2732 trees[k] = (CvCARTClassifier*) cvCreateCARTClassifier( trainer->trainData,
2733 trainer->flags, trainer->y, NULL, NULL, NULL, sample_idx, trainer->weights,
2734 (CvClassifierTrainParams*) &trainer->cartParams );
2736 CV_GET_SAMPLE( *trainer->trainData, trainer->flags, 0, sample );
2737 CV_GET_SAMPLE_STEP( *trainer->trainData, trainer->flags, sample_step );
2738 sample_data = sample.data.ptr;
2739 for( i = 0; i < trimmed_num; i++ )
2741 index = icvGetIdxAt( sample_idx, i );
2742 sample.data.ptr = sample_data + index * sample_step;
2743 idx[index] = (int) cvEvalCARTClassifierIdx( (CvClassifier*) trees[k],
2746 for( j = 0; j <= trees[k]->count; j++ )
2751 for( i = 0; i < trimmed_num; i++ )
2753 index = icvGetIdxAt( sample_idx, i );
2754 if( idx[index] == j )
2756 val += trainer->y->data.fl[index];
2757 sum_weights += weights[index];
2761 if( sum_weights > 0.0F )
2763 val = ((float) (trainer->numclasses - 1)) * val /
2764 ((float) (trainer->numclasses)) / sum_weights;
2770 trees[k]->val[j] = val;
2772 } /* for each class */
2774 cvReleaseMat( &trimmed_idx );
2775 cvFree( &sorted_weights );
2781 void icvBtNext_XXBCLASS( CvCARTClassifier** trees, CvBtTrainer* trainer )
2785 CvMat* weak_eval_vals;
2792 weak_eval_vals = cvCreateMat( 1, trainer->m, CV_32FC1 );
2794 sample_idx = cvTrimWeights( trainer->weights, trainer->sampleIdx,
2795 trainer->param[1] );
2796 num_samples = ( sample_idx == NULL )
2797 ? trainer->m : MAX( sample_idx->rows, sample_idx->cols );
2799 printf( "Used samples %%: %g\n",
2800 (float) num_samples / (float) trainer->numsamples * 100.0F );
2802 trees[0] = (CvCARTClassifier*) cvCreateCARTClassifier( trainer->trainData,
2803 trainer->flags, trainer->y, NULL, NULL, NULL,
2804 sample_idx, trainer->weights,
2805 (CvClassifierTrainParams*) &trainer->cartParams );
2807 /* evaluate samples */
2808 CV_GET_SAMPLE( *trainer->trainData, trainer->flags, 0, sample );
2809 CV_GET_SAMPLE_STEP( *trainer->trainData, trainer->flags, sample_step );
2810 sample_data = sample.data.ptr;
2812 for( i = 0; i < trainer->m; i++ )
2814 sample.data.ptr = sample_data + i * sample_step;
2815 weak_eval_vals->data.fl[i] = trees[0]->eval( (CvClassifier*) trees[0], &sample );
2818 alpha = cvBoostNextWeakClassifier( weak_eval_vals, trainer->trainClasses,
2819 trainer->y, trainer->weights, trainer->boosttrainer );
2821 /* multiply tree by alpha */
2822 for( i = 0; i <= trees[0]->count; i++ )
2824 trees[0]->val[i] *= alpha;
2826 if( trainer->type == CV_RABCLASS )
2828 for( i = 0; i <= trees[0]->count; i++ )
2830 trees[0]->val[i] = cvLogRatio( trees[0]->val[i] );
2834 if( sample_idx != NULL && sample_idx != trainer->sampleIdx )
2836 cvReleaseMat( &sample_idx );
2838 cvReleaseMat( &weak_eval_vals );
2841 typedef void (*CvBtNextFunc)( CvCARTClassifier** trees, CvBtTrainer* trainer );
2843 static CvBtNextFunc icvBtNextFunc[] =
2857 void cvBtNext( CvCARTClassifier** trees, CvBtTrainer* trainer )
2865 icvBtNextFunc[trainer->type]( trees, trainer );
2868 if( trainer->param[0] != 1.0F )
2870 for( j = 0; j < trainer->numclasses; j++ )
2872 for( i = 0; i <= trees[j]->count; i++ )
2874 trees[j]->val[i] *= trainer->param[0];
2879 if( trainer->type > CV_GABCLASS )
2881 /* update F_(m-1) */
2882 CV_GET_SAMPLE( *(trainer->trainData), trainer->flags, 0, sample );
2883 CV_GET_SAMPLE_STEP( *(trainer->trainData), trainer->flags, sample_step );
2884 sample_data = sample.data.ptr;
2885 for( i = 0; i < trainer->numsamples; i++ )
2887 index = icvGetIdxAt( trainer->sampleIdx, i );
2888 sample.data.ptr = sample_data + index * sample_step;
2889 for( j = 0; j < trainer->numclasses; j++ )
2891 trainer->f[index * trainer->numclasses + j] +=
2892 trees[j]->eval( (CvClassifier*) (trees[j]), &sample );
2899 void cvBtEnd( CvBtTrainer** trainer )
2901 CV_FUNCNAME( "cvBtEnd" );
2905 if( trainer == NULL || (*trainer) == NULL )
2907 CV_ERROR( CV_StsNullPtr, "Invalid trainer parameter" );
2910 if( (*trainer)->y != NULL )
2912 CV_CALL( cvReleaseMat( &((*trainer)->y) ) );
2914 if( (*trainer)->weights != NULL )
2916 CV_CALL( cvReleaseMat( &((*trainer)->weights) ) );
2918 if( (*trainer)->boosttrainer != NULL )
2920 CV_CALL( cvBoostEndTraining( &((*trainer)->boosttrainer) ) );
2922 CV_CALL( cvFree( trainer ) );
2927 /****************************************************************************************\
2928 * Boosted tree model as a classifier *
2929 \****************************************************************************************/
2932 float cvEvalBtClassifier( CvClassifier* classifier, CvMat* sample )
2936 CV_FUNCNAME( "cvEvalBtClassifier" );
2943 if( CV_IS_TUNABLE( classifier->flags ) )
2946 CvCARTClassifier* tree;
2948 CV_CALL( cvStartReadSeq( ((CvBtClassifier*) classifier)->seq, &reader ) );
2949 for( i = 0; i < ((CvBtClassifier*) classifier)->numiter; i++ )
2951 CV_READ_SEQ_ELEM( tree, reader );
2952 val += tree->eval( (CvClassifier*) tree, sample );
2957 CvCARTClassifier** ptree;
2959 ptree = ((CvBtClassifier*) classifier)->trees;
2960 for( i = 0; i < ((CvBtClassifier*) classifier)->numiter; i++ )
2962 val += (*ptree)->eval( (CvClassifier*) (*ptree), sample );
2973 float cvEvalBtClassifier2( CvClassifier* classifier, CvMat* sample )
2977 CV_FUNCNAME( "cvEvalBtClassifier2" );
2981 CV_CALL( val = cvEvalBtClassifier( classifier, sample ) );
2985 return (float) (val >= 0.0F);
2989 float cvEvalBtClassifierK( CvClassifier* classifier, CvMat* sample )
2993 CV_FUNCNAME( "cvEvalBtClassifierK" );
3004 numclasses = ((CvBtClassifier*) classifier)->numclasses;
3005 data_size = sizeof( *vals ) * numclasses;
3006 CV_CALL( vals = (float*) cvAlloc( data_size ) );
3007 memset( vals, 0, data_size );
3009 if( CV_IS_TUNABLE( classifier->flags ) )
3012 CvCARTClassifier* tree;
3014 CV_CALL( cvStartReadSeq( ((CvBtClassifier*) classifier)->seq, &reader ) );
3015 for( i = 0; i < ((CvBtClassifier*) classifier)->numiter; i++ )
3017 for( k = 0; k < numclasses; k++ )
3019 CV_READ_SEQ_ELEM( tree, reader );
3020 vals[k] += tree->eval( (CvClassifier*) tree, sample );
3027 CvCARTClassifier** ptree;
3029 ptree = ((CvBtClassifier*) classifier)->trees;
3030 for( i = 0; i < ((CvBtClassifier*) classifier)->numiter; i++ )
3032 for( k = 0; k < numclasses; k++ )
3034 vals[k] += (*ptree)->eval( (CvClassifier*) (*ptree), sample );
3040 max_val = vals[cls];
3041 for( k = 1; k < numclasses; k++ )
3043 if( vals[k] > max_val )
3050 CV_CALL( cvFree( &vals ) );
3057 typedef float (*CvEvalBtClassifier)( CvClassifier* classifier, CvMat* sample );
3059 static CvEvalBtClassifier icvEvalBtClassifier[] =
3061 cvEvalBtClassifier2,
3062 cvEvalBtClassifier2,
3063 cvEvalBtClassifier2,
3064 cvEvalBtClassifier2,
3065 cvEvalBtClassifier2,
3066 cvEvalBtClassifierK,
3073 int cvSaveBtClassifier( CvClassifier* classifier, const char* filename )
3075 CV_FUNCNAME( "cvSaveBtClassifier" );
3082 memset(&reader, 0, sizeof(reader));
3083 CvCARTClassifier* tree;
3085 CV_ASSERT( classifier );
3086 CV_ASSERT( filename );
3088 if( !icvMkDir( filename ) || (file = fopen( filename, "w" )) == 0 )
3090 CV_ERROR( CV_StsError, "Unable to create file" );
3093 if( CV_IS_TUNABLE( classifier->flags ) )
3095 CV_CALL( cvStartReadSeq( ((CvBtClassifier*) classifier)->seq, &reader ) );
3097 fprintf( file, "%d %d\n%d\n%d\n", (int) ((CvBtClassifier*) classifier)->type,
3098 ((CvBtClassifier*) classifier)->numclasses,
3099 ((CvBtClassifier*) classifier)->numfeatures,
3100 ((CvBtClassifier*) classifier)->numiter );
3102 for( i = 0; i < ((CvBtClassifier*) classifier)->numclasses *
3103 ((CvBtClassifier*) classifier)->numiter; i++ )
3105 if( CV_IS_TUNABLE( classifier->flags ) )
3107 CV_READ_SEQ_ELEM( tree, reader );
3111 tree = ((CvBtClassifier*) classifier)->trees[i];
3114 fprintf( file, "%d\n", tree->count );
3115 for( j = 0; j < tree->count; j++ )
3117 fprintf( file, "%d %g %d %d\n", tree->compidx[j],
3122 for( j = 0; j <= tree->count; j++ )
3124 fprintf( file, "%g ", tree->val[j] );
3126 fprintf( file, "\n" );
3138 void cvReleaseBtClassifier( CvClassifier** ptr )
3140 CV_FUNCNAME( "cvReleaseBtClassifier" );
3146 if( ptr == NULL || *ptr == NULL )
3148 CV_ERROR( CV_StsNullPtr, "" );
3150 if( CV_IS_TUNABLE( (*ptr)->flags ) )
3153 CvCARTClassifier* tree;
3155 CV_CALL( cvStartReadSeq( ((CvBtClassifier*) *ptr)->seq, &reader ) );
3156 for( i = 0; i < ((CvBtClassifier*) *ptr)->numclasses *
3157 ((CvBtClassifier*) *ptr)->numiter; i++ )
3159 CV_READ_SEQ_ELEM( tree, reader );
3160 tree->release( (CvClassifier**) (&tree) );
3162 CV_CALL( cvReleaseMemStorage( &(((CvBtClassifier*) *ptr)->seq->storage) ) );
3166 CvCARTClassifier** ptree;
3168 ptree = ((CvBtClassifier*) *ptr)->trees;
3169 for( i = 0; i < ((CvBtClassifier*) *ptr)->numclasses *
3170 ((CvBtClassifier*) *ptr)->numiter; i++ )
3172 (*ptree)->release( (CvClassifier**) ptree );
3177 CV_CALL( cvFree( ptr ) );
3183 void cvTuneBtClassifier( CvClassifier* classifier, CvMat*, int flags,
3184 CvMat*, CvMat* , CvMat*, CvMat*, CvMat* )
3186 CV_FUNCNAME( "cvTuneBtClassifier" );
3192 if( CV_IS_TUNABLE( flags ) )
3194 if( !CV_IS_TUNABLE( classifier->flags ) )
3196 CV_ERROR( CV_StsUnsupportedFormat,
3197 "Classifier does not support tune function" );
3201 /* tune classifier */
3202 CvCARTClassifier** trees;
3204 printf( "Iteration %d\n", ((CvBtClassifier*) classifier)->numiter + 1 );
3206 data_size = sizeof( *trees ) * ((CvBtClassifier*) classifier)->numclasses;
3207 CV_CALL( trees = (CvCARTClassifier**) cvAlloc( data_size ) );
3208 CV_CALL( cvBtNext( trees,
3209 (CvBtTrainer*) ((CvBtClassifier*) classifier)->trainer ) );
3210 CV_CALL( cvSeqPushMulti( ((CvBtClassifier*) classifier)->seq,
3211 trees, ((CvBtClassifier*) classifier)->numclasses ) );
3212 CV_CALL( cvFree( &trees ) );
3213 ((CvBtClassifier*) classifier)->numiter++;
3218 if( CV_IS_TUNABLE( classifier->flags ) )
3223 assert( ((CvBtClassifier*) classifier)->seq->total ==
3224 ((CvBtClassifier*) classifier)->numiter *
3225 ((CvBtClassifier*) classifier)->numclasses );
3227 data_size = sizeof( ((CvBtClassifier*) classifier)->trees[0] ) *
3228 ((CvBtClassifier*) classifier)->seq->total;
3229 CV_CALL( ptr = cvAlloc( data_size ) );
3230 CV_CALL( cvCvtSeqToArray( ((CvBtClassifier*) classifier)->seq, ptr ) );
3231 CV_CALL( cvReleaseMemStorage(
3232 &(((CvBtClassifier*) classifier)->seq->storage) ) );
3233 ((CvBtClassifier*) classifier)->trees = (CvCARTClassifier**) ptr;
3234 classifier->flags &= ~CV_TUNABLE;
3235 CV_CALL( cvBtEnd( (CvBtTrainer**)
3236 &(((CvBtClassifier*) classifier)->trainer )) );
3237 ((CvBtClassifier*) classifier)->trainer = NULL;
3244 CvBtClassifier* icvAllocBtClassifier( CvBoostType type, int flags, int numclasses,
3247 CvBtClassifier* ptr;
3250 assert( numclasses >= 1 );
3251 assert( numiter >= 0 );
3252 assert( ( numclasses == 1 ) || (type == CV_LKCLASS) );
3254 data_size = sizeof( *ptr );
3255 ptr = (CvBtClassifier*) cvAlloc( data_size );
3256 memset( ptr, 0, data_size );
3258 if( CV_IS_TUNABLE( flags ) )
3260 ptr->seq = cvCreateSeq( 0, sizeof( *(ptr->seq) ), sizeof( *(ptr->trees) ),
3261 cvCreateMemStorage() );
3266 data_size = numclasses * numiter * sizeof( *(ptr->trees) );
3267 ptr->trees = (CvCARTClassifier**) cvAlloc( data_size );
3268 memset( ptr->trees, 0, data_size );
3270 ptr->numiter = numiter;
3274 ptr->numclasses = numclasses;
3277 ptr->eval = icvEvalBtClassifier[(int) type];
3278 ptr->tune = cvTuneBtClassifier;
3279 ptr->save = cvSaveBtClassifier;
3280 ptr->release = cvReleaseBtClassifier;
3286 CvClassifier* cvCreateBtClassifier( CvMat* trainData,
3288 CvMat* trainClasses,
3290 CvMat* missedMeasurementsMask,
3294 CvClassifierTrainParams* trainParams )
3296 CvBtClassifier* ptr = 0;
3298 CV_FUNCNAME( "cvCreateBtClassifier" );
3305 CvCARTClassifier** trees;
3308 CV_ASSERT( trainData != NULL );
3309 CV_ASSERT( trainClasses != NULL );
3310 CV_ASSERT( typeMask == NULL );
3311 CV_ASSERT( missedMeasurementsMask == NULL );
3312 CV_ASSERT( compIdx == NULL );
3313 CV_ASSERT( weights == NULL );
3314 CV_ASSERT( trainParams != NULL );
3316 type = ((CvBtClassifierTrainParams*) trainParams)->type;
3318 if( type >= CV_DABCLASS && type <= CV_GABCLASS && sampleIdx )
3320 CV_ERROR( CV_StsBadArg, "Sample indices are not supported for this type" );
3323 if( type == CV_LKCLASS )
3328 cvMinMaxLoc( trainClasses, &min_val, &max_val );
3329 num_classes = (int) (max_val + 1.0);
3331 CV_ASSERT( num_classes >= 2 );
3337 num_iter = ((CvBtClassifierTrainParams*) trainParams)->numiter;
3339 CV_ASSERT( num_iter > 0 );
3341 ptr = icvAllocBtClassifier( type, CV_TUNABLE | flags, num_classes, num_iter );
3342 ptr->numfeatures = (CV_IS_ROW_SAMPLE( flags )) ? trainData->cols : trainData->rows;
3346 printf( "Iteration %d\n", 1 );
3348 data_size = sizeof( *trees ) * ptr->numclasses;
3349 CV_CALL( trees = (CvCARTClassifier**) cvAlloc( data_size ) );
3351 CV_CALL( ptr->trainer = cvBtStart( trees, trainData, flags, trainClasses, sampleIdx,
3352 ((CvBtClassifierTrainParams*) trainParams)->numsplits, type, num_classes,
3353 &(((CvBtClassifierTrainParams*) trainParams)->param[0]) ) );
3355 CV_CALL( cvSeqPushMulti( ptr->seq, trees, ptr->numclasses ) );
3356 CV_CALL( cvFree( &trees ) );
3359 for( i = 1; i < num_iter; i++ )
3361 ptr->tune( (CvClassifier*) ptr, NULL, CV_TUNABLE, NULL, NULL, NULL, NULL, NULL );
3363 if( !CV_IS_TUNABLE( flags ) )
3366 ptr->tune( (CvClassifier*) ptr, NULL, 0, NULL, NULL, NULL, NULL, NULL );
3371 return (CvClassifier*) ptr;
3375 CvClassifier* cvCreateBtClassifierFromFile( const char* filename )
3377 CvBtClassifier* ptr = 0;
3379 CV_FUNCNAME( "cvCreateBtClassifierFromFile" );
3386 int num_classifiers;
3391 CV_ASSERT( filename != NULL );
3394 file = fopen( filename, "r" );
3397 CV_ERROR( CV_StsError, "Unable to open file" );
3400 fscanf( file, "%d %d %d %d", &type, &num_classes, &num_features, &num_classifiers );
3402 CV_ASSERT( type >= (int) CV_DABCLASS && type <= (int) CV_MREG );
3403 CV_ASSERT( num_features > 0 );
3404 CV_ASSERT( num_classifiers > 0 );
3406 if( (CvBoostType) type != CV_LKCLASS )
3410 ptr = icvAllocBtClassifier( (CvBoostType) type, 0, num_classes, num_classifiers );
3411 ptr->numfeatures = num_features;
3413 for( i = 0; i < num_classes * num_classifiers; i++ )
3416 CvCARTClassifier* tree;
3418 fscanf( file, "%d", &count );
3420 data_size = sizeof( *tree )
3421 + count * ( sizeof( *(tree->compidx) ) + sizeof( *(tree->threshold) ) +
3422 sizeof( *(tree->right) ) + sizeof( *(tree->left) ) )
3423 + (count + 1) * ( sizeof( *(tree->val) ) );
3424 CV_CALL( tree = (CvCARTClassifier*) cvAlloc( data_size ) );
3425 memset( tree, 0, data_size );
3426 tree->eval = cvEvalCARTClassifier;
3429 tree->release = cvReleaseCARTClassifier;
3430 tree->compidx = (int*) ( tree + 1 );
3431 tree->threshold = (float*) ( tree->compidx + count );
3432 tree->left = (int*) ( tree->threshold + count );
3433 tree->right = (int*) ( tree->left + count );
3434 tree->val = (float*) ( tree->right + count );
3436 tree->count = count;
3437 for( j = 0; j < tree->count; j++ )
3439 fscanf( file, "%d %g %d %d", &(tree->compidx[j]),
3440 &(tree->threshold[j]),
3442 &(tree->right[j]) );
3444 for( j = 0; j <= tree->count; j++ )
3446 fscanf( file, "%g", &(tree->val[j]) );
3448 ptr->trees[i] = tree;
3455 return (CvClassifier*) ptr;
3458 /****************************************************************************************\
3459 * Utility functions *
3460 \****************************************************************************************/
3463 CvMat* cvTrimWeights( CvMat* weights, CvMat* idx, float factor )
3467 CV_FUNCNAME( "cvTrimWeights" );
3476 float* sorted_weights;
3478 CV_ASSERT( CV_MAT_TYPE( weights->type ) == CV_32FC1 );
3481 sorted_weights = NULL;
3483 if( factor > 0.0F && factor < 1.0F )
3487 CV_MAT2VEC( *weights, wdata, wstep, wnum );
3488 num = ( idx == NULL ) ? wnum : MAX( idx->rows, idx->cols );
3490 data_size = num * sizeof( *sorted_weights );
3491 sorted_weights = (float*) cvAlloc( data_size );
3492 memset( sorted_weights, 0, data_size );
3495 for( i = 0; i < num; i++ )
3497 index = icvGetIdxAt( idx, i );
3498 sorted_weights[i] = *((float*) (wdata + index * wstep));
3499 sum_weights += sorted_weights[i];
3502 icvSort_32f( sorted_weights, num, 0 );
3504 sum_weights *= (1.0F - factor);
3507 do { sum_weights -= sorted_weights[++i]; }
3508 while( sum_weights > 0.0F && i < (num - 1) );
3510 threshold = sorted_weights[i];
3512 while( i > 0 && sorted_weights[i-1] == threshold ) i--;
3514 if( i > 0 || ( idx != NULL && CV_MAT_TYPE( idx->type ) != CV_32FC1 ) )
3516 CV_CALL( ptr = cvCreateMat( 1, num - i, CV_32FC1 ) );
3518 for( i = 0; i < num; i++ )
3520 index = icvGetIdxAt( idx, i );
3521 if( *((float*) (wdata + index * wstep)) >= threshold )
3523 CV_MAT_ELEM( *ptr, float, 0, count ) = (float) index;
3528 assert( count == ptr->cols );
3530 cvFree( &sorted_weights );
3540 void cvReadTrainData( const char* filename, int flags,
3542 CvMat** trainClasses )
3545 CV_FUNCNAME( "cvReadTrainData" );
3554 if( filename == NULL )
3556 CV_ERROR( CV_StsNullPtr, "filename must be specified" );
3558 if( trainData == NULL )
3560 CV_ERROR( CV_StsNullPtr, "trainData must be not NULL" );
3562 if( trainClasses == NULL )
3564 CV_ERROR( CV_StsNullPtr, "trainClasses must be not NULL" );
3568 *trainClasses = NULL;
3569 file = fopen( filename, "r" );
3572 CV_ERROR( CV_StsError, "Unable to open file" );
3575 fscanf( file, "%d %d", &m, &n );
3577 if( CV_IS_ROW_SAMPLE( flags ) )
3579 CV_CALL( *trainData = cvCreateMat( m, n, CV_32FC1 ) );
3583 CV_CALL( *trainData = cvCreateMat( n, m, CV_32FC1 ) );
3586 CV_CALL( *trainClasses = cvCreateMat( 1, m, CV_32FC1 ) );
3588 for( i = 0; i < m; i++ )
3590 for( j = 0; j < n; j++ )
3592 fscanf( file, "%f", &val );
3593 if( CV_IS_ROW_SAMPLE( flags ) )
3595 CV_MAT_ELEM( **trainData, float, i, j ) = val;
3599 CV_MAT_ELEM( **trainData, float, j, i ) = val;
3602 fscanf( file, "%f", &val );
3603 CV_MAT_ELEM( **trainClasses, float, 0, i ) = val;
3613 void cvWriteTrainData( const char* filename, int flags,
3614 CvMat* trainData, CvMat* trainClasses, CvMat* sampleIdx )
3616 CV_FUNCNAME( "cvWriteTrainData" );
3628 if( filename == NULL )
3630 CV_ERROR( CV_StsNullPtr, "filename must be specified" );
3632 if( trainData == NULL || CV_MAT_TYPE( trainData->type ) != CV_32FC1 )
3634 CV_ERROR( CV_StsUnsupportedFormat, "Invalid trainData" );
3636 if( CV_IS_ROW_SAMPLE( flags ) )
3638 m = trainData->rows;
3639 n = trainData->cols;
3643 n = trainData->rows;
3644 m = trainData->cols;
3646 if( trainClasses == NULL || CV_MAT_TYPE( trainClasses->type ) != CV_32FC1 ||
3647 MIN( trainClasses->rows, trainClasses->cols ) != 1 )
3649 CV_ERROR( CV_StsUnsupportedFormat, "Invalid trainClasses" );
3651 clsrow = (trainClasses->rows == 1);
3652 if( m != ( (clsrow) ? trainClasses->cols : trainClasses->rows ) )
3654 CV_ERROR( CV_StsUnmatchedSizes, "Incorrect trainData and trainClasses sizes" );
3657 if( sampleIdx != NULL )
3659 count = (sampleIdx->rows == 1) ? sampleIdx->cols : sampleIdx->rows;
3667 file = fopen( filename, "w" );
3670 CV_ERROR( CV_StsError, "Unable to create file" );
3673 fprintf( file, "%d %d\n", count, n );
3675 for( i = 0; i < count; i++ )
3679 if( sampleIdx->rows == 1 )
3681 sc = cvGet2D( sampleIdx, 0, i );
3685 sc = cvGet2D( sampleIdx, i, 0 );
3687 idx = (int) sc.val[0];
3693 for( j = 0; j < n; j++ )
3695 fprintf( file, "%g ", ( (CV_IS_ROW_SAMPLE( flags ))
3696 ? CV_MAT_ELEM( *trainData, float, idx, j )
3697 : CV_MAT_ELEM( *trainData, float, j, idx ) ) );
3699 fprintf( file, "%g\n", ( (clsrow)
3700 ? CV_MAT_ELEM( *trainClasses, float, 0, idx )
3701 : CV_MAT_ELEM( *trainClasses, float, idx, 0 ) ) );
3710 #define ICV_RAND_SHUFFLE( suffix, type ) \
3711 void icvRandShuffle_##suffix( uchar* data, size_t step, int num ) \
3713 CvRandState state; \
3721 cvRandInit( &state, (double) 0, (double) 0, (int)seed ); \
3722 for( i = 0; i < (num-1); i++ ) \
3724 rn = ((float) cvRandNext( &state )) / (1.0F + UINT_MAX); \
3725 CV_SWAP( *((type*)(data + i * step)), \
3726 *((type*)(data + ( i + (int)( rn * (num - i ) ) )* step)), \
3731 ICV_RAND_SHUFFLE( 8U, uchar )
3733 ICV_RAND_SHUFFLE( 16S, short )
3735 ICV_RAND_SHUFFLE( 32S, int )
3737 ICV_RAND_SHUFFLE( 32F, float )
3740 void cvRandShuffleVec( CvMat* mat )
3742 CV_FUNCNAME( "cvRandShuffle" );
3750 if( (mat == NULL) || !CV_IS_MAT( mat ) || MIN( mat->rows, mat->cols ) != 1 )
3752 CV_ERROR( CV_StsUnsupportedFormat, "" );
3755 CV_MAT2VEC( *mat, data, step, num );
3756 switch( CV_MAT_TYPE( mat->type ) )
3759 icvRandShuffle_8U( data, step, num);
3762 icvRandShuffle_16S( data, step, num);
3765 icvRandShuffle_32S( data, step, num);
3768 icvRandShuffle_32F( data, step, num);
3771 CV_ERROR( CV_StsUnsupportedFormat, "" );