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

cvTrimWeights函数详细解读

时间:2015-07-10 16:42:21      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:cvtrimweights   opencv源码分析   adaboost   

cvTrimWeights的源码在opencv的cvboost.cpp文件之中,具体内容和部分注释如下所

/*
 *cvTrimWeights
 *作用:对小于一定阈值的权重剔除,因为权重较小的样本对训练结果影响很小,剔除后,这样在训练样本时可以缩短训练时间
 */
CV_BOOST_IMPL
CvMat* cvTrimWeights( CvMat* weights,//训练样本的权重矩阵
                      CvMat* idx,    //训练样本的索引序列矩阵
                      float factor ) //剔除小权重的样本后剩余样本的比例,根据这个参数来计算需要剔除较小样本的阈值
{
    CvMat* ptr = 0;

    CV_FUNCNAME( "cvTrimWeights" );
    __BEGIN__;
    int i, index, num;
    float sum_weights;
    uchar* wdata;
    size_t wstep;
    int wnum;
    float threshold;
    int count;
    float* sorted_weights;

    CV_ASSERT( CV_MAT_TYPE( weights->type ) == CV_32FC1 );

    ptr = idx;
    sorted_weights = NULL;

    if( factor > 0.0F && factor < 1.0F )
    {
        size_t data_size;

        CV_MAT2VEC( *weights, wdata, wstep, wnum );
        num = ( idx == NULL ) ? wnum : MAX( idx->rows, idx->cols );

        data_size = num * sizeof( *sorted_weights );
        sorted_weights = (float*) cvAlloc( data_size );
        memset( sorted_weights, 0, data_size );

        sum_weights = 0.0F;
        for( i = 0; i < num; i++ )
        {
            index = icvGetIdxAt( idx, i );//将矩阵idx中第i个位置上的样本序列取出
            sorted_weights[i] = *((float*) (wdata + index * wstep));//取出idx第i个位置上的权重
            sum_weights += sorted_weights[i];//样本的权重和
        }

        icvSort_32f( sorted_weights, num, 0 );//对样本排序

        sum_weights *= (1.0F - factor);      //根据训练样本总的权重和factor来计算需要剔除的小权重训练样本的权重和

        i = -1;
        do { sum_weights -= sorted_weights[++i]; }//对排序后的样本从最小的小权重的样本开始减去,直到while中条件结束
        while( sum_weights > 0.0F && i < (num - 1) );

        threshold = sorted_weights[i];      
       /*跳出do-while循环后,把没有被剔除权重的样本中,最小权重的那个样本的权重赋给threshold。对外表现为:凡是样本的权重小于
        这个阈值,就直接剔除*/

        while( i > 0 && sorted_weights[i-1] == threshold ) i--;//剔除小权重的样本后,再对原来剔除的那部分中等于阈值的样本捡回来,挺人性化的哈

        if( i > 0 || ( idx != NULL && CV_MAT_TYPE( idx->type ) != CV_32FC1 ) )
        {
            CV_CALL( ptr = cvCreateMat( 1, num - i, CV_32FC1 ) );
            count = 0;
            for( i = 0; i < num; i++ )
            {
                index = icvGetIdxAt( idx, i );
                if( *((float*) (wdata + index * wstep)) >= threshold )//只对阈值>threshold的权重操作
                {
                    CV_MAT_ELEM( *ptr, float, 0, count ) = (float) index;
                    count++;
                }
            }

            assert( count == ptr->cols );
        }
        cvFree( &sorted_weights );
    }

    __END__;

    return ptr;     //只返回权重大于阈值的样本
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

cvTrimWeights函数详细解读

标签:cvtrimweights   opencv源码分析   adaboost   

原文地址:http://blog.csdn.net/ding977921830/article/details/46830399

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