icvGetHaarTrainingData详细解析

本内容的源码在opencv开源源码的........\opencv\sources\apps\haartraining\cvhaartraining.cpp文件中,其他有关结构体,宏,函数指针的信息请参考http://blog.csdn.net/ding977921830/article/details/46799043。具体内容如下:

/* consumed counter */
typedef uint64 ccounter_t;
//含义无符号整形最大值
#define CCOUNTER_MAX CV_BIG_UINT(0xffffffffffffffff) 
//把括号内参数清零
#define CCOUNTER_SET_ZERO(cc) ((cc) = 0)             
//cc自加1
#define CCOUNTER_INC(cc) ( (CCOUNTER_MAX > (cc) ) ? (++(cc)) : (CCOUNTER_MAX) )
//二者之和
#define CCOUNTER_ADD(cc0, cc1) ( ((CCOUNTER_MAX-(cc1)) > (cc0) ) ? ((cc0) += (cc1)) : ((cc0) = CCOUNTER_MAX) )
//二者之除
#define CCOUNTER_DIV(cc0, cc1) ( ((cc1) == 0) ? 0 : ( ((double)(cc0))/(double)(int64)(cc1) ) ) 

/*
 * icvGetHaarTrainingData
 *计算从first开始共count个样本的haar特征值,并最后返回实际取出的haar特征值的个数
 * Unified method that can now be used for vec file, bg file and bg vec file
 *
 * Fill <data> with samples, passed <cascade>
 */
static
int icvGetHaarTrainingData( CvHaarTrainingData* data, 
                            int first, int count,         //计算从first开始的共count个训练样本的特征值
                            CvIntHaarClassifier* cascade, //计算haar特征值的haar分类器
                            CvGetHaarTrainingDataCallback callback,
                            void* userdata,              //训练样本数据和haar特征数据
                            int* consumed,               //查询过的正样本总数
                            double* acceptance_ratio )   //实际取出的haar特征数与查询过的haar特征数之比
{
    int i = 0;
    ccounter_t getcount = 0;         //实际取出的haar特征值的总数
    ccounter_t thread_getcount = 0;  //在程序中计算实际取出的haar特征值的总数
    ccounter_t consumed_count;       //查询过的haar特征总数
    ccounter_t thread_consumed_count;//在程序中计算查询过的haar特征总数

    /* private variables */
    CvMat img;     //源图像
    CvMat sum;     //积分图
    CvMat tilted;  //旋转积分图
    CvMat sqsum;   //像素平方的积分图

    sum_type* sumdata;
    sum_type* tilteddata;
    float*    normfactor;

    /* end private variables */

    assert( data != NULL );
    assert( first + count <= data->maxnum );
    assert( cascade != NULL );
    assert( callback != NULL );

    // if( !cvbgdata ) return 0; this check needs to be done in the callback for BG
    //清零
    CCOUNTER_SET_ZERO(getcount);
    CCOUNTER_SET_ZERO(thread_getcount);
    CCOUNTER_SET_ZERO(consumed_count);
    CCOUNTER_SET_ZERO(thread_consumed_count);

    #ifdef CV_OPENMP
    #pragma omp parallel private(img, sum, tilted, sqsum, sumdata, tilteddata, \
                                 normfactor, thread_consumed_count, thread_getcount)
    #endif /* CV_OPENMP */
    {
        sumdata    = NULL;
        tilteddata = NULL;
        normfactor = NULL;

        CCOUNTER_SET_ZERO(thread_getcount);
        CCOUNTER_SET_ZERO(thread_consumed_count);
        int ok = 1;
        //确定img,sum,tilted和sqsum的大小,并分配内存
        img = cvMat( data->winsize.height, data->winsize.width, CV_8UC1,
            cvAlloc( sizeof( uchar ) * data->winsize.height * data->winsize.width ) );
        sum = cvMat( data->winsize.height + 1, data->winsize.width + 1,
                     CV_SUM_MAT_TYPE, NULL );
        tilted = cvMat( data->winsize.height + 1, data->winsize.width + 1,
                        CV_SUM_MAT_TYPE, NULL );
        sqsum = cvMat( data->winsize.height + 1, data->winsize.width + 1, CV_SQSUM_MAT_TYPE,
                       cvAlloc( sizeof( sqsum_type ) * (data->winsize.height + 1)
                                                     * (data->winsize.width + 1) ) );

        #ifdef CV_OPENMP
        #pragma omp for schedule(static, 1)
        #endif /* CV_OPENMP */
        for( i = first; (i < first + count); i++ )//遍历从first开始的共count个样本
        {
            if( !ok )
                continue;
            for( ; ; )
            {
                ok = callback( &img, userdata );
                if( !ok )
                    break;

                CCOUNTER_INC(thread_consumed_count);//查询过的haar特征总数
                //在data中,每个样本的积分图占用一行,所以第i个样本的积分图为(sum_type*) (data->sum.data.ptr + i * data->sum.step)
                //把data中的积分图的数据进行传递
                sumdata = (sum_type*) (data->sum.data.ptr + i * data->sum.step);   
                tilteddata = (sum_type*) (data->tilted.data.ptr + i * data->tilted.step);
                normfactor = data->normfactor.data.fl + i;
                //把从data中提取出的数据存储到sum和tilted中
                sum.data.ptr = (uchar*) sumdata;
                tilted.data.ptr = (uchar*) tilteddata;
                icvGetAuxImages( &img, &sum, &tilted, &sqsum, normfactor );//根据img图像计算积分图,旋转积分图,平方积分图和归一化因子
                //如果计算出来的haar特征值不为0
                if( cascade->eval( cascade, sumdata, tilteddata, *normfactor ) != 0.0F )
                {
                    CCOUNTER_INC(thread_getcount);//从这里可以看出来thread_getcount的含义是这count个样本所有的有效的haar特征值的个数
                    break;
                }
            }

#ifdef CV_VERBOSE
            if( (i - first) % 500 == 0 )
            {
                fprintf( stderr, "%3d%%\r", (int) ( 100.0 * (i - first) / count ) );
                fflush( stderr );
            }
#endif /* CV_VERBOSE */
        }

        cvFree( &(img.data.ptr) );
        cvFree( &(sqsum.data.ptr) );

        #ifdef CV_OPENMP
        #pragma omp critical (c_consumed_count)
        #endif /* CV_OPENMP */
        {
            /* consumed_count += thread_consumed_count; */
            CCOUNTER_ADD(getcount, thread_getcount);           //得到的有效haar特征值的总数
            CCOUNTER_ADD(consumed_count, thread_consumed_count);
        }
    } /* omp parallel */

    if( consumed != NULL )
    {
        *consumed = (int)consumed_count;
    }

    if( acceptance_ratio != NULL )
    {
        /* *acceptance_ratio = ((double) count) / consumed_count; */
        *acceptance_ratio = CCOUNTER_DIV(count, consumed_count);
    }

    return static_cast<int>(getcount);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值