opencv源码分析:icvCreateCARTStageClassifier之二(转载)


本文转自:http://blog.sina.com.cn/s/blog_5f853eb10100sdgn.html,在我博文中有另一篇文章,对icvCreateCARTStageClassifier介绍更为详细,如下http://blog.csdn.net/ding977921830/article/details/46442805

static
CvIntHaarClassifier* icvCreateCARTStageClassifier( CvHaarTrainingData* data,
CvMat* sampleIdx,
CvIntHaarFeatures* haarFeatures,
float minhitrate,
float maxfalsealarm,
int symmetric,
float weightfraction,
int numsplits,
CvBoostType boosttype,
CvStumpError stumperror,
int maxsplits )
int num_splits;
//N,是弱分类器的序号
//SMP由weightfraction决定,表示通过剔除小权值的样本后与总体样本数的%比值,
//weightfraction会改变参与下一个弱分类器的样本数量,即大权值样本
//考虑AdaBoost算法,权值更新的时候一般正确分类的权值会乘一个因子,应该对应权值会变小,这样是否会减少参与训练的正样本数?
//由于函数cvTrimWeights内部与门限相同的权值会被保留,减少的数目有限,(考虑一种极端情况,正确分类的都被踢除掉)
//F表示symmetric环境下奇数弱分类器,如果考虑是从0计数,则应该是第偶数个弱分类器,是否指示采用对称特征???

#ifdef CV_VERBOSE
printf( "+----+----+-+---------+---------+---------+---------+\n" );
printf( "| N |%%SMP|F| ST.THR | HR | FA | EXP. ERR|\n" );
printf( "+----+----+-+---------+---------+---------+---------+\n" );
#endif

//userdata包含了参与训练的积分图和特征,其指针应该是用于回调的用户参数
userdata = cvUserdata( data, haarFeatures );

//权值只有在LB这样的boosttype中起作用icvBoostStartTrainingLB。
//这里讨论非LB情况,函数根据cls值计算参与训练特征的weakTrainVals,weakTrainVals或为+1或为-1
trainer = cvBoostStartTraining( &data->cls, weakTrainVals, &data->weights,
sampleIdx, boosttype );

乎剔除小权值的特征,将大权值的index放到trimmedIdx数据结构中
trimmedIdx = cvTrimWeights( &data->weights, sampleIdx, weightfraction );
numtrimmed = (trimmedIdx) ? MAX( trimmedIdx->rows, trimmedIdx->cols ) : m;

//data->valcache有预计算特征值
//flags是CV_COL_SAMPLE或CV_ROW_SAMPLE
//weakTrainVals?
//
//得到对称特征
if( classifier->feature[i].desc[0] == 'h' )

{//倾斜
int tmp = 0;




//计算各对称特征的特征值
for( j = 0; j < numtrimmed; j++ )

/调用icvEvalCARTHaarClassifier函数计算训练出来的弱分类器对于所有参与训练的样本的特征值
eval.data.fl[idx] = classifier->eval_r( (CvIntHaarClassifier*) classifier,
(sum_type*) (data->sum.data.ptr + idx * data->sum.step),
(sum_type*) (data->tilted.data.ptr + idx * data->tilted.step),
data->normfactor.data.fl[idx] );

//这里应该是更新各个样本的weight
alpha = cvBoostNextWeakClassifier( &eval, &data->cls, weakTrainVals,
&data->weights, trainer );

//统计正样本数量,并且计算出正样本的对于弱分类器的特征值(一个弱分类器对应一个特征)
//icvEvalCARTHaarClassifier中的left right是否是考虑多特征情况下,按照一定顺序编号
//找到最适合的特征值返回
eval.data.fl[numpos] = 0.0F;
for( j = 0; j < seq->total; j++ )
{
classifier = *((CvCARTHaarClassifier**) cvGetSeqElem( seq, j ));
eval.data.fl[numpos] += classifier->eval_r(
(CvIntHaarClassifier*) classifier,
(sum_type*) (data->sum.data.ptr + idx * data->sum.step),
(sum_type*) (data->tilted.data.ptr + idx * data->tilted.step),
data->normfactor.data.fl[idx] );
}

//根据检测率取门限,通过该门限获得虚警率
threshold = eval.data.fl[(int) ((1.0F - minhitrate) * numpos)];


CvClassifier* cvCreateCARTClassifier( CvMat* trainData,
//包含每个样本预计算的特征的特征值,按特征值升序排列的索引数组在trainParams的sortedIdx中
int flags,
CvMat* trainClasses,//+1,-1
CvMat* typeMask,
CvMat* missedMeasurementsMask,
CvMat* compIdx,
CvMat* sampleIdx,//如果不为NULL,样本的序,按权值升序排列
CvMat* weights,//样本权值
CvClassifierTrainParams* trainParams )

CvClassifier* cvCreateMTStumpClassifier( CvMat* trainData,//预先计算的特征值
int flags,
CvMat* trainClasses,//样本分类+1或者-1
CvMat* typeMask,
CvMat* missedMeasurementsMask,
CvMat* compIdx,
CvMat* sampleIdx,//剔除小权值样本后的序号数组
CvMat* weights,//样本权值
CvClassifierTrainParams* trainParams )

//datan为预计算特征数,如果能得到新的特征(getTrainData!=NULL)则n应该为所有能够得到的特征数,n肯定大于等于datan
//当在进行对称训练的时候cvCreateMTStumpClassifier中的getTrainData为NULL,此时为训练剩下的特征数
assert( datan <= n );
//m为所有可能参与训练的样本数,如果剔除了小权值样本,则sampleIdx!=NULL,此时为l为实际参与训练的样本数,
//按照权值对样本排序产生sampleIdx与按照特征值对样本排序产生sortedata
if( sampleIdx != NULL )

//filter!=NULL表示剔除小权值样本并且样本按照特特征值排序
if( filter != NULL || sortedn < n ) 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值