OpenCV Extra 03 - 训练级联分类器

训练级联分类器

一、引言

使用增强级联的弱分类器包括两个主要阶段:训练和检测阶段。 对象检测教程中描述了使用基于 HAAR 或 LBP 的模型的检测阶段。 本文档概述了训练您自己的增强级联弱分类器所需的功能。 本指南将介绍所有不同的阶段:收集训练数据、准备训练数据和执行实际模型训练。

本小节中,将使用几个官方 OpenCV 应用程序:opencv_createsamples、opencv_annotation、opencv_traincascade 和 opencv_visualisation。

  • 注意:

自 OpenCV 4.0 起,Createsamples 和 traincascade 被禁用。 考虑使用这些应用程序从 Cascade Classifier 的 3.4 分支进行训练。 模型格式在 3.4 和 4.x 之间是相同的。

1. 牢记:

  1. 如果您遇到任何提到旧的 opencv_haartraining 工具(已弃用且仍在使用 OpenCV1.x 界面)的教程,请忽略该教程并坚持使用 opencv_traincascade 工具。该工具是较新的版本,根据 OpenCV 2.x 和 OpenCV 3.x API 用 C++ 编写。 opencv_traincascade 支持类似 HAAR 的小波特征 [264] 和 LBP(局部二进制模式)[148] 特征。与 HAAR 特征相比,LBP 特征产生整数精度,产生浮点精度,因此使用 LBP 的训练和检测都比使用 HAAR 特征快几倍。关于 LBP 和 HAAR 的检测质量,主要取决于使用的训练数据和选择的训练参数。可以在训练时间的一定百分比内训练一个基于 LBP 的分类器,该分类器将提供与基于 HAAR 的分类器几乎相同的质量。
  2. OpenCV 2.x 和 OpenCV 3.x (cv::CascadeClassifier) 中较新的级联分类器检测接口支持使用新旧模型格式。如果由于某种原因您无法使用旧界面,opencv_traincascade 甚至可以以旧格式保存(导出)经过训练的级联。至少可以在最稳定的界面中完成模型的训练。
  3. opencv_traincascade 应用程序可以使用 TBB 进行多线程。要在多核模式下使用它,OpenCV 必须在启用 TBB 支持的情况下构建。

二、准备训练数据

为了训练增强级联的弱分类器,我们需要一组正样本(包含您想要检测的实际对象)和一组负图像(包含您不想检测的所有内容)。 负样本集必须手动准备,而正样本集是使用 opencv_createsamples 应用程序创建的。

1. 负样本

负样本取自任意图像,不包含您要检测的对象。 这些生成样本的负片图像应列在一个特殊的负片图像文件中,其中每行包含一个图像路径(可以是绝对的或相对的)。 请注意,负样本和样本图像也称为背景样本或背景图像,在本文档中可以互换使用。

所描述的图像可能具有不同的大小。 但是,每个图像应该等于或大于所需的训练窗口大小(对应于模型尺寸,大多数情况下是对象的平均大小),因为这些图像用于将给定的负图像子采样为多个图像 具有此训练窗口大小的样本。

这种负面描述文件的一个例子:

文件目录

/img
  img1.jpg
  img2.jpg
bg.txt
复制代码

bg.txt文件内容:

img/img1.jpg
img/img2.jpg
复制代码

您的一组负窗口样本将用于告诉机器学习步骤,在这种情况下,在尝试找到您感兴趣的对象时,提升不寻找的内容。

2. 正样本

正样本由 opencv_createsamples 应用程序创建。 提升过程使用它们来定义模型在尝试查找感兴趣的对象时应该实际查找的内容。 该应用程序支持两种生成正样本数据集的方法。

  1. 您可以从单个正面对象图像生成一堆正面。
  2. 您可以自己提供所有正面信息,并且只使用该工具将它们剪掉,调整它们的大小并将它们放入 opencv 所需的二进制格式。

虽然第一种方法适用于固定对象,例如非常刚性的徽标,但对于不太刚性的对象,它往往很快就会失败。 在这种情况下,我们建议使用第二种方法。 网络上的许多教程甚至指出,通过使用 opencv_createsamples 应用程序,100 个真实对象图像可以生成比 1000 个人工生成的正样本更好的模型。 但是,如果您决定采用第一种方法,请记住以下几点:

