首页 > 代码库 > opencv之adaboost中的cvCreateMTStumpClassifier函数详解~

opencv之adaboost中的cvCreateMTStumpClassifier函数详解~

cvCreateMTStumpClassifier函数出自opencv中的haartraining程序,在adaboost(cvCreateTreeCascadeClassifier)的强分类器(icvCreateCARTStageClassifier)中被两次调用,该函数用于寻找最优弱分类器,或者说成计算最优haar特征。功能很明确,但是大家都知道的,opencv的代码绝大部分写的让人真心看不懂,这个函数算是haartraining中比较难以看懂的函数,局部变量达到20个之多,童鞋我也是不甘心,不甘心被这小小的函数所击溃,于是擦干泪水,仔细研读,终于恍然大悟,大彻大悟的同时,不忘回报CSDN博客,与朋友们分享。

最优弱分类器的计算过程,网上到处都有介绍,其实就是个穷举的过程,对每个特征多对应的训练样本的特征值进行排序,然后遍历每个特征值作为阈值,根据一定的公式(1.misclass 2.gini 3.entropy 4.least sum of squares确定最优阈值,进一步确定最优特征,也就是最优弱分类器了。

但是opencv写的比较通用,所以有点让人摸不清头脑,它是这么干的:我先预计算一些haar特征(基本上为600个)的训练样本升序矩阵(trainData),然后先寻找这600个特征中的最优特征,但是总共的特征可能有1万多个,对于新特征那就只能在重新计算训练样本升序矩阵(mat),继续寻找最优特征。可能是程序一直跃跃欲试,想用并行的方法处理,导致了程序的局部变量增多(例如portion的引用)。这是值得大家注意的地方。

另外,上面说到cvCreateMTStumpClassifier函数被两次调用,一次是在cvCreateCARTClassifier中,一次是在icvCreateCARTStageClassifier中,其中,cvCreateCARTClassifier中trainData对应的是一个矩阵,而后者对应的是一个行向量。

注意上面两处,应该就不会被弄晕了,我直接上代码,并且做了比较详细的注释,这样子更加实在一些,希望能够对童鞋们有所帮助!

// 函数功能:计算最优弱分类器
CV_BOOST_IMPL
CvClassifier* cvCreateMTStumpClassifier( CvMat* trainData,      // 训练样本特征值
                      int flags,                                // 1.按行排列,0.按列排列
                      CvMat* trainClasses,                      // weakTrainVals(行向量)
                      CvMat* /*typeMask*/,                      // 搞不懂这么写有什么意义
                      CvMat* missedMeasurementsMask,            // 未知,很少用到
                      CvMat* compIdx,                           // 特征序列(必须为NULL)(行向量)
                      CvMat* sampleIdx,                         // 实际训练样本序列(行向量)
                      CvMat* weights,                           // 实际训练样本样本权重(行向量)
                      CvClassifierTrainParams* trainParams )    // 其它数据&参数
{
    CvStumpClassifier* stump = NULL;        // 弱分类器(桩)
    int m = 0;                              // 样本总数
    int n = 0;                              // 所有特征个数   
    uchar* data = http://www.mamicode.com/NULL;                     // trainData数据指针>


其实,我现在一直认为,寻找弱分类器是一个很easy的过程,根本不需要这么多行代码,这么多局部变量,但是仔细阅读之后发现,opencv还是很牛的,这段代码的通用性比较强大,兼顾了并行操作可能性。可以应对多特征弱分类器,代码结构也是比较爽快的,尤其是其在条件宏、函数指针方面的应用,令人羡慕异常。今后还要继续研读opencv代码,对编程素养的提高,绝对有很大帮助。

如果有啥问题,还请不吝赐教,私聊,评论,哪怕直接骂都可以!!!!

opencv之adaboost中的cvCreateMTStumpClassifier函数详解~