标签:cvbooststarttraining cvboostnextweakclass cvboostendtraining cvboost.cpp opencv源码分析
/***************************************************************************************** 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 );
}
opencv源码分析:有关boosting的源代码( cvBoostStartTraining, cvBoostNextWeakClassifier, cvBoostEndTraining)
标签:cvbooststarttraining cvboostnextweakclass cvboostendtraining cvboost.cpp opencv源码分析
原文地址:http://blog.csdn.net/ding977921830/article/details/46619235