opencv haartraining 分析二:每级…

来源:互联网 发布:centos 解压 编辑:程序博客网 时间:2024/05/29 07:05

函数               poscount = icvGetHaarTrainingDataFromVec( training_data, 0,npos,
                   (CvIntHaarClassifier*) tcc, vecfilename, &consumed)负责从正样本集*.vec 文件中载入count(npos)个正样本。在程序第一次运行到此(即训练第一个分类器之前)时,只要正样本集中有 count 个样本,就一定能取出count 个正样本。在以后运行到此时,有可能取不到 count 个样本,因为
必须是用前面的级联强分类器((CvIntHaarClassifier*)tcc)分类为正样本(即分类正确的样本)的样本才会被取出作为下一个强分类器训练样本,具体可参考icvGetHaarTrainingData和icvEvalTreeCascadeClassifierFilter函数。

 

训练负样本,具体可参考icvGetHaarTrainingDataFromBG和icvEvalTreeCascadeClassifierFilter函数。

int icvGetHaarTrainingDataFromBG(CvHaarTrainingData* data, int first, int count,
                                 CvIntHaarClassifier* cascade, double* acceptance_ratio, const char* filename = NULL )
  传递返回值的 acceptance_ratio参数记录的是实际取出的负样本数与查询过的负样本数(如果通过前面级联stage强分类器的负样本数很少时,那么程序会循环重复读取负样本,并用thread_consumed_count计数)之比(acceptance_ratio= ((double) count) /consumed_count),也就是虚警率,用于判断已训练的级联分类器是否达到指标,若达到指标,则停止训练过程。 

 
  注意函数 icvGetHaarTrainingData中一个主要的 For 循环:
       for( i = first; i < first + count; i++ ) //共读取 count个负样本,当读取不到
                                 //这么多负样本时将出现死循环!
 
 对上面代码中的注释有必要进一步说明一下:只有当之前的强分类器对负样本集内的样本全部分类正确时才会出现死循环。因为只要有一个样本会被错分为正样本,那么通过count次扫描整个负样本集就能得到 count 个负样本,当然这 count 个负样本实际上就是一个负样本的 count个拷贝。为避免这些情况的发生,负样本集中的样本数需要足够多。
 在负样本图像大小与正样本大小完全一致时,假设最终的分类器虚警率要求是falsealarm,参加训练的负样本要求是 count个,则需要的负样本总数可计算如下: TotalCount = count /falsealarm
  以 Rainer Lienhart的文章中的一些参数为例,falsealarm=0.5^20=9.6e-07, count=3000,
则 TotalCount=3000/(0.5^20)= 3,145,728,000=31 亿。

函数 icvGetHaarTrainingDataFromBG ()负责从负样本集中载入 count个负样本。在程序第一次运行到此(即训练第一个分类器之前)时,只要负样本集中有 count 个样本,就一定能取出 count个负样本。在以后运行到此时,有可能取不到 count个样本,因为必须是用前面的级联强分类器分类为正样本的样本(即分类错误的样本)才会被取出作为下一个强分类器的负样本输入。
 

对于int icvGetHaarTrainingData( CvHaarTrainingData* data, intfirst, int count,
                           CvIntHaarClassifier* cascade,
                           CvGetHaarTrainingDataCallback callback, void* userdata,
                           int* consumed, double* acceptance_ratio )

 这个函数的解释:

这是个对于读取正负样本通用的函数,区别在于callback的调用。在这个函数中有个变量thread_getcount,表示将样本分为正样本的数目(不论这个样本是负样本还是正样本)。
  传递返回值的 Consumed 参数表示为取 count个正样本,查询过的正样本总数。对于负样本为空(null),没有返回值。 
 

0 0
原创粉丝点击