cvBoostStartTraining, cvBoostNextWeakClassifier和 cvBoostEndTraining

/*****************************************************************************************                                        Boosting                                        *
\****************************************************************************************/

typedef struct CvBoostTrainer
{
    CvBoostType type;      //一共四类例如以下
   /* CV_DABCLASS = 0, // 2 class Discrete AdaBoost?????????
??? CV_RABCLASS = 1, // 2 class Real AdaBoost??????????????
??? CV_LBCLASS? = 2, // 2 class LogitBoost?????????????????
??? CV_GABCLASS = 3, //2 class Gentle AdaBoost???????????? */

  ?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,     //训练样本的类别为0,1
                                       CvMat* weakTrainVals,    //训练的弱分类器的输出值,-1和1
                                       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 );
    }
  /*******************************ptr的初始化*********************************************/
  ?datasize = sizeof( *ptr ) + sizeof( *ptr->idx ) * idxnum;
    ptr = (CvBoostTrainer*) cvAlloc( datasize );         //为ptr分配内存
    memset( ptr, 0, datasize );                          //初始化ptr,所有为0
    ptr->F = NULL;
    ptr->idx = NULL;

    ptr->count = m;
    ptr->type = type;

    if( idxnum > 0 )
    {
        CvScalar s;       //s内部是四个double型的val,分别为val[0],val[1],val[2]val[3]

        ptr->idx = (int*) (ptr + 1);
        ptr->count = idxnum;
        for( i = 0; i < ptr->count; i++ )
        {
           //将原始数据转化为cvScale类型的数据
           ?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;////y*=2y-1,类别标签由{0,1}变为{-1,1}
    }

    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 );                                       //取对数后,再取相反数,目的是把把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;                                                    //返回err。注意这个err是取对数后,再取相反数的那个err,也就是上文程序中最后那个err
}

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    );
}

原文地址:https://www.cnblogs.com/llguanli/p/8410428.html

时间: 2024-11-05 11:18:36

cvBoostStartTraining, cvBoostNextWeakClassifier和 cvBoostEndTraining的相关文章

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

/***************************************************************************************** Boosting * \****************************************************************************************/ typedef struct CvBoostTrainer { CvBoostType type; int cou

opencv源码之一:cvboost.cpp

我使用的是opencv2.4.9,安装后,我的cvboost..cpp文件的路径是........\opencv\sources\apps\haartraining\cvboost.cpp,研究源码那么多天,有很多收获,opencv库真是非常强大.具体内容如下: /*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFOR

cvBoostNextWeakClassifier(翻译)

原文如下: /* * cvBoostNextWeakClassifier * * The cvBoostNextWeakClassifier function performs next training * iteration and caluclates response values and weights for the next weak * classifier training. * * Parameters * weakEvalVals * Vector of values ob

cvBoostStartTraining

原文如下: /***************************************************************************************** Iterative training functions * \****************************************************************************************/ /* * CvBoostTrainer * * The CvB

Opencv研读笔记:haartraining程序之icvCreateCARTStageClassifier函数详解~

之前介绍了haartraining程序中的cvCreateMTStumpClassifier函数,这个函数的功能是计算最优弱分类器,这篇文章介绍一下自己对haartraining中关于强分类器计算的一些理解,也就是程序中的icvCreateCARTStageClassifier函数. 由于haartraining是基于HAAR特征进行adaboost训练,对于HAAR特征的处理比较繁琐,采用了奇数弱分类器补充针对翻转特征最优弱分类器计算的代码,所以代码看起来较为冗长.此外,其采用了较多的中间结构

opencv源代码分析之二:cvhaartraining.cpp

我使用的是opencv2.4.9.安装后.我的cvboost..cpp文件的路径是........\opencv\sources\apps\haartraining\cvhaartraining.cpp,研究源代码那么多天,有非常多收获.opencv库真是非常强大.当中在这篇博文中我有部分凝视,其它的有关知识请參考我博客http://blog.csdn.net/ding977921830?viewmode=contents.详细内容例如以下: /*M///////////////////////

opencv源码分析之二:cvhaartraining.cpp

我使用的是opencv2.4.9,安装后,我的cvboost..cpp文件的路径是........\opencv\sources\apps\haartraining\cvhaartraining.cpp,研究源码那么多天,有很多收获,opencv库真是非常强大.其中在这篇博文中我有部分注释,其他的有关知识请参考我博客http://blog.csdn.net/ding977921830?viewmode=contents.具体内容如下: /*M///////////////////////////