请注意,在将其提供给上述应用程序之前,您需要多个正样本,因为它只应用透视变换。 如果您想要一个稳健的模型,请采集涵盖您的对象类中可能出现的各种类型的样本。 例如,在面孔的情况下,您应该考虑不同的种族和年龄组、情绪,也许还有胡须样式。 这也适用于使用第二种方法时。

第一种方法采用带有例如公司徽标的单个对象图像,并通过随机旋转对象、更改图像强度以及将图像放置在任意背景上,从给定对象图像创建大量正样本。 随机性的数量和范围可以通过 opencv_createsamples 应用程序的命令行参数来控制。

命令行参数:

  1. -vec <vec_file_name> :包含用于训练的正样本的输出文件的名称。
  2. -img <image_file_name> :源对象图像(例如,公司徽标)。
  3. -bg <background_file_name> :背景描述文件;包含图像列表,这些图像用作对象随机扭曲版本的背景。
  4. -num <number_of_samples> :要生成的正样本数。
  5. -bgcolor <background_color> :背景颜色(当前假定为灰度图像);背景色表示透明色。由于可能存在压缩伪影,因此可以通过
  6. -bgthresh 指定颜色容差量。 bgcolor-bgthresh 和 bgcolor bgthresh 范围内的所有像素都被解释为透明的。
  7. -bgthresh <background_color_threshold>
  8. -inv :如果指定,颜色将被反转。
  9. -randinv :如果指定,颜色将随机反转。
  10. -maxidev <max_intensity_deviation> :前景样本中像素的最大强度偏差。
  11. -maxxangle <max_x_rotation_angle> :朝向 x 轴的最大旋转角度,必须以弧度表示。
  12. -maxyangle <max_y_rotation_angle> :朝向 y 轴的最大旋转角度,必须以弧度表示。
  13. -maxzangle <max_z_rotation_angle> :朝向 z 轴的最大旋转角度,必须以弧度为单位。
  14. -show :有用的调试选项。如果指定,将显示每个样本。按 Esc 将继续样本创建过程,而不显示每个样本。
  15. -w <sample_width> :输出样本的宽度(以像素为单位)。
  16. -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.dat文件内容

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 包含两个对象实例。

为了从此类集合中创建正样本,应指定 -info 参数而不是 -img:

  • info <collection_file_name> :标记图像集合的描述文件。

请注意,在这种情况下,-bg、-bgcolor、-bgthreshold、-inv、-randinv、-maxxangle、-maxyangle、-maxzangle 等参数将被忽略,不再使用。在这种情况下创建样本的方案如下。通过从原始图像中切出提供的边界框,从给定图像中获取对象实例。然后将它们调整为目标样本大小(由 -w 和 -h 定义)并存储在由 -vec 参数定义的输出 vec 文件中。没有应用失真,因此唯一影响的参数是 -w、-h、-show 和 -num。

手动创建 -info 文件的过程也可以使用 opencv_annotation 工具来完成。这是一个开源工具,用于在任何给定图像中直观地选择对象实例的感兴趣区域。以下小节将更详细地讨论如何使用此应用程序。

  • 额外说明
  1. opencv_createsamples 实用程序可用于检查存储在任何给定正样本文件中的样本。为此,只需指定 -vec、-w 和 -h 参数。
  2. 此处提供了 vec 文件的示例 opencv/data/vec_files/trainingfaces_24-24.vec。它可用于训练具有以下窗口大小的人脸检测器:-w 24 -h 24。

3. OpenCV中内置注解工具

自 OpenCV 3.x 以来,社区一直在提供和维护一个开源注释工具,用于生成 -info 文件。如果构建 OpenCV 应用程序,则可以通过命令 opencv_annotation 访问该工具。

使用该工具非常简单。该工具接受几个必需参数和一些可选参数:

  • annotations(必需):注释 txt 文件的路径,您要在其中存储注释,然后将其传递给 -info 参数 [example - /data/annotations.txt]
  • images(必需):包含带有您的对象的图像的文件夹的路径 [示例 - /data/testimages/]
  • maxWindowHeight(可选):如果输入图像的高度大于此处给定的分辨率,则使用 --resizeFactor 调整图像大小以便于注释。
  • resizeFactor(可选):使用 --maxWindowHeight 参数时用于调整输入图像大小的因子。

请注意,可选参数只能一起使用。可以使用的命令示例如下所示

注意,上面的可选参数要选就一起选。命令行参数实例:

