训练的过程其他方法的训练大致一样,首先是准备正样本,负样本,然后交由训练程序进行训练。
Opencv里面自带的Cascade训练器在准备数据的时候有点不一样,它要求将正样本图片写入到一个vec二进制文件中(这应该是为了在训练的时候方便并行运算),opencv提供了一个程序opencv_createsamples来生成vec文件,使用该程序需要按下面的格式准备好正负样本数据。
正样本和负样本均放在一个文件夹下,结构如下:
负样本文件夹下面有一个文件夹和一个bg.txt,存放的数据如下
/img
img1.jpg
img2.jpg
bg.txt
Bg.txt里面的数据如下
img/img1.jpg
img/img2.jpg
正样本文件夹下面有一个文件夹和一个pos.txt,存放的数据如下
/img
img1.jpg
img2.jpg
pos.txt
pos.txt除了存放图片名外,还存放了图像中目标的boundingbox的Rect,内容如下
img/img1.jpg 1 140 100 45 45
img/img2.jpg 2 100 200 50 50 50 30 25 25
文件名之后跟的是boundingbox的数目,后面就是对应的Rect
准备好这些数据之后,再执行opencv_createsamples生成vec文件,下面是一个使用示例:
将数据文件夹全部都放在e:/dataset下的文件夹中,如下图
然后执行命令
opencv_createsamples -vec e:/dataset/posImgData164_24.vec -bg e:/dataset/bg.txt -info e:/dataset/pos.txt -num 1648 -w 164 -h 24 -show
即会在e:/dataset文件夹下生成posImgData164_24.vec文件
按上面的要求准备好正负样本之后,就可以使用opencv中自带的opencv_createsamples来创建vec文件。
先给出一个使用示例:
opencv_traincascade -data e:/dataset -vec e:/dataset/posImgData164_24.vec -bg e:/dataset/bg.txt -numNeg 1111 -numPos 1400 -numStages 15 -precalcValBufSize 500 -precalcIdxBufSize 500 -stageType BOOST -featureType LBP -w 164 -h 24
上面的大部分参数的意思都是很明显的,不清楚的看下wiki也很容易理解。其中需要注意的-numPos,-w,-h,-featureType这几项。
-numPos
使用的正样本的个数,这里传入的数值必须小于opencv_createsample中生成vec时使用的样本个数,一个比较合理的数字是numPos = numSample*0.9,具体可以参见stackoverflow的这个链接,假如使用的-numPos参数值等于numSample,则在stage2的时候训练程序会崩溃。
-w
必须与opencv_createsample中使用的-w值一致,并且-w和-h的比例必须符合真实目标的比例
-h
必须与opencv_createsample中使用的-h值一致,并且-w和-h的比例必须符合真实目标的比例
-featureType
使用的特征类型,有HAAR和LBP两种类型,但是HAAR训练非常非常的慢,而LBP则相对快很多,因为HAAR需要浮点运算,精度自然比LBP更高,但是LBP的效果也基本能达到HAAR的效果,推荐使用LBP
下图是训练过程中的截图
另:-w和-h的大小对训练时间的影响非常大,我测试了两个不同尺寸下的训练,分别是Size(100,15)和Size(164,24),后者所用的时间至少是前者的2-3倍。
我使用了1648个正样本和1111个负样本进行训练,测试发现检测的效果还是挺不错~