opencv利用(HAAR,LBP等特征)训练自己的分类器

来源:互联网 发布:java web直播源码 编辑:程序博客网 时间:2024/05/21 08:56

Step1:准备训练样本

训练样本的准备包括正样本和负样本。

正样本就是你要检测的物体图片,比如身份证识别中的国徽。负样本原则上是国徽以外的任何物体都行,这是网上教程所说的,但是实际上,负样本是每一级级联分类器自身调参优化的依据。也就是说,单级分类器的目的是寻找一组参数,让所有的正样本都通过该级分类器,只让少数不可区分开的负样本通过,到下一级分类器的时候再增加特征数目以寻求把所有负样本都kill掉,如果无法做到kill所有负样本,就增加特征进入下一级分类器。所以负样本的选取如果没有迷惑性,训练出来的分类器可能只有1级或者2级(虽然你可能预先设定了12级,但训练还有一个终止条件,就是所有的正负样本都正确地区分开),这样的效果就不是很好。最好的方法是先选取一些负样本训练出分类器,然后使用该分类器去检测,把误判的区域做成负样本重新训练。

网上的教程对正负样本的数量以及他们之间的数量比例都有一定要求,其实OpenCV自带的引擎对正负样本的数量倒是没有硬性规定,但是如果负样本的数目不足,或者差异性太小甚至全部相同,容易卡在一个死循环里出不来(这是opencv分类器训练引擎自己代码的问题http://blog.sina.com.cn/s/blog_75e063c10100za53.html)。所以

训练样本要求:

1)灰度图!灰度图!灰度图!重要的事情说三遍!正负样本都是!不然就assert报错咯!

2)正样本大小要统一!比如30*30,不统一就报错!但是如果正样本太大的话,训练的过程就会耗时较长!负样本没有大小的要求

3)负样本最好不要重复,重复就是在做无用功

4)数量没有要求,但别太少,正样本至少50+吧,负样本应该更多,我用了200张左右

 

Step2:备齐所需文件

建一个文件夹(比如train),然后在opencv库里找到opencv_createsamples.exeopencv_haartraining.exe两个exe文件,以及相应的dll(可以把opencv的所有dll全部无脑暴力地拷进train文件夹,如opencv_core249.dll等)拷进train文件夹,然后在该文件夹里建一个neg文件夹放置负样本,pos文件夹放置正样本(文件夹命名随意哈,但是最好不要用中文名)。

 

Step3:生成正负样本描述文件

train文件夹下打开cmd,进入pos文件夹,输入dir /s/b >pos.txt,然后打开该txt,删除最后一行,把其余行的绝对路径改为相对路径,并在文件名后加上1 0 0 30 301表示一个文件,0 0表示起点,30 30表示长和宽),比如pos\guohui1.jpg 1 0 0 30 30

接着进入neg文件夹,输入dir /s/b >neg.txt,删除最后一行,把绝对路径改为相对路径,保存即可(不需要加起点长宽等信息)。

 

Step4:创建正样本特征文件

这个特征文件是用来描述正样本特征的,大小不会太大,因为正样本都是同一个物体。

step3创建的neg.txtpos.txt拷到train文件夹下(就是你放置opencv_createsamples.exe等执行文件的文件夹下),然后在该文件夹下用cmd命令行执行以下:

opencv_createsamples.exe  -vec pos.vec  -info pos.txt  -num 50  -w 30  -h 30 

解释以下几个参数-vec后面的pos.vec是你要生成的特征文件,后缀vec要对,名字可以随便取;-info pos.txt就是你刚才生成的pos.txt文件;-num是你的正样本数;-w -h是正样本的宽和高

Step5:分类器训练

train文件夹下cmd输入以下:

opencv_haartraining.exe -data xml -vec pos.vec -bg neg.txt -nstages 12 nsplits 1 -npos 45 -nneg 800 -mem 1280 -mode all -w 30 -h 30

解释以下几个参数:

-data后跟的是分类器的格式,训练后之后你会得到一个xml.xml的分类器,重命名就好啦

-vec pos.vec 这是step4生成的正样本特征文件

-bg neg.txt bg means background,就是背景描述文件,也就是你的负样本描述文件

-nstages 预先设定的分类器级数,但是如果你的负样本不给力的话,这句有跟没有一样

-nsplits 决定用于阶段分类器的弱分类器。如果1,则一个简单的stump classifier被使用。如    果是2或者更多,则带有number_of_splits个内部节点的CART分类器被使用。一    般来说,默认1就好啦

-npos  正样本的数目,这个值一定不要超过你的真实正样本的值(比如50张正样本,你就         设为45),不然就会assert报错,具体原因并不清楚,有点莫名其妙!

-nneg  负样本数目

-mem  你预先分配的内存数目,比如1280就是分配1280M的内存给分类器训练,分配的    内存越大,速度越快

-mode  分类器的模式,选择all的话就表示各个角度都能检测到,不过相应的也耗时较长

 

ATTENTION!!!!

    上述的分类器都是基于haar特征训练的,但是如果我们不想用haar特征来训练,有其他办法吗?Of course

这就是opencv_traincascade.exe,把它拷到train文件夹底下(就是放一大堆dll的那个文件夹),然后cmd输入以下:

opencv_traincascade.exe -data DATAHOG -vec pos.vec -bg neg.txt -numPos 700 -numNeg 2100 -featureType HOG -w 50 -h 55 -numStages 20

各个参数应该都和step5Haar特征分类器差不多,只是命名上会有变化!特别注意到:

-featureType 这个指令,后面可以跟HOG,LBP,HAAR三种特征!

 

比较详细的参考资料有:

http://blog.csdn.net/xidianzhimeng/article/details/10470839

http://blog.csdn.net/carson2005/article/details/8171571

阅读全文
0 0
原创粉丝点击