1.介绍
使用Cascade Classifier包括两个主要阶段:训练阶段和检测阶段。需要用到的OpenCV应用程序:opencv_createssamples, opencv_annotation, opencv_traincascade和opencv_visualisation。opencv_createssamples和opencv_traincascade自OpenCV 4.0以来被禁用,但由于3.4和4.x的模型格式相同,因此可以采用3.4版本的程序进行模型训练。
2.准备训练数据
为了训练一个模型,我们需要一组正样本(包含你想检测的实际对象)和一组负样本(包含你不想检测的所有东西)。负样本集必须手动准备,而正样本集则使用opencv_createssamples创建。
2.1.样本要求
- 样本图片最好使用灰度图,且最好根据实际情况做一定的预处理;
- 样本数量越多越好,尽量高于1000;
- 样本间差异性越大越好;
- 正负样本比例为1:3最佳;
- 样本尺寸为20x20最佳;
2.2.获取训练程序
WINDOWS:
下载地址https://opencv.org/releases/,目前4.x.x版本中没有训练程序,此处采用3.4.16版本,下载后安装就可以找到对应的exe文件;
LINUX:
下载地址https://opencv.org/releases/,目前4.x.x版本中没有训练程序,此处采用3.4.16版本,编译后生成的目录为“build/bin”
2.3.准备目录和程序
- negdata:放负样本的目录
- posdata:放正样本的目录
- opencv_annotation:用于在任何给定图像中可视化地选择对象实例感兴趣的对象,并创建info描述文件
- opencv_createsamples:生成样本描述文件的可执行程序
- opencv_traincascade:样本训练的可执行程序
- opencv_visualisation:可视化训练后的级联,可以看到选择了哪些特征,以及它的阶段有多复杂
3.采集样本数据
3.1.正样本
正样本是由opencv_createssamples应用程序创建的。应用程序支持两种生成正样本数据集的方法:
- 方法1:从一个正样本图像中生成一堆正的样本图像
- 方法2:自己提供所有的正样本图像,并且使用工具将它们剪切出来,调整它们的大小并将它们放入openv所需的二进制格式中
3.1.1.正样本生成方法1
方法1对于固定对象非常有效,但对于不那么严格的对象,它往往很快就会失败,在这种情况下,建议使用方法2。OPENCV甚至指出,100个真实图像可以产生比1000个人工生成的更好的模型。如果依然决定采用方法1,请记住以下几点:
- 请注意,在将其提供给应用程序前,您需要不止一个正样本,因为它只适用于透视图转换(perspective transformation)。
- 如果您想要一个健壮的模型,那么请选取涵盖对象类中可能出现的各种类型的样本。例如,训练脸模型,应该考虑不同的种族、年龄、情绪,也许还有胡子的风格,这也适用于使用第二种方法。
方法1采用单个对象图像,并随机旋转对象、改变图像强度以及将图像放置在任意背景上,从给定对象图像中创建大量正样本。随机性的数量和范围可以通过opencv_createssamples应用程序的命令行参数来控制。
opencv_createsamples的参数说明:
-vec 用于训练的正样本的输出文件名
-img 源对象图像
-bg 背景描述文件,包含一个图像列表,这些图像用作对象随机扭曲版本的背景
-num 生成的正样本数量
-bgcolor 背景色(目前采用灰度图像),背景色为透明色。由于可能存在压缩伪影,因此可以通过-bgthresh指定颜色容错量。bgcolor-bgthresh和bgcolor+bgthresh范围内的所有像素都被解释为透明的。
-bgthresh < background_color_threshold >
-inv 如果指定,颜色将被反转
-randinv 如果指定,颜色将随机反转
-maxidev 前景样本中像素的最大强度偏差
-maxxangle 朝向x轴的最大旋转角度,必须以弧度为单位
-maxyangle 朝向y轴的最大旋转角度,必须以弧度为单位
-maxzangle 朝向z轴的最大旋转角度,必须以弧度为单位
-show 调试选项。如果指定,将显示每个样品。按Esc将继续示例创建过程,但不会显示每个示例
-w 输出样本的宽度(像素)
-h 输出样本的高度(像素)
当以方法1运行opencv_createsamples时,使用以下过程来创建示例对象实例:
- 给定的源图像围绕所有三个轴随机旋转。所选角度受-maxxangle, -maxyangle和-maxzangle的限制
- 像素的亮度从[bg_color-bg_color_threshold;Bg_color +bg_color_threshold]范围被解释为透明。白噪声被添加到前景的强度中
- 如果指定了-inv,则前景像素强度反转。如果指定-randinv key,则算法随机选择是否对该样本进行反转
- 最后,将获得的图像从背景描述文件放置到任意背景上,将其大小调整为-w和-h指定的所需大小,并存储到由-vec指定的vec文件中
3.1.2.正样本生成方法2
正样本也可以从先前标记的图像集合中获得,这是构建robust对象模型时所需的方法。该集合由一个类似于背景描述文件的文本文件描述。这个文件的每一行都对应一个图像。该行的第一个元素是文件名,然后是对象注释的数量,然后是描述对象边界矩形(x, y,宽度,高度)的坐标的数字。
进入posdata目录,然后创建 pos.txt,目录格式如下:
/posdata
00001.jpg
00002.jpg
00003.jpg
pos.txt
pos.txt的内容如下:
00001.jpg 3 548 605 95 100 771 641 125 94 1199 634 182 269
00002.jpg 5 333 464 115 148 844 610 205 259 1139 460 98 138 1315 461 93 101 943 503 57 78
00003.jpg 5 5 491 103 156 472 517 80 114 845 449 151 177 877 631 148 203 1292 482 68 91
图像00001.jpg包含了3个对象,分别是{548,605,95,100},{771,641,125,94},{1199,634,182,269}
为了从这样的集合中创建正样本,应该指定-info参数而不是-img。注意,在方法2中,-bg、-bgcolor、-bgthreshold、-inv、-randinv、-maxxangle、-maxyangle、-maxzangle等参数将被忽略,不再使用。方法2创建示例的方案如下:
- 从原始图像中剪切提供的边界框,从给定图像中获取对象实例
- 将它们调整为目标样本大小(由-w和-h定义),并存储在由-vec参数定义的输出vec文件中
- 方法2唯一有影响的参数是-w, -h, -show和-num
生成VEC指令:
opencv_createsamples -info ${FILEINFO_POS} -vec ${FILEVEC_POS} -num ${NUM_POS} -bgcolor 0 -bgthresh 0 ${SIZ_POS}
3.1.3.opencv_annotation工具
创建info描述文件的过程也可以通过使用opencv_annotation工具来完成。这是一个开源工具,用于在任何给定图像中可视化地选择对象实例感兴趣的区域。
使用该工具非常简单。该工具接受几个必需的和一些可选的参数:
-?, -h, --help, --usage (value:true)
显示帮助信息
-a, --annotations 必选参数,指定生成info描述文件的路径
-i,--images 必选参数,包含样本的目录路径
-m,--maxWindowHeight 可选参数,如果输入图像的高度大于这里给定的分辨率,请使用resizeFactor调整图像的大小
-r,--resizeFactor 可选参数,当使用maxWindowHeight参数时,用于调整输入图像大小的因子(默认:一半大小)。
示例:
./opencv_annotation -a=sample_people/posdata/pos.txt -i=sample_people/posdata/
opencv_annotation命令将打开一个窗口,其中包含第一个图像和用于注释的鼠标光标。鼠标左键用于选择对象的第一个角,然后继续绘制直到确定为止,并在第二次单击鼠标左键时停止。每次选择后,您有以下选择:
按c键:确认标注,标注变为绿色,确认已保存
按d键:从注释列表中删除最后一个注释(方便删除错误注释)
按n键:继续下一个图像
按ESC:退出注释软件
最后,您将得到一个可用的注释文件,它可以传递给opencv_createssamples的-info参数。
3.2.负样本
负样本取自任意图像,图像中应不包含想要检测的对象。这些负样本图像被记录在一个负样本描述文件中,描述文件的每行包含一个图像的路径(可以是绝对路径或相对路径)。请注意,负样本和样本图像也称为背景样本或背景图像。
描述的图像可能有不同的大小,然而每个图像都应该等于或大于期望的训练窗口大小(模型尺寸,大多数情况下是对象的平均大小)。
负样本也不能随意的找些图片来作为负样本。最好根据不同的项目选择不同的负样本。比如一个项目是做机场的人脸检测,那么就最好从现场拍摄一些图片数据回来,从中采集负样本。不同的项目,就采集不同的正样本和负样本。
进入negdata目录,然后创建 neg.txt,目录格式如下:
/negdata
00001.jpg
00002.jpg
00003.jpg
00004.jpg
neg.txt
neg.txt的内容如下:
00001.jpg
00002.jpg
00003.jpg
00004.jpg
4.模型训练
通用参数:
-data 训练好的分类器存储的位置,这个文件夹应该事先手动创建
-vec 带有正样本的vec文件
-bg 背景描述文件,包含负样本图像的文件
-numPos 每个分类器阶段训练中使用的正样本数量。
-numNeg 每个分类器阶段训练中使用的负样本数量。
-numStages 要训练的级联阶段的数量。
-precalcValBufSize 预计算特征值的缓冲区大小(单位为Mb)。
-precalcIdxBufSize 预计算特征索引的缓冲区大小(单位:Mb)。
注意:precalcValBufSize和precalcIdxBufSize分配的内存越多,训练过程就越快,但是不应超过可用的系统内存。
-baseFormatSave 仅在使用Haar特征时有效。如果指定了该参数,则级联将以旧格式保存。
-numThreads 训练期间使用的最大线程数。注意,实际使用的线程数可能更少,这取决于您的机器和编译选项。默认情况下,如果您使用TBB支持构建OpenCV,则选择最大可用线程,这是此优化所需要的。
-acceptanceRatioBreakValue 用于确定你的模型应该保持学习的精确程度以及何时停止。一个好的指导方针是训练不超过10e-5,以确保模型不会在你的训练数据上过度训练。缺省情况下,该值设置为-1,表示禁用该特性。
级联参数
-stageType 级别(stage)参数。目前只支持将BOOST分类器作为级联的类型;
-featureType 特征的类型:HAAR-类Haar特征;LBP-局部二进制模式(默认Harr);
如果遇到的教程提到旧的opencv_haartraining工具(已弃用),请忽略该教程并使用opencv_traincascade工具。openv_traincascade同时支持HAAR和LBP特征。与HAAR特征相比,LBP特征产生整数精度,产生浮点精度,因此LBP的训练和检测速度都比HAAR特征快几倍。对于LBP和HAAR的检测质量,主要取决于所使用的训练数据和所选择的训练参数。
-w 训练样本的度(像素,默认24);
-h 训练样本的度(像素,默认24);
注意:训练样本的尺寸必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致
Boosted分类器参数
-bt
Boosted分类器的类型(DAB-Discrete AdaBoost, RAB-Real AdaBoost, LB-LogitBoost,GAB-Gentle AdaBoost为默认);
-minHitRate
每个阶段的最小期望命中率(默认值为0.995)。总命中率可以估计为(minHitRate^ number_of_stages)
-maxFalseAlarmRate
每一级希望得到的最大误检率(默认值为0.5),总的误检率大约为 maxFalseAlarmRate^number_of_stages;
-weightTrimRate
是否应该使用微调及其权重。一个不错的选择是0.95。
-maxDepth
弱树的最大深度。一个合适的选择是1,这是树桩的情况。
-maxWeakCount
每个级联阶段弱树的最大计数(默认值为100)。boosted分类器(阶段)将有许多弱树(<=maxWeakCount),以实现给定的-maxFalseAlarmRate。
Haar-like 特征参数
-mode
选择训练中使用的Haar特征集的类型。BASIC只使用直立特征,而ALL使用全套直立和45度旋转特征集。
opencv_traincascade应用程序完成其工作后,训练好的级联将保存在-data文件夹中的cascade.xml文件中。此文件夹中的其他文件是为培训中断而创建的,您可以在培训结束后删除。
训练指令:
opencv_traincascade -data ${PATH_OUT} -vec ${FILEVEC_POS} -bg ${FILEINFO_NEG} -numPos ${NUM_POS} -numNeg ${NUM_NEG} -numStages 20 -feattureType HAAR ${SIZ_POS} -minHitRate 0.995 -maxFalseAlarmRate 0.5
5.可视化级联分类器opencv_visualisation
可视化训练后的级联是很有用的,可以看到它选择了哪些特征,以及它的阶段有多复杂。为此,OpenCV提供了一个opencv_visualisation应用程序。这个应用程序有以下命令:
-?, -h, --help, --usage
显示帮助信息
-d, --data
(可选)如果提供了一个数据文件夹,必须事先手动创建,将存储阶段输出和特征的视频
-i, --image
(必选):指向对象模型的参考图像的路径。应该是一个维度为[-w,-h]的注释(annotation),同时传递给opencv_createssamples和opencv_traincascade应用程序。
-m, --model
(必选):训练模型的路径,它应该在openv_traincascade应用程序的-data参数提供的文件夹中。
示例
./opencv_visualisation -m=output/sample_people/cascade.xml -d=output/sample_people/ -i=sample_people/posdata/object.jpg
当前可视化工具的一些局限性
- 只处理用opencv_traincascade工具训练的级联分类器模型,包含树桩作为决策树[默认设置]。
- 所提供的图像需要是具有原始模型尺寸的示例窗口,并传递给–image参数。
6.问题解决
6.1.问题1
问题描述:Traincascade Error: Bad argument (Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.
解决办法:主要是numPos的值设置的不对,把numPos简单设置成正样本数量,将numPos设置正样本数量*4/5即可。
6.2.问题2
问题描述:(-215:Assertion failed) !ssize.empty() in function ‘resize’
解决办法:描述文件中的样本点数据错误导致;文章来源:https://www.toymoban.com/news/detail-557491.html
7.后语
基于人头(正样本4100,负样本23240)、汽车(正样本516,负样本1044)、行人((正样本1126,负样本1000))和实际环境(正样本79,负样本19)训练,感觉最终的效果都不是很好。有知道原因,或者有想法的可以一起交流。文章来源地址https://www.toymoban.com/news/detail-557491.html
到了这里,关于OPENCV训练模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!