opencv中traincascade训练分类器
训练级联分类器traincascade需要OpenCV中的两个exe文件,这两个文件分别是opencv_createsamples.exe和opencv_traincascade.exe文件。
训练过程可分为以下几步:
(1)准备正负训练样本。
正样本:
正样本尺寸保持一致,建议自己写个小程序来剪裁图像实现尺寸统一。
负样本:
负样本的尺寸无需统一,负样本越多,检测结果误检率越小。
demo所检测的目标是图像中的云,其他均为背景。
准备好训练样本后,创建两个文件夹,假设为pos以及neg,分别存放正负样本,并将这两个文件夹与opencv_createsamples.exe和opencv_traincascade.exe文件放在同一目录下,如下图所示。
为防止混乱,将这些文件都在统一的文件夹”yunc”下。图1中有两个文件夹pos_new,以及neg_new,这是后续为了新加样本库所建的文件夹。因为一般需要处理的样本较多,容易搞混,如果样本很少也就用不到级联了。
(2)在DOS环境下生成正负样本描述符:
首先进入到正负样本所在的目录。若处于正样本所在目录,输入命令:dir/b>../pos.txt则生成正样本描述文件。
若处于负样本所在目录,输入命令:dir/b> ../neg.txt,则生成负样本描述文件。生成的正负样本描述文件为.txt文件,打开后可见其为一个个样本的名称,然后将正负样本作以下处理:
对于负样本,如下图所示:
在样本名字前加上”neg/”,即为负样本所在的文件夹,所有的样本名称都要修改,修改完后把最后一行的neg.txt去掉,还有最后一行的空行去掉,切记,否则训练过程会报错。对于正样本,如下图所示:
除了在样本名字前加上其所在的文件夹名称,还要在后缀名后面加上样本描述,即样本的尺寸大小,1表示样本数为1,0 0表示的是样本左上角的坐标即为(0,0), 4 4 表示右下角的坐标。同样修改完后把最后一行的pos.txt以及空行去掉。至此,正负样本描述文件已全部处理完。
(3)生成.vec文件
生成.vec文件需要用到opencv_createsamples.exe文件,.vec文件是为后面训练分类器所准备的。在dos环境下的相对目录下键入以下命令:
opencv_createsamples.exe -vec pos.vec -info pos.txt -num 1467 -w 4 –h 4
此时可在opencv_createsamples.exe文件所在目录中看到所生成的.vec文件。
由命令行可知,-w 4 –h 4为正样本的尺寸大小,也间接说明了正样本的尺寸大小必须一致。-num为需要生成的正样本数目。对于负样本则无需生成.vec文件。接下来就要利用opencv_traincascade.exe来开始训练分类器了。
下图表示生成.vec文件成功!
(4)级联分类器的训练
在命令行键入以下命令:
opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 900 numNeg 788 -numStage 20 -precalValBufSize 300 -precalIdxBufSize 100 -featureType HAAR -w 4 -h 4 -mode ALL
便开始训练分类器了。其中各个含义现在一一来说明。
-data xml
Xml为文件夹名称,该文件夹需要自己新建,用来存放训练好的分类器。-data表示分类器所在的文件夹。
-bg numPos 900
这个是训练正样本的数目,为何这个地方不是1467呢,而创建样本时创建了1467个?这个我也不是很清楚,总之要是能看源代码就能搞清楚了。
-bg
这个很明显是负样本文件。
numNeg 788
负样本数目。
-numStage 20
训练阶数。(这个地方其实设置为20没有意义,因为级联分类器的最高训练阶数为19级)
-precalValBufSize 300
缓存大小,用于存储预先计算的特征值(feature values),单位为MB。
-precalIdxBufSize 100
缓存大小,用于存储预先计算的特征索引(feature indices),单位为MB。内存越大,训练时间越短。
-featureType HAAR
用于检测的特征为Haar特征
-mode ALL
选择训练过程中使用的Haar特征的类型。 BASIC 只使用右上特征, ALL 使用所有右上特征和45度旋转特征。
正确训练过程如下图所示:
训练完成结果如下:
训练完成后即可在yunc文件下的xml文件里找到最终训练的结果。打开xml文件夹如下图所示:
上图中的xml文件夹下便是级联分类器训练的中间过程,cascade.xml文件是训练完成的分类器。
2 云层的检测
检测过程主要通过detectMultiScale()来检测,对于该函数是如何检测的,查过很多文献和技术博客都没有一个答案。所以只能通过实验的探索其检测过程。
在opencv中只能查到其原函数的声明如下:
void detectMultiScale( const Mat& image,
CV_OUT vector<Rect>& objects,
double scaleFactor=1.1,
int minNeighbors=3,
int flags=0,
Size minSize=Size(),
Size maxSize=Size() );
其中Mat& image为输入的Mat类图像,CV_OUT vector<Rect>& objects为所检测到的目标所存放的容器,double scaleFactor=1.1以及int minNeighbors=3这两个参数比较复杂,先介绍最后三个参数,int flags=0表示检测的是Haar特征,Size minSize=Size()为检测的最小尺寸,Size maxSize=Size() )为检测的最大尺寸。
scaleFactor=1.1为多尺度检测的缩放倍数,当4*4检测到了目标,则再继续扩大检测范围。
int minNeighbors=3为在检测到的目标领域再继续检测。
吐血花了两天时间做的实验总结的,到现在没搞明白这三个的关系(scaleFactor,minNeighbors,检测最小尺度)
关于多尺度特征检测函数detectMultiScale()检测尺度表:
scaleFactor |
minNeighbors |
检测最小尺度 |
1.1 |
1 |
4 |
1.1 |
2 |
5 |
1.1 |
3 |
5 |
1.1 |
4 |
5 |
1.1 |
5 |
5 |
1.1 |
6,7,8,9 |
5 |
1.2 |
1 |
6 |
1.2 |
2 |
6 |
1.2 |
3 |
6 |
1.2 |
4 |
6 |
最小检测尺度关系到算法的运行速率,检测过程中参数的设置合理与否影响到算法的最终结果。检测的范围因子越小,检测时间越长;检测的最小邻域越大,检测时间也越长。即检测时间与最小范围因子成反比,与最小邻域成正比。
文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/jacke121/article/details/76266694
- 点赞
- 收藏
- 关注作者
评论(0)