haar training

 opencv_createsamples -info pos.txt -vec pos.vec -bg neg.txt -w 20 -h 20 -num 2706
 
 opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 1000 -numNeg 2000 -numStages 6 -precalcValbufSize 200 -precalcdxBufSize 1000 -featureType LBP -w 20 -h 20





首先,需要说明的是,OpenCV自带的haar training提取的特征是haar特征(具体请参考我的另一篇关于haar特征的文章:http://blog.csdn.net/carson2005/article/details/8094699 ),分类器是AdaBoost级联分类器(如需了解Adaboost算法,请参考我的另一篇文章:http://blog.csdn.net/carson2005/article/details/8130557 )。所谓的级联分类器,就是将若干的简单的分量分类器(可以理解为一般的普通分类器)依次串联起来,最终的检测分类结果,要依次通过所有的分量分类器才能算是一个有效的检测分类结果。否则,就认为当前检测区域内没有我们需要找的目标。

利用OpenCV自带的haar training程序训练一个分类器,需要经过以下几个步骤:

(1)收集训练样本:

        训练样本包括正样本和负样本。正样本,通俗点说,就是图片中只有你需要的目标。而负样本的图片只要其中不含有目标就可以了。但需要说明的是,负样本也并非随便选取的。例如,你需要检测的目标是汽车,那么正样本就应该是仅仅含有汽车的图片,而负样本显然不能是一些包含天空的,海洋的,风景的图片。因为你最终训练分类器的目的是检测汽车,而汽车应该出现在马路上。也就是说,分类器最终检测的图片应该是那些包含马路,交通标志,建筑物,广告牌,汽车,摩托车,三轮车,行人,自行车等在内的图片。很明显,这里的负样本应该是包含摩托车、三轮车、自行车、行人、路面、灌木丛、花草、交通标志、广告牌等。

        另外,需要提醒的是,adaboost方法也是机器学习中的一个经典算法,而机器学习算法的前提条件是,测试样本和训练样本独立同分布。所谓的独立同分布,可以简单理解为:训练样本要和最终的应用场合非常接近或者一致。否则,基于机器学习的算法并不能保证算法的有效性。此外,足够的训练样本(至少得几千张正样本、几千张负样本)也是保证训练算法有效性的一个前提条件。

        这里,假设所有的正样本都放在f:/pos文件夹下,所有的负样本都放在f:/neg文件夹下;

(2)对所有的正样本进行尺寸归一化:

上一步收集到的正样本,有很多的尺寸大小,有的是200*300,有的是500*800...尺寸归一化的目的,就是把所有的图片都缩放到同一大小。比如,都缩放到50*60的大小。

(3)生成正样本描述文件:

        所谓的正样本描述文件,其实就是一个文本文件,只不过,很多人喜欢将这个文件的后缀改成.dat而已。正样本描述文件中的内容包括:文件名 目标个数 目标在图片中的位置(x,y,width,height

典型的正样本描述文件如下所示:

0.jpg 1 0 0 30 40

1.jpg 1 0 0 30 40

2.jpg 1 0 0 30 40

.....

        不难发现,正样本描述文件中,每一个正样本占一行,每一行以正样本图片开头,后面紧跟着该图片中正样本的数量(通常为1),以及正样本在图片中的位置

        假如,f:\pos文件夹下有5000个正样本图片,每个图片中仅有一个目标。那么,我们可以写程序(遍历文件夹中的所有图片文件,将文件名写入到文件中,将正样本在图片中的位置,大小都写入文件中)生成一个pos.dat文件作为正样本描述文件。

(4)创建正样本vec文件

    由于haarTraining训练的时候需要输入的正样本是vec文件,所以需要使用createsamples程序来将正样本转换为vec文件。

打开OpenCV安装目录下bin文件夹里面的名为createSamples(新版本的OpenCV里面改名为opencv_createSamples)的可执行程序。需要提醒的是,该程序应该通过命令行启动(可以参考我的另一篇博客:http://blog.csdn.net/carson2005/article/details/6704589 )。并设置正样本所在的路径以及生成的正样本文件保存路劲(例如:f:\pos\pos.vec)。

Createsamples程序的命令行参数:
命令行参数:
-vec <vec_file_name>
训练好的正样本的输出文件名。
-img<image_file_name>
源目标图片(例如:一个公司图标)
-bg<background_file_name>
背景描述文件。
-num<number_of_samples>
要产生的正样本的数量,和正样本图片数目相同。
-bgcolor<background_color>
背景色(假定当前图片为灰度图)。背景色制定了透明色。对于压缩图片,颜色方差量由bgthresh参数来指定。则在bgcolor-bgthresh和bgcolor+bgthresh中间的像素被认为是透明的。
-bgthresh<background_color_threshold>
-inv
如果指定,颜色会反色
-randinv
如果指定,颜色会任意反色
-maxidev<max_intensity_deviation>
背景色最大的偏离度。
-maxangel<max_x_rotation_angle>
-maxangle<max_y_rotation_angle>,
-maxzangle<max_x_rotation_angle>
最大旋转角度,以弧度为单位。
-show
如果指定,每个样本会被显示出来,按下"esc"会关闭这一开关,即不显示样本图片,而创建过程继续。这是个有用的debug选项。
-w<sample_width>
输出样本的宽度(以像素为单位)
-h《sample_height》
输出样本的高度,以像素为单位。

(5) 创建负样本描述文件

在保存负样本的文件夹下生成一个负样本描述文件,具体步骤同(3),此处不再赘叙; 

(6)进行样本训练

    该步骤通过调用OpenCV\bin目录下的haartraining程序(新版本的opencv改名为opencv_haartraining)来完成。其中,Haartraining的命令行参数为:
-data<dir_name>
存放训练好的分类器的路径名。
-vec<vec_file_name>
正样本文件名(由trainingssamples程序或者由其他的方法创建的)
-bg<background_file_name>
背景描述文件。
-npos<number_of_positive_samples>,
-nneg<number_of_negative_samples>
用来训练每一个分类器阶段的正/负样本。合理的值是:nPos = 7000;nNeg = 3000
-nstages<number_of_stages>
训练的级联分类器层数。
-nsplits<number_of_splits>
决定用于阶段分类器的弱分类器。如果1,则一个简单的stump classifier被使用。如果是2或者更多,则带有number_of_splits个内部节点的CART分类器被使用。
-mem<memory_in_MB>
预先计算的以MB为单位的可用内存。内存越大则训练的速度越快。
-sym(default)
-nonsym
指定训练的目标对象是否垂直对称。垂直对称提高目标的训练速度。例如,正面部是垂直对称的。
-minhitrate《min_hit_rate》
每个阶段分类器需要的最小的命中率。总的命中率为min_hit_rate的number_of_stages次方。
-maxfalsealarm<max_false_alarm_rate>
没有阶段分类器的最大错误报警率。总的错误警告率为max_false_alarm_rate的number_of_stages次方。
-weighttrimming<weight_trimming>
指定是否使用权修正和使用多大的权修正。一个基本的选择是0.9
-eqw
-mode<basic(default)|core|all>
选择用来训练的haar特征集的种类。basic仅仅使用垂直特征。all使用垂直和45度角旋转特征。
-w《sample_width》
-h《sample_height》
训练样本的尺寸,(以像素为单位)。必须和训练样本创建的尺寸相同。
一个训练分类器的例子:
"D:\Program Files\OpenCV\bin\haartraining.exe"   -data data\cascade -vec data\pos.vec -bg negdata\negdata.dat -npos 49 -nneg 49 -mem 200 -mode ALL -w 20 -h 20

训练结束后,会在目录data下生成一些子目录,即为训练好的分类器。

(7) 生成xml文件

上一步在进行haartraining的时候,会在data目录下生成一些目录及txt文件,我们需要调用opencv\bin\haarconv.exe将这些txt文件转换为xml文件,也就是所谓的分类器。

    至此,分类器的训练工作已完成。剩下的,就是在程序中加载xml文件,并调用相应的函数接口来实现分类检测的作用了。


最近在使用opencv里的haar+adaboost做检测,其实早在一年前的无锡已经看过用它做车徽检测,然后再做识别(大众,奔驰...)。这次终于要自己动手做了,网上有很多这方面的资料,感谢大家分享他们的经验。重复的东西这里就不再赘述了,只简单的补充几个大家容易疏忽的东西。

step1.首先是准备正负样本,正样本好说,打了标签,解析xml文件,然后做点小旋转就可以用了

       负样本就复杂了,第一点要求是不能包含正样本,在我的应用场景中还需要尽可能多的提供场景的背景图,而不是网上所说的从网络上找一些不相干的图像,这些图像加进来促进作用也不大,因为我的场景中根本不会出现它们,但也不会出现负作用。第二是负样本数目尽可能的多,但这个还是量力而行吧,毕竟纯体力活,没多大的乐趣在里面。补充一句,样本的目录结构很简单,只要包含pos和neg两个子文件夹和opencv_haartraining.exe,

opencv_createsamples.exe,convert_cascade.exe等几个可执行程序,比如face-->face\train  face\test

step2.生成正负样本描述文件,描述文件保存在face目录下与train test平级,命令如下:

打开cmd  分别cd 到正负样本目录

                        cd negdir  
                         dir /b > negative.data
                         cd posdir
                         dir /b > positive.data

生成的描述文件当然还要替换才能够最终使用 对于positive.data只要在最后把jpg ->jpg 1 0 0 20 20,这里注意最好是在word下面替换好,再拷到txt下,速度快些,1 0 0 20 20的意思是这幅图片包含一个正样本目标,矩形区域为 0 0 20 20这里由于我们的正样本只有一个目标,而且已经大小归一化为20x20的图像,所以这里参数这么定义,而且opencv的坐标是从0开始的,我开始想过是不是要写成 0 0 19 19,本来看过网上一篇文章错写成1 1 20 20也没出错。正负样本的.data文件都要做的一件事是:打开.data文件,替换掉不是图片的行,比如positive.data negative.data.对于正样本,由于大小一致,为了避免过多的IO操作,可以生成vec文件,cd 到face目录 直接cd ..即可 然后输入命令:

opencv_createsamples.exe -info "pos/positive.data" -vec pos.vec -num 7097 -w 20 -h 20

其中-num指定你的正样本数目 -w 图像宽度,-h图像高度    生成描述文件

step3:经过上一步,准备工作已经做好,可以开始运行训练了,输入命令:

opencv_haartraining.exe -data haarcascade7097 -vec pos7097.vec -bg neg/negative.data -nstages 20 -nsplits 2 -minhitrate 0.999 -maxfalsealarm 0.5 -npos 7097 -nneg 7097 -w 20 -h 20  -mem 1024 -mode ALL

解释下各个参数的含义  -data 指定生成的文件目录, -vec vec文件名, -bg 负样本描述文件路径, -nstage 20 指定训练层数,推荐15~20,层数越高,耗时越长。-nsplits 分裂子节点数目,选取默认值 2 -minhitrate 最小命中率,即训练目标准确度。-maxfalsealarm最大虚警(误检率),每一层训练到这个值小于0.5时训练结束,进入下一层训练,-npos 正样本数目,-nneg  负样本数目 这个值可以设置大于真正的负样本图像数目,程序可以自动从负样本图像中切割出和正样本大小一致的 -nneg张图 这个参数一半设置为正样本数目的1~3倍, -w -h意思很明确, -mem 程序可使用的内存,这个设置为256即可,实际运行时根本就不怎么耗内存。 -mode ALL指定haar特征的类型数目

step3:然后就是等待了 ,我用上面的代码,负样本数目为2830,训练了一周,当然如果实在等不住了,中间结果也可以生成xml文件,命令如下:

/*转换为xml*/
convert_cascade.exe --size="20x20" ..\cascade ..\cascade.xml

ps:还有一个小建议:大家最好自己编译opencv,这样就可以vs--->project-->properties-->c++-->language-->OpenMp support 开启openmp选项,编译出来的exe就是多核并行的,提升速度很重要,我上面说的一周就是openmp加速在8核,3.2Ghz的服务器上跑的。

用别人的总有一天要还,想要最快,不会出错,最好自己写 haar+ adaboost ,这样选取负样本(最耗时的部分)的程序也可以并行加速了。waiting for me

最后添加几幅运行时图片:

这个是我跑到19层的结果,其中BACKGROUNG PROCESSING TIME 是负样本切割时间 很长很长

N 为训练层数 %SMP 样本占总样本个数 ST.THR 阈值,HR 击中率, FA  虚警 EXP.ERR 经验错误率

这个是指定的haarcasade7079 文件中生成的每一层文件的文件夹

文件和文件中的内容,然后使用

convert_cascade.exe --size="20x20" ..\cascade ..\cascade.xml就可以生成xml文件

祝大家玩的开心 有问题可以发信到gjtjx@163.com,只回复本文所包含的问题,

其他问题可以参看Opencv自带的doc 中haar训练的问题FAQ,还是参看英文原版的东西

节约时间.

最近使用OpenCV训练Haar like+Adaboost分类器,查阅了一些资料,这些资料对训练过程陈述的很详细,但是缺少一些细节,偶然看到了一篇英文资料,觉得很好,简单翻译了自己觉得有用的部分。

原文链接:FAQ:OpenCV Haartraining

关于正样本图片

1、 I have  positive images, how create vec file of positive samples?
     有了正样本图片,如果生成对应的vec文件?
 OpenCV中有一个工具可以生成vec文件,在安装目录C:\Program Files\OpenCV\apps\HaarTraining\src createsamples.cpp。
使用方法:
createsamples -info positive_description.txt -vec samples.vec -w 20 -h 20
2、What’s positive description file?
    正样本描述文件是什么?
以人脸为例,在正样本的图片中,可能有数个人脸,每个人脸的位置可以用一个矩形框来表示:矩形左上角是x, y,宽、高是width,height。所以我们可以写一个文件来表示每张图片中的每个人脸如下:
positive_image_name  num_of_objects x y width height x y width height …
像这样,指定了正样本中需要检测目标位置的文件就叫正样本描述文件。在生成vec文件时,添加到vec文件中的是需要检测的目标,而不是整张图片。本质上来讲,vec文件用来加速机器学习。
3、Do I always need description file, even if I have only one object on a image?
    描述文件是不是必须的?如果正样本图片中只包含一个需要检测的目标时呢?
    使用createsamples工具时,描述文件是必须的。如果正样本图片中只有一个被检测物,矩形框就是整幅图片。你也可以自己编写工具来生成vec文件。

4、Should lightning conditions and background be various on positive images?
    正样本图片中的关照和背景的变化是否需要很大?
是的,而且这很重要。在正样本图片中,除了被检测目标,剩下的就是背景。应该尝试用随机噪声来填充背景,避免没有变化的背景。
5、How much background should be on positive image?
    在正样本图片中,应该有多少背景?
如果在正样本图片中,背景相对被检测目标来说,所占像素很多的话,会产生不好的效果,因为haartraining(haar训练 程序)会把背景当作被检测物的特征记下来。如果在正样本图片中根本没有背景像素,也会造成训练的结果不好。在正样本图片中有很少背景是比较理想的。
6、What’ s  -w and -h should I put in createsamples? Should it be always square?
    在使用createsamples工具时,-w -h参数应该设定为多少?是不是一定要设定成正方向?
-w -h参数的值应该根据希望检测目标的比例来设定。但是,使用生成的分类器来进行检测时,比-w -h所确定的形状小的目标不会被检测到。在检测脸时,通常使用的值是24*24,20*20。你也可以使用24*20,20*24等等类似的值。

7、Errors during vec file generation: Incorrect size of input array, 0 kb vec file,
    生成vec文件时报错:输入矩阵大小错误,vec文件0kb
-首先,检测描述文件:例如正样本图片的路径是否正确
-描述文件末尾不能有空行
-正样本图片的分辨率不能小于设置的-w -h参数
-检查正样本图片是否可用,是否被占用
-正样本图片格式是否正确。支持的格式有jpeg、bmp、ppm。

关于负样本图片

1、What negative images should I take?
    应该使用什么样的负样本图片?
可是使用任何OpenCV支持的图片格式,而且其中不能包含被检测目标。负样本图片应该变化很大,多种多样。

2、Should negative images have the same size?
    负样本图片是否需要缩放到同样大小?
不需要,但是负样本图片不能小于使用createsamples工具生成vec文件时设定的-w -h参数。

3、What’s description file for negative image?
    负样本的描述文件是什么样的?
负样本的描述文件是一个简单的文本文件,通常命名为negative.dat。它指定了负样本图片,并且不能有空行(包括末尾)。例如:
     image_name1.jpg
    image_name2.jpg
4、How many negative/positive image should I take?
    通常需要使用多少正/负样本图片?
这往往根据你的需求来确定。例如,对cascades来说,需要有1000个正样本和2000个负样本。
比较好的比例关系是 positive : negative = 1:2,但这并不是硬性规定。我推荐先使用少量的样本来尝试产生 cascades,然后再扩大样本。

关于haartraining.exe的使用

1、Example of launching
    使用haartraining的示例
vec文件为samples.vec,负样本描述文件为negative.dat。使用haartraining.exe的方法如下:
 haartraining -data haarcascade -vec samples.vec -bg negatives.dat -nstages 20  -minhitrate 0.999 -maxfalsealarm 0.5 -npos 1000 -nneg 2000 -w 20 -h 20 -nonsym -mem 1024

-data haarcascade  
 
       生成的xml文件目录为haarcascade 

-vec   samples.vec         
    
vec文件为samples.vec
-bg   negatives.dat          
  
   负样本描述文件为negatives.dat
-nstages 20            
  
           分类器的级联层数
 -minhitrate 0.999               每一层的最低正确检测率99.9%
-maxfalsealarm 0.5             最大 错误接受 率50%
-npos 1000 -nneg 2000     正、负样本数
-w  20 -h 20            
  
             -w -h参数与生成vec文件时设置的数值相同

2、What’ s falsealarm and hitrate of stage?
  stage的 ”错误接受率“ 和 ”正确检测率“ 是什么?
要了解这两个参数,需要查阅adaboost算法中关于强分类器的理论。stage就是强分类器。简单来说:

如果有1000个正样本,你希望检测系统能检测出其中的900个,期望的”正确检测率“就是900/1000 = 0.9。通常将 minhitrate设置为0.999;
如果有1000个负样本,如果检测系统错误的将其中490当作了检测目标,”错误接受率“就是490/1000 = 0.49。通常false alram设置为0.5。
3、Are falsealarm and hitrate depend on each other?
    错误接受率和正确检测率之间有关系吗?
它们之间是有关系的,不能这样设置:min hitrate = 1.0,   max falsealarm  
= 0.0。
首先,系统根据期望的hitrate创建分类器,然后计算分类器的falsealarm。如果falsealarm比设置的maxfalsealarm高,系统会拒绝这个分类器,开始创建新的分类器。所以在训练过程中,你可以看到类似下面的信息:

N |%SMP|F| ST.THR | HR | FA | EXP. ERR|
+—-+—-+-+———+———+———+———+
| 0 |25%|-|-1423.312590| 1.000000| 1.000000| 0.876272|
HR – hitrate
FA – falsealarm
4、What’s falsealarm and hitrate of whole cascade?
    整个级联分类器的falsealarm和hitrate是多少?
False alarm of cascade = false alarm of  stage 1* false alarm of  stage 2* …
Hit rate = hitrate of  stage 1 * hitrate of stage 2* …
5、How many stages should be used?
    级联分类器应该被设定为多少层?
通常,14-25层就足够了。
如果层数过多,分类器的false alarm就更小,但是产生级联分类器的时间更长。
如果层数过多,分类器的hitrate就更小。(原因见4)
如果层数过多,检测速度更慢。
如果正、负样本较少,层数没必要设置很多。
6、What’s weighttrimming, eqw, bt, nonsym options?
     weighttrimming、eqw、bt、 nonsym  选项表示什么?
nonsym                
如果检测目标不是x或者y轴对称的,使用-nonsym选项。系统默认使用-sym选项
eqw             
  
      — 如果正负样本数目不相等,不要使用此选项
weighttrimming — 计算最优化选项。能减一点计算事件,但是质量也会降低
bt                       
  
— 使用哪种adaboost算法:Real AB,Gentle AB等
7、What’s  minpos, nsplits, maxtreesplits options?
    minpos、nsplits、nsplits、maxtreesplits选项是什么?
nsplits                  ——  
  树节点数的最小值
maxtreesplits     ——     树节点数的最大值
minpos                 ——  
 训练过程中,节点可使用的正样本数目。正样本根据节点被分类,通常来说,minpos不小于npos / nsplits

8、   Errors and stranges during haartraining!
    训练过程中的错误!
①Error (valid only for Discrete and Real AdaBoost): misclass
这是警告而不是错误。D and R Adaboost算法有一些特别的选项。
②控制台上都是类似下面的提示 : | 1000 |25%|-|-1423.312590| 1.000000| 1.000000| 0.876272| 
训练进入了循环,重新启动训练。正常情况下,第一列应小于100

③cvAlloc fails. Out of memory
负样本太多或者vec文件太大,所有的图片都加载到内存,导致内存不足。
④注意-w -h参数的值与生成vec文件时的值相同
⑤注意正、负样本数目与-npos 、-nneg参数设定值相同
⑥防止dat文件(描述文件)中的空行
⑦Required leaf false alarm rate achieved. Branch training terminated
负样本图片中可能包含了被检测目标。maxfalsealarm值应该设定到0.4 - 0.5之间。

分类器xml文件

1、 During haartraining, there are txt file in haarcascade folder, how can we
get XML  from them?
    训练过程中会产生txt文件,如果根据这些文件生成xml文件?
使用convert_cascade工具:
 convert_cascade –size=”20×20″ haarcascade haarcascade.xml
其中,haarcascade 是txt文件所在目录
2、How can I test generated XML cascade?
       如何测试生成的分类器?
使用performance工具来测试,其中正样本是训练过程中未使用的图片:
performance -data haarcascade -w 20 -h 20 -info positive_description.txt -ni
performance -data haarcascade.xml -info positive_description.txt -ni

使用OpenCV和训练得到的分类器检测物体

1、Is it possible to detect rotated faces?
    能不能检测旋转过的脸?
训练一个分类器来检测旋转不同角度的人脸是不可能的。但是,可是训练出分类器来检测旋转到对应角度的人脸。可以使用选择到这一角度的人脸图片来训练出分类器。在训练分类器时,加上-mode all选项表示使用所有的特征,但是早期的OpenCV版本实现的比较差。你也可以增加自己的特征,这并不困难。
另一种方法是计算出头部的选择角度,然后根据选择角度旋转检测图片来得到正脸,这样就可以使用OpenCV自带的人脸检测期来进行检测了。
2、Is it possible to recognize gender, attention, race with  Haar features?

    使用Haar特征能否分辨出性别、注意力、种族?
我们有过尝试,但是使用OpenCV的haartraining没有成功。我们使用性别、注意力分类器。当然你可以使用Adaboost算法,但我们没有得到很好的结果。
3、Is it possible to detect faces in real time?
    能否做到实时检测人脸?
在电脑上,OpenCV自带的人脸检测器检测一幅分辨率为640*480的图片需要200ms,也就是5fps,非实时。我们可以改进检测器,做到15fps,进行实时检测。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值