/***************************************************************************************** Boosting * \****************************************************************************************/ typedef struct CvBoostTrainer { CvBoostType type; int count; /* (idx) ? number_of_indices : number_of_samples */ int* idx; float* F; } CvBoostTrainer; /* * cvBoostStartTraining, cvBoostNextWeakClassifier, cvBoostEndTraining * * These functions perform training of 2-class boosting classifier * using ANY appropriate weak classifier */ static CvBoostTrainer* icvBoostStartTraining( CvMat* trainClasses, CvMat* weakTrainVals, CvMat* /*weights*/, CvMat* sampleIdx, CvBoostType type ) { uchar* ydata; int ystep; int m; uchar* traindata; int trainstep; int trainnum; int i; int idx; size_t datasize; CvBoostTrainer* ptr; int idxnum; int idxstep; uchar* idxdata; assert( trainClasses != NULL ); assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 ); assert( weakTrainVals != NULL ); assert( CV_MAT_TYPE( weakTrainVals->type ) == CV_32FC1 ); CV_MAT2VEC( *trainClasses, ydata, ystep, m ); CV_MAT2VEC( *weakTrainVals, traindata, trainstep, trainnum ); CV_Assert( m == trainnum ); idxnum = 0; idxstep = 0; idxdata = NULL; if( sampleIdx ) { CV_MAT2VEC( *sampleIdx, idxdata, idxstep, idxnum ); } datasize = sizeof( *ptr ) + sizeof( *ptr->idx ) * idxnum; ptr = (CvBoostTrainer*) cvAlloc( datasize ); memset( ptr, 0, datasize ); ptr->F = NULL; ptr->idx = NULL; ptr->count = m; ptr->type = type; if( idxnum > 0 ) { CvScalar s; ptr->idx = (int*) (ptr + 1); ptr->count = idxnum; for( i = 0; i < ptr->count; i++ ) { cvRawDataToScalar( idxdata + i*idxstep, CV_MAT_TYPE( sampleIdx->type ), &s ); ptr->idx[i] = (int) s.val[0]; } } for( i = 0; i < ptr->count; i++ ) { idx = (ptr->idx) ? ptr->idx[i] : i; *((float*) (traindata + idx * trainstep)) = 2.0F * (*((float*) (ydata + idx * ystep))) - 1.0F; } return ptr; } /* * * Discrete AdaBoost functions * */ static float icvBoostNextWeakClassifierDAB( CvMat* weakEvalVals, CvMat* trainClasses, CvMat* /*weakTrainVals*/, CvMat* weights, CvBoostTrainer* trainer ) { uchar* evaldata; int evalstep; int m; uchar* ydata; int ystep; int ynum; uchar* wdata; int wstep; int wnum; float sumw; float err; int i; int idx; CV_Assert( weakEvalVals != NULL ); CV_Assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 ); CV_Assert( trainClasses != NULL ); CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 ); CV_Assert( weights != NULL ); CV_Assert( CV_MAT_TYPE( weights ->type ) == CV_32FC1 ); CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m ); CV_MAT2VEC( *trainClasses, ydata, ystep, ynum ); CV_MAT2VEC( *weights, wdata, wstep, wnum ); CV_Assert( m == ynum ); CV_Assert( m == wnum ); sumw = 0.0F; err = 0.0F; for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; sumw += *((float*) (wdata + idx*wstep)); err += (*((float*) (wdata + idx*wstep))) * ( (*((float*) (evaldata + idx*evalstep))) != 2.0F * (*((float*) (ydata + idx*ystep))) - 1.0F ); } err /= sumw; err = -cvLogRatio( err ); for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; *((float*) (wdata + idx*wstep)) *= expf( err * ((*((float*) (evaldata + idx*evalstep))) != 2.0F * (*((float*) (ydata + idx*ystep))) - 1.0F) ); sumw += *((float*) (wdata + idx*wstep)); } for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; *((float*) (wdata + idx * wstep)) /= sumw; } return err; } /* * * Real AdaBoost functions * */ static float icvBoostNextWeakClassifierRAB( CvMat* weakEvalVals, CvMat* trainClasses, CvMat* /*weakTrainVals*/, CvMat* weights, CvBoostTrainer* trainer ) { uchar* evaldata; int evalstep; int m; uchar* ydata; int ystep; int ynum; uchar* wdata; int wstep; int wnum; float sumw; int i, idx; CV_Assert( weakEvalVals != NULL ); CV_Assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 ); CV_Assert( trainClasses != NULL ); CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 ); CV_Assert( weights != NULL ); CV_Assert( CV_MAT_TYPE( weights ->type ) == CV_32FC1 ); CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m ); CV_MAT2VEC( *trainClasses, ydata, ystep, ynum ); CV_MAT2VEC( *weights, wdata, wstep, wnum ); CV_Assert( m == ynum ); CV_Assert( m == wnum ); sumw = 0.0F; for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; *((float*) (wdata + idx*wstep)) *= expf( (-(*((float*) (ydata + idx*ystep))) + 0.5F) * cvLogRatio( *((float*) (evaldata + idx*evalstep)) ) ); sumw += *((float*) (wdata + idx*wstep)); } for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; *((float*) (wdata + idx*wstep)) /= sumw; } return 1.0F; } /* * * LogitBoost functions * */ #define CV_LB_PROB_THRESH 0.01F #define CV_LB_WEIGHT_THRESHOLD 0.0001F static void icvResponsesAndWeightsLB( int num, uchar* wdata, int wstep, uchar* ydata, int ystep, uchar* fdata, int fstep, uchar* traindata, int trainstep, int* indices ) { int i, idx; float p; for( i = 0; i < num; i++ ) { idx = (indices) ? indices[i] : i; p = 1.0F / (1.0F + expf( -(*((float*) (fdata + idx*fstep)))) ); *((float*) (wdata + idx*wstep)) = MAX( p * (1.0F - p), CV_LB_WEIGHT_THRESHOLD ); if( *((float*) (ydata + idx*ystep)) == 1.0F ) { *((float*) (traindata + idx*trainstep)) = 1.0F / (MAX( p, CV_LB_PROB_THRESH )); } else { *((float*) (traindata + idx*trainstep)) = -1.0F / (MAX( 1.0F - p, CV_LB_PROB_THRESH )); } } } static CvBoostTrainer* icvBoostStartTrainingLB( CvMat* trainClasses, CvMat* weakTrainVals, CvMat* weights, CvMat* sampleIdx, CvBoostType type ) { size_t datasize; CvBoostTrainer* ptr; uchar* ydata; int ystep; int m; uchar* traindata; int trainstep; int trainnum; uchar* wdata; int wstep; int wnum; int i; int idxnum; int idxstep; uchar* idxdata; assert( trainClasses != NULL ); assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 ); assert( weakTrainVals != NULL ); assert( CV_MAT_TYPE( weakTrainVals->type ) == CV_32FC1 ); assert( weights != NULL ); assert( CV_MAT_TYPE( weights->type ) == CV_32FC1 ); CV_MAT2VEC( *trainClasses, ydata, ystep, m ); CV_MAT2VEC( *weakTrainVals, traindata, trainstep, trainnum ); CV_MAT2VEC( *weights, wdata, wstep, wnum ); CV_Assert( m == trainnum ); CV_Assert( m == wnum ); idxnum = 0; idxstep = 0; idxdata = NULL; if( sampleIdx ) { CV_MAT2VEC( *sampleIdx, idxdata, idxstep, idxnum ); } datasize = sizeof( *ptr ) + sizeof( *ptr->F ) * m + sizeof( *ptr->idx ) * idxnum; ptr = (CvBoostTrainer*) cvAlloc( datasize ); memset( ptr, 0, datasize ); ptr->F = (float*) (ptr + 1); ptr->idx = NULL; ptr->count = m; ptr->type = type; if( idxnum > 0 ) { CvScalar s; ptr->idx = (int*) (ptr->F + m); ptr->count = idxnum; for( i = 0; i < ptr->count; i++ ) { cvRawDataToScalar( idxdata + i*idxstep, CV_MAT_TYPE( sampleIdx->type ), &s ); ptr->idx[i] = (int) s.val[0]; } } for( i = 0; i < m; i++ ) { ptr->F[i] = 0.0F; } icvResponsesAndWeightsLB( ptr->count, wdata, wstep, ydata, ystep, (uchar*) ptr->F, sizeof( *ptr->F ), traindata, trainstep, ptr->idx ); return ptr; } static float icvBoostNextWeakClassifierLB( CvMat* weakEvalVals, CvMat* trainClasses, CvMat* weakTrainVals, CvMat* weights, CvBoostTrainer* trainer ) { uchar* evaldata; int evalstep; int m; uchar* ydata; int ystep; int ynum; uchar* traindata; int trainstep; int trainnum; uchar* wdata; int wstep; int wnum; int i, idx; assert( weakEvalVals != NULL ); assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 ); assert( trainClasses != NULL ); assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 ); assert( weakTrainVals != NULL ); assert( CV_MAT_TYPE( weakTrainVals->type ) == CV_32FC1 ); assert( weights != NULL ); assert( CV_MAT_TYPE( weights ->type ) == CV_32FC1 ); CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m ); CV_MAT2VEC( *trainClasses, ydata, ystep, ynum ); CV_MAT2VEC( *weakTrainVals, traindata, trainstep, trainnum ); CV_MAT2VEC( *weights, wdata, wstep, wnum ); CV_Assert( m == ynum ); CV_Assert( m == wnum ); CV_Assert( m == trainnum ); //assert( m == trainer->count ); for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; trainer->F[idx] += *((float*) (evaldata + idx * evalstep)); } icvResponsesAndWeightsLB( trainer->count, wdata, wstep, ydata, ystep, (uchar*) trainer->F, sizeof( *trainer->F ), traindata, trainstep, trainer->idx ); return 1.0F; } /* * * Gentle AdaBoost * */ static float icvBoostNextWeakClassifierGAB( CvMat* weakEvalVals, CvMat* trainClasses, CvMat* /*weakTrainVals*/, CvMat* weights, CvBoostTrainer* trainer ) { uchar* evaldata; int evalstep; int m; uchar* ydata; int ystep; int ynum; uchar* wdata; int wstep; int wnum; int i, idx; float sumw; CV_Assert( weakEvalVals != NULL ); CV_Assert( CV_MAT_TYPE( weakEvalVals->type ) == CV_32FC1 ); CV_Assert( trainClasses != NULL ); CV_Assert( CV_MAT_TYPE( trainClasses->type ) == CV_32FC1 ); CV_Assert( weights != NULL ); CV_Assert( CV_MAT_TYPE( weights->type ) == CV_32FC1 ); CV_MAT2VEC( *weakEvalVals, evaldata, evalstep, m ); CV_MAT2VEC( *trainClasses, ydata, ystep, ynum ); CV_MAT2VEC( *weights, wdata, wstep, wnum ); CV_Assert( m == ynum ); CV_Assert( m == wnum ); sumw = 0.0F; for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; *((float*) (wdata + idx*wstep)) *= expf( -(*((float*) (evaldata + idx*evalstep))) * ( 2.0F * (*((float*) (ydata + idx*ystep))) - 1.0F ) ); sumw += *((float*) (wdata + idx*wstep)); } for( i = 0; i < trainer->count; i++ ) { idx = (trainer->idx) ? trainer->idx[i] : i; *((float*) (wdata + idx*wstep)) /= sumw; } return 1.0F; } typedef CvBoostTrainer* (*CvBoostStartTraining)( CvMat* trainClasses, CvMat* weakTrainVals, CvMat* weights, CvMat* sampleIdx, CvBoostType type ); typedef float (*CvBoostNextWeakClassifier)( CvMat* weakEvalVals, CvMat* trainClasses, CvMat* weakTrainVals, CvMat* weights, CvBoostTrainer* data ); CvBoostStartTraining startTraining[4] = { icvBoostStartTraining, icvBoostStartTraining, icvBoostStartTrainingLB, icvBoostStartTraining }; CvBoostNextWeakClassifier nextWeakClassifier[4] = { icvBoostNextWeakClassifierDAB, icvBoostNextWeakClassifierRAB, icvBoostNextWeakClassifierLB, icvBoostNextWeakClassifierGAB }; /* * * Dispatchers * */ CV_BOOST_IMPL CvBoostTrainer* cvBoostStartTraining( CvMat* trainClasses, CvMat* weakTrainVals, CvMat* weights, CvMat* sampleIdx, CvBoostType type ) { return startTraining[type]( trainClasses, weakTrainVals, weights, sampleIdx, type ); } CV_BOOST_IMPL void cvBoostEndTraining( CvBoostTrainer** trainer ) { cvFree( trainer ); *trainer = NULL; } CV_BOOST_IMPL float cvBoostNextWeakClassifier( CvMat* weakEvalVals, CvMat* trainClasses, CvMat* weakTrainVals, CvMat* weights, CvBoostTrainer* trainer ) { return nextWeakClassifier[trainer->type]( weakEvalVals, trainClasses, weakTrainVals, weights, trainer ); }
时间: 2024-10-12 09:31:28