目的
在本章中,将学习:
- 级联分类器的训练过程
- 学习函数:
原理
使用弱分类器的增强级联包括两个主要阶段:训练阶段和检测阶段。对象检测教程中介绍了使用基于HAAR或LBP(中心点为阈值,大于它的设为1,小于它的设为0)模型的检测阶段。本文档概述了训练弱分类器的级联所需的函数。当前指南将逐步完成所有不同阶段:
- 收集训练数据
- 准备训练数据
- 训练实际模型
为了支持本教程,将使用几个官方的OpenCV应用程序:
opencv_createsamples
opencv_annotation
opencv_traincascade
opencv_visualisation
注意
自opencv 4.0版本以来,
createsamples
和traincascade
被禁用。考虑使用这些应用程序为级联分类器的3.4分支训练,因此模型格式在3.4和4.x之间相同。
重要提示
- 如果遇到任何提及旧的
opencv_haartraining
工具的教程,请忽略该教程并坚持使用opencv_traincascade
工具。该工具是较新的版本,根据OpenCV 2.x和OpenCV 3.x API用C ++编写。opencv_traincascade
支持类似**HAAR
的小波特征和LBP
(局部二进制模式)特征**。与HAAR特征相比,LBP特征产生整数精度,HAAR产生浮点精度,因此LBP的训练和检测速度都比HAAR特征快几倍。关于LBP和HAAR的检测质量,主要取决于所使用的训练数据和选择的训练参数。可以训练基于LBP的分类器,该分类器将在训练时间的一定百分比内提供与基于HAAR的分类器几乎相同的质量。 - 来自OpenCV 2.x和OpenCV 3.x(
cv::CascadeClassifier
)的较新的级联分类器检测接口支持使用新旧模型格式。如果由于某种原因而使用旧界面,则opencv_traincascade
可以旧格式保存(导出)经过训练的级联,然后可以在最稳定的界面中训练模型。 - opencv_traincascade应用程序可以使用TBB进行多线程处理。 要在多核模式下使用它,必须在启用TBB支持的情况下构建OpenCV。
准备训练数据
为了训练弱分类器的增强级联,需要一组正样本(包含要检测的实际对象)和一组负样本(包含不想检测的所有内容)。负样本集必须手动准备,而正样本集是使用opencv_createsamples
应用程序创建的。
负样本|Negative Samples
负样本来自任意图像,不包含要检测的对象。这些生成样本的负片图像应列在一个特殊的负片图像文件中,该文件每行包含一个图像路径(可以是绝对路径,也可以是相对路径)。注意,负样本和样本图像也称为背景样本或背景图像,在本文档中可以互换使用。
所描述的图像可能具有不同的尺寸。但是,每个图像都应等于或大于所需的训练窗口大小(与模型尺寸相对应,多数情况下是对象的平均大小),因为这些图像用于将给定的负像子采样为几个图像,具有此训练窗口大小的样本。
负样本描述文件的示例:
目录结构:
/img
img1.jpg
img2.jpg
bg.txt
bg.txt
样式:
img/img1.jpg
img/img2.jpg
这样的一组负窗口样本将用于机器学习步骤中,试图找到的感兴趣对象时不寻找什么。
正样本|Positive Samples
正样本由opencv_createsamples
应用程序创建。正样本告诉机器学习算法来定义在尝试找到感兴趣的对象时模型应实际寻找的内容。该应用程序支持两种生成正样本数据集的方式。
- 可以从单个正对象图像生成一堆正值
- 可以自己提供所有肯定的内容,仅使用该工具将其裁剪调整大小并以opencv所需的二进制格式放置
尽管第一种方法对固定对象(例如非常刚性的Logo)效果不错,但对于刚性较差的对象,它往往就会失效。在这种情况下,建议使用第二种方法。
网络上的许多教程甚至都指出,通过使用opencv_createsamples
应用程序可以生成100个真实对象图像,而不是1000个人工生成的正值。但是**,如果采用第一种方法,请记住以下几点**:
- 需要在将其交给所提到的应用程序之前需要多个正示例,因为它只适用透视变换;
- 如果想要一个健壮的模型,请获取涵盖对象类中可能出现的各种变化的样本。例如,对于人脸,应考虑不同的种族和年龄段,情绪以及胡须风格。当使用第二种方法时,这一条也适用;
第一种方法采用带有公司徽标的单个对象图像,并通过随机旋转对象,更改图像强度以及将图像放置在任意背景上,从给定的对象图像中创建大量正样本。随机性的数量和范围可以通过opencv_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>
:前景样本中像素的最大强度偏差-maxxangle <max_x_rotation_angle>
:朝向x轴的最大旋转角度,必须以弧度为单位-maxyangle <max_y_rotation_angle>
:朝向y轴的最大旋转角度,必须以弧度为单位-maxzangle <max_z_rotation_angle>
:朝向z轴的最大旋转角度,必须以弧度为单位-show
:如果指定,将显示每个样本。 按Esc将继续示例创建过程,而不会显示每个示例-w <sample_width>
:输出样本的宽度(以像素为单位)-h <sample_height>
:输出样本的高度(以像素为单位)
当以此方式运行opencv_createsamples
时,将使用以下过程创建示例对象实例:给定的源图像围绕所有三个轴随机旋转。 所选角度受-maxxangle
,-maxyangle
和 -maxzangle
限制。 然后,像素在[bg_color-bg_color_threshold; bg_color + bg_color_threshold]
范围内被设置为透明。白噪声被添加到前景的强度。如果指定-inv
键,则前景像素强度将反转。如果指定-randinv
键,则算法将随机选择是否应对该样本应用反演。最后,将获得的图像从背景描述文件放置到任意背景上,将其大小调整为由 -w
和 -h
指定的所需大小,并存储到由 -vec
命令行选项指定的vec文件中。
正样本也可以从先前标记的图像的集合获得,这是在构建鲁棒目标模型时是所需的方式,该集合由类似于背景描述文件的文本文件描述。此文件的每一行对应于图像。该行的第一个元素是文件名,后跟对象注释的数量,后跟描述对象边界矩形的坐标(x,y,宽度,高度)的数字。
正样本描述文件的示例:
目录结构:
/img
img1.jpg
img2.jpg
info.dat
info.data
文件内容:
img/img1.jpg 1 140 100 45 45
img/img2.jpg 2 100 200 50 50 50 30 25 25
图像img1.jpg
包含具有以下边界矩形坐标的单个对象实例:(140,100,45,45)
。图像img2.jpg包含了两个对象实例,分别为(100,200,50,50)
以及(50,30,25,25)
要从此系列中创建正示例,应指定-info
参数而不是-img
:
-
-info <collection_file_name>
:标记图像集合的描述文件
请注意,在这种情况下, -bg
,-bgcolor
,-bgthreshold
,-inv
,-randinv
,-maxxangle
,-maxyangle
和-maxzangle
等参数将被简单地忽略并且不再使用。在这种情况下,样本创建的方案如下。通过从原始图像中切出提供的边界框,从给定图像中获取对象实例,然后将它们调整为目标样本大小(由-w
和-h
定义),并存储在由 -vec
参数定义的输出vec文件中。没有应用任何失真,因此仅有的影响参数是-w
,-h
, -show
和 -num
。
也可以使用opencv_annotation
工具完成手动创建 -info
文件的过程。这是一个开放源代码工具,用于在任何给定图像中直观地选择对象实例的关注区域。
额外事项
opencv_createsamples
实用程序可用于检查存储在任何给定正样本文件中的样本。为此,仅应指定-vec
,-w
和-h
参数- 此处提供了vec文件的示例
opencv/data/vec_files/trainingfaces_24-24.vec
。它可以用于训练具有以下窗口大小的面部检测器:-w 24 -h 24
使用OpenCV集成的标注工具
由于OpenCV 3.x社区一直在提供和维护一个用于生成-Info
文件的开源注释工具。如果Command OpenCV_Annotation
,则可以访问该工具,如果opencv应用程序在其中构建。
使用该工具非常简单,该工具接受几种必需的和一些可选参数:
-
--annotations
(必需):txt标注文件的路径,要在其中存储标注,然后将其传递给-info
参数[example-/data/annotations.txt]
-
--images
(必需):包含带有对象的图像的文件夹的路径[example-/data/testimages/]
-
--maxWindowHeight
(可选):如果输入图像的高度大于此处的给定分辨率,则调整图像的大小以用于 使用--resizeFactor 可以简化注释。
-
--resizeFactor (可选):使用
–maxWindowHeight` 参数时用于调整输入图像大小的因子
请注意,可选参数只能一起使用。可以使用的命令示例如下所示
opencv_annotation --annotations=/path/to/annotations/file.txt --images=/path/to/image/folder/
此命令将启动一个窗口,其中包含第一张图像和鼠标光标,这些窗口将用于标注。有关如何使用标注工具的视频,请参见此处。基本上,有几个按键可以触发一个动作。鼠标左键用于选择对象的第一个角,然后继续绘制直到满意为止,并在单击鼠标第二次单击时停止。每次选择后,有以下选择:
- 按
c
:确认标注,将标注变为绿色并确认已存储 - 按
d
:从标注列表中删除最后一个注释(易于删除错误的注释) - 按
n
:继续进行操作下一张图片 - 按
ESC
键:退出注释软件
标注完成后,将获得一个可用的标注文件,该文件可以传递给opencv_createsamples
的 -info
参数。
训练级联分类器
下一步是根据预先准备的正负数据集对弱分类器的增强级联进行实际训练。
opencv_traincascade
应用程序的命令行参数按目的进行分组:
- 常用参数
-
-data <cascade_dir_name>
:应将经过训练的分类器存储在何处,该文件夹应事先手动创建 -
-vec <vec_file_name>· :带有正样本的vec文件(由
opencv_createsamples·实用程序创建) -
-bg <background_file_name>
:背景描述文件,这是包含阴性样本图像的文件 -
-numPos <number_of_positive_samples>
:在每个分类器阶段的训练中使用的阳性样本数 -
-numNeg <number_of_negative_samples>
:在每个分类器阶段的训练中使用的负样本数 -
-numStages <number_of_stages>
:要训练的级联级数 -
-precalcValBufSize <precalculated_vals_buffer_size_in_Mb>
:用于预先计算的特征值的缓冲区大小(以Mb为单位)。分配的内存越多,训练过程就越快,但是请记住-precalcValBufSize
和-precalcIdxBufSize
的总和不应超过可用的系统内存 -
-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>
:用于预先计算的特征索引的缓冲区大小(以Mb为单位)。分配的内存越多,训练过程就越快,但是请记住,-precalcValBufSize
和-precalcIdxBufSize
的总和不应超过可用的系统内存。 -
-baseFormatSave
:对于类似Haar的功能,此参数是实际的。如果指定,级联将以旧格式保存。仅出于向后兼容的原因,并且允许用户停留在旧的不赞成使用的界面上,至少可以使用较新的界面训练模型,才可以使用此功能 -
-numThreads <max_number_of_threads>
:训练期间要使用的最大线程数。实际使用的线程数可能会更少,具体取决于计算机和编译选项。默认情况下,如果使用TBB支持构建了OpenCV,则会选择最大可用线程,这是此优化所必需的 -
-acceptanceRatioBreakValue <break_value>
:此参数用于确定模型应保持学习的精确度以及何时停止。良好的指导原则是进行不超过10e-5
的训练,以确保模型不会对训练数据过度训练。默认情况下,此值设置为-1
以禁用此特征
- 级联参数:
-
-stageType <BOOST(default)>
:阶段的类型,目前仅支持提升分类器作为阶段类型。 -
-featureType <{HAAR(default),LBP}>
:特征类型:HAAR-类似Haar的特征
,LBP-本地二进制模式
-
-w <sampleWidth>
:训练样本的宽度(以像素为单位),必须具有与训练样本创建期间使用的值完全相同的值 -
-h <sampleHeight>
:训练样本的高度(以像素为单位)。必须具有与训练样本创建期间使用的值完全相同的值
- 提升分类器参数:
-bt <{DAB,RAB,LB,GAB(default)}>
:增强分类器的类型:DAB-Discrete AdaBoost
,RAB-Real AdaBoost
,LB-LogitBoost
,GAB-Gentle AdaBoost
-minHitRate <min_hit_rate>
:分类器每个阶段的最低期望命中率。总命中率可以估计为(min_hit_rate ^ number_of_stages
)-maxFalseAlarmRate <max_false_alarm_rate>
:分类器每个阶段的最大期望误报率。总体误报率可以估计为(max_false_alarm_rate ^ number_of_stages
)-weightTrimRate
:指定是否应使用修剪及其权重,推荐设置为0.95-maxDepth <max_weak_tree>
:弱树的最大深度,推荐设置为1-maxWeakCount <max_weak_tree_count>
:每个级联阶段的弱树的最大计数。提升分类器(阶段)将具有如此多的弱树(<= maxWeakCount),以实现给定的-maxFalseAlarmRate
- 类似Haar的特征参数:
-
-mode <BASIC(default)|CORE| ALL>
:选择训练中使用的Haar特征集的类型。BASIC
仅使用竖着的特征,而ALL使
用整套竖着和45度旋转特征集,更多信息参考该论文 - 本地二进制模式参数:本地二进制模式没有参数
opencv_traincascade应用程序完成工作后,经过训练的级联将保存在 -data
文件夹中cascade.xml
文件中。此文件夹中的其他文件是为中断训练而创建的,因此可以在训练完成后将其删除。训练完成后,可以测试级联分类器。
级联分类器的可视化
有时,可视化经过训练的级联可能很有用,以查看其选择的特征以及其阶段的复杂程度。为此,OpenCV提供了一个opencv_visualisation
应用程序。该应用程序具有以下命令:
--image
(必需):对象模型参考图像的路径。 这应该是标注,标注[-w,-h]
传递给opencv_createsamples
和opencv_traincascade
应用程序--model
(必需):训练模型的路径,该路径应该在opencv_traincascade
应用程序的-data
参数提供的文件夹中。--data
(可选):如果提供数据文件夹,应该事先手动创建它,那么将存储阶段输出和特征的视频。 下面是一个示例命令:
opencv_visualisation --image=/data/object.png --model=/data/model.xml --data=/data/result/
当前可视化工具的某些限制
- 仅能处理级联分类器模型() 使用
opencv_traincascade
工具进行训练),其中包含树桩作为决策树[默认设置]。 - 提供的图像必须是带有原始模型尺寸的样本窗口,并传递给
–image
参数
例子:
在安吉丽娜·朱莉(Angelina Jolie)图像上使用HAAR
/LBP
人脸模型在给定窗口上运行**,该窗口具有与级联分类器文件相同的预处理**–>24x24像素图像
,灰度转换和直方图均衡:
每个阶段都会制作一个视频,每个特征都可视化:
每个阶段都会制作一个视频,以显示每个特征:
附加资源
- https://docs.opencv.org/4.5.5/dc/d88/tutorial_traincascade.html
- https://docs.opencv.org/4.5.5/db/d28/tutorial_cascade_classifier.html
- https://github.com/opencv/opencv/tree/4.x/apps/createsamples
- https://github.com/opencv/opencv/tree/4.x/apps/annotation
- https://github.com/opencv/opencv/tree/4.x/apps/traincascade
- https://github.com/opencv/opencv/tree/4.x/apps/visualisation