icvGetTrainingDataCallback源码详细分析

来源:互联网 发布:2007-2017年的网络热词 编辑:程序博客网 时间:2024/06/03 19:44

cvUsedata的内容请参考我的另外一篇博文http://blog.csdn.net/ding977921830/article/details/46868313。转载请注明本博网址http://blog.csdn.net/ding977921830/article/details/46867757。


/**函数icvGetTrainingDataCallback介绍*功能:计算特征值,具体来说也就是,根据训练样本信息和特征信息,对所有样本计算特征编号从first开始的num个特征,并保存到mat里。*输入:*CvMat* mat矩阵样本总数个行,num个列。保存每个样本的num个特征值。*First:特征类型编号的开始处*Num:要计算的特征类型个数。*Userdata:训练样本信息和特征信息,包括积分矩阵和权重、特征模板等信息。*输出:*CvMat* mat矩阵样本总数个行,num个列。保存每个样本的num个特征值。*部分内容参考http://www.opencvchina.com/thread-200-1-1.html。 */staticvoid icvGetTrainingDataCallback( CvMat* mat, CvMat* sampleIdx, CvMat*,                                 int first, int num, void* userdata ){    int i = 0;    int j = 0;    float val = 0.0F;    float normfactor = 0.0F;    CvHaarTrainingData* training_data;  //存储训练样本信息    CvIntHaarFeatures* haar_features;   //存储特征信息#ifdef CV_COL_ARRANGEMENT    assert( mat->rows >= num );#else    assert( mat->cols >= num );#endif//userdata = cvUserdata( data, haarFeatures )//userdata包含了参与训练的积分图和特征,其指针应该是用于回调的用户参数    training_data = ((CvUserdata*) userdata)->trainingData;    haar_features = ((CvUserdata*) userdata)->haarFeatures;    if( sampleIdx == NULL )                                      //当sampleIdx为空时,需要的训练样本数量以mat的大小为准    {        int num_samples;#ifdef CV_COL_ARRANGEMENT        num_samples = mat->cols;#else        num_samples = mat->rows;#endif         for( i = 0; i < num_samples; i++ )                        //遍历所有样本        {            for( j = 0; j < num; j++ )                            //遍历从first开始的num个特征            {   //根据积分图来计算特征的特征值,我认为本质上是根据训练样本信息和特征信息来共同计算                val = cvEvalFastHaarFeature(                        ( haar_features->fastfeature                            + first + j ),                       //确定是计算的哪个特征,也就是第first+j个特征                        (sum_type*) (training_data->sum.data.ptr                            + i * training_data->sum.step),      //因为每个图片的积分图是按行排列的,所以第i个样本的积分图要这样计算                        (sum_type*) (training_data->tilted.data.ptr                            + i * training_data->tilted.step) );                normfactor = training_data->normfactor.data.fl[i];                val = ( normfactor == 0.0F ) ? 0.0F : (val / normfactor);//根据缩放因子来调整特征值的大小#ifdef CV_COL_ARRANGEMENT                CV_MAT_ELEM( *mat, float, j, i ) = val;          //根据是按行排列还是按列排列来存储计算好的特征值val#else                CV_MAT_ELEM( *mat, float, i, j ) = val;#endif            }        }    }    else                                                        //当sampleIdx不为空时,需要的训练样本数量以sampleIdx中的信息为准    {        uchar* idxdata = NULL;        size_t step    = 0;        int    numidx  = 0;        int    idx     = 0;        assert( CV_MAT_TYPE( sampleIdx->type ) == CV_32FC1 );        idxdata = sampleIdx->data.ptr;                         //把sampleIdx中样本的数据信息指向idxdata        if( sampleIdx->rows == 1 )                             //根据sampleIdx是否为一行来确定训练样本的数量和一个样本所占的步长step        {            step = sizeof( float );            numidx = sampleIdx->cols;        }        else        {            step = sampleIdx->step;            numidx = sampleIdx->rows;        }        for( i = 0; i < numidx; i++ )        {            for( j = 0; j < num; j++ )            {                idx = (int)( *((float*) (idxdata + i * step)) );                /*这里与上面求val不同的是,需要求一个idx,也就是需要知道是要求的第几个训练样本序号,因为在sampleIdx中训练样本并不一定是按顺                  序排列的,但是在计算好的积分图中,所有训练样本的积分图都是严格排列的。那么,我们要计算的第numidx个样本的第j个特征的特征值                  就需要先求出它在积分图中是第idx个样本的序号*/                 val = cvEvalFastHaarFeature(                        ( haar_features->fastfeature                            + first + j ),                        (sum_type*) (training_data->sum.data.ptr                            + idx * training_data->sum.step),                        (sum_type*) (training_data->tilted.data.ptr                            + idx * training_data->tilted.step) );                normfactor = training_data->normfactor.data.fl[idx];                val = ( normfactor == 0.0F ) ? 0.0F : (val / normfactor);#ifdef CV_COL_ARRANGEMENT                CV_MAT_ELEM( *mat, float, j, idx ) = val;#else                CV_MAT_ELEM( *mat, float, idx, j ) = val;#endif            }        }    }#if 0 /*def CV_VERBOSE*/    if( first % 5000 == 0 )    {        fprintf( stderr, "%3d%%\r", (int) (100.0 * first /            haar_features->count) );        fflush( stderr );    }#endif /* CV_VERBOSE */}


0 0
原创粉丝点击