opencv_annotation --annotations=/path/to/annotations/file.txt --images=/path/to/image/folder/
复制代码

此命令将启动一个窗口,其中包含第一张图像和将用于注释的鼠标光标。 可以在此处 www.youtube.com/watch?v=EV5… 找到有关如何使用注释工具的视频。 基本上有几个按键可以触发一个动作。 鼠标左键用于选择对象的第一个角,然后继续绘制直到您没问题,并在注册第二次鼠标左键单击时停止。 每次选择后,您有以下选择:

  1. 按 c :确认注释,将注释变为绿色并确认已存储
  2. 按 d :从注释列表中删除最后一个注释(便于删除错误的注释)
  3. 按 n :继续下一张图片
  4. 按 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-like 特性的情况下是实际的。如果指定,级联将以旧格式保存。这只适用于向后兼容的原因,并允许用户坚持使用旧的已弃用界面,至少可以使用较新的界面训练模型。
    • numThreads <max_number_of_threads> :训练期间使用的最大线程数。请注意,实际使用的线程数可能会更少,具体取决于您的机器和编译选项。默认情况下,如果您使用 TBB 支持构建 OpenCV,则会选择最大可用线程,这是优化所必需的。
    • acceptanceRatioBreakValue <break_value> :此参数用于确定您的模型应该保持学习的精确程度以及何时停止。一个好的指导原则是训练不超过 10e-5,以确保模型不会过度训练您的训练数据。默认情况下,此值设置为 -1 以禁用此功能。
  • 级联参数:

    • stageType <BOOST(default)> :阶段的类型。目前仅支持增强分类器作为阶段类型。
    • featureType<{HAAR(default), LBP}> :特征类型:HAAR - 类似 Haar 的特征,LBP - 本地二进制模式。
    • w :训练样本的宽度(以像素为单位)。必须具有与创建训练样本期间使用的值完全相同的值(opencv_createsamples 实用程序)。
    • h :训练样本的高度(以像素为单位)。必须具有与创建训练样本期间使用的值完全相同的值(opencv_createsamples 实用程序)。
  • 增强分类器参数:

    • bt <{DAB, RAB, LB, GAB(default)}> :增强分类器的类型:DAB - 离散 AdaBoost,RAB - 真实 AdaBoost,LB - LogitBoost,GAB - 温和 AdaBoost。
    • minHitRate <min_hit_rate> :分类器每个阶段的最小期望命中率。总体命中率可以估计为 (min_hit_rate ^ number_of_stages), [265] §4.1。
    • maxFalseAlarmRate <max_false_alarm_rate> :分类器每个阶段的最大期望误报率。总体误报率可以估计为 (max_false_alarm_rate ^ number_of_stages),[265] §4.1。
    • weightTrimRate <weight_trim_rate> :指定是否应使用修剪及其权重。一个不错的选择是 0.95。
    • maxDepth <max_depth_of_weak_tree> :弱树的最大深度。一个不错的选择是 1,即树桩的情况。
    • maxWeakCount <max_weak_tree_count> :每个级联阶段的弱树的最大计数。提升分类器(阶段)将有很多弱树(<=maxWeakCount),以实现给定的 -maxFalseAlarmRate。
  • Haar-like特征参数:

    • mode <基本(默认)|核心 | ALL> :选择训练中使用的 Haar 特征集的类型。 BASIC 仅使用直立特征,而 ALL 使用全套直立和 45 度旋转特征集。有关详细信息,请参见 [151]。
  • 本地二进制模式参数:本地二进制模式没有参数。

    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/
复制代码

当前可视化工具的一些限制

  1. 仅处理级联分类器模型,使用 opencv_traincascade 工具训练,包含树桩作为决策树 [默认设置]。
  2. 提供的图像需要是具有原始模型尺寸的示例窗口,并传递给 --image 参数。

HAAR/LBP 人脸模型的示例在 Angelina Jolie 的给定窗口上运行,该窗口具有与级联分类器文件相同的预处理——>24x24 像素图像、灰度转换和直方图均衡:

每个阶段都制作了一个视频,每个功能都可视化:

download.png

每个阶段都存储为图像,以供将来验证功能:

download.png

这项工作是由 StevenPuttemans 为 OpenCV 3 Blueprints 创建的,但 Packt Publishing 同意将其集成到 OpenCV 中。

猜你喜欢

转载自juejin.im/post/7106346356079329293