icvGetTrainingDataCallback源码详细分析
2015-07-13 21:50
489 查看
cvUsedata的内容请参考我的另外一篇博文/article/9786789.html。转载请注明本博网址/article/9786787.html。
/* *函数icvGetTrainingDataCallback介绍 *功能:计算特征值,具体来说也就是,根据训练样本信息和特征信息,对所有样本计算特征编号从first开始的num个特征,并保存到mat里。 *输入: *CvMat* mat矩阵样本总数个行,num个列。保存每个样本的num个特征值。 *First:特征类型编号的开始处 *Num:要计算的特征类型个数。 *Userdata:训练样本信息和特征信息,包括积分矩阵和权重、特征模板等信息。 *输出: *CvMat* mat矩阵样本总数个行,num个列。保存每个样本的num个特征值。 *部分内容参考http://www.opencvchina.com/thread-200-1-1.html。 */ static void 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 */ }
相关文章推荐
- icvCreateHaarTrainingData源码详细分析
- [LeetCode] Factorial Trailing Zeroes
- Project Euler:Problem 60 Prime pair sets
- LightOJ 1070 Algebraic Problem (推导+矩阵快速幂)
- OC 基础之----属性
- CPaintDC 、CWindowDC、 CClientDC、 CDC的区别与联系
- Swiper使用方法(向前和向后按钮在swiper-container外面)
- SonarQube安装完后出现SonarQube is under maintenance. Please check back later.
- LOJ 1070 - Algebraic Problem(矩阵快速幂啊)
- 【转载】Foxmail 小技巧 25则 (转载)
- POJ 3691 DNA repair 基于AC自己主动机DP
- 人工智能计算器AI Calculator 3.3.0 详细破解思路&教程
- 在rails中pluck和select和collect区别
- installation error: unknown failure
- copy, retain, assign , readonly , readwrite,strong,weak,nonatomic整理
- HD 1151Air Raid
- LightOJ 1070 - Algebraic Problem 矩阵快速幂
- ubuntu 下配置发送邮件(sendmail/msmtp+mtt)
- Kafka设计解析(三):Kafka High Availability (下)
- Kafka设计解析(二):Kafka High Availability (上)