码迷,mamicode.com
首页 > 其他好文 > 详细

opencv源码分析:有关boosting的源代码( cvBoostStartTraining, cvBoostNextWeakClassifier, cvBoostEndTraining)

时间:2015-06-24 13:01:42      阅读:83      评论:0      收藏:0      [点我收藏+]

标签: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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!