OpenCV  4.10.0
开源计算机视觉
加载中...
搜索中...
无匹配项
级联分类器训练

上一教程: 级联分类器
下一教程: 条形码识别

简介

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

为了支持本教程,将使用多个官方 OpenCV 应用程序:opencv_createsamplesopencv_annotationopencv_traincascadeopencv_visualisation

注意
Createsamples 和 traincascade 已自 OpenCV 4.0 起禁用。考虑使用 3.4 分支中的这些应用程序从级联分类器进行训练。在 3.4 和 4.x 之间,模型格式是相同的。

重要说明

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

训练数据的准备

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

负样本

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

所述图像可以具有不同的尺寸。但是,每个图像应等于或大于所需的训练窗口尺寸(与模型维度相对应,大多数情况下为对象的平均尺寸),因为这些图像用于对给定的负图像进行子采样,将其生成多个具有此训练窗口尺寸的图像样本。

此类负描述文件的示例

目录结构

/img
img1.jpg
img2.jpg
bg.txt

文件 bg.txt

img/img1.jpg
img/img2.jpg

一组负窗口样本将用于告知机器学习步骤(在本例中为提升),在尝试查找感兴趣对象时要查看的内容。

正样本

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

  1. 可以从单个正对象图像生成大量正样本。
  2. 可以自己提供所有正样本,并仅使用该工具将它们剪切出来、调整大小并置于 opencv 需要的二进制格式中。

虽然第一个方法对于固定物体,比如非常坚硬的徽标,效果很好,但它往往很快就会在不太坚硬的物体上出现问题。在这种情况下,我们建议使用第二个方法。网上许多教程甚至指出,通过使用 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.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

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

额外备注

  • opencv_createsamples 实用程序可以用来检验存储在任何给定正样本文件中的样本。要执行此操作,应仅指定 -vec-w-h 参数。
  • 向量文件示例可从此处获得:opencv/data/vec_files/trainingfaces_24-24.vec。它可用于训练窗口大小为 -w 24 -h 24 的人脸检测器。

使用 OpenCV 的集成注释工具

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

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

  • --annotations (必需):要存储注释的注释文本文件路径,然后传递给 -info 参数 [示例 - /data/annotations.txt]
  • --images (必需):包含带有对象的图像的文件夹的路径 [示例 - /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 <级联目录名称> :应当存储已训练分类器的位置。应当事先手动创建此文件夹。
    • -vec <vec 文件名称> :包含阳性样本的 vec 文件(由 opencv_createsamples 功用程序创建)。
    • -bg <背景文件名称> :背景描述文件。这是包含负样本图像的文件。
    • -numPos <阳性样本数量> :每个分类器阶段使用于训练的阳性样本数量。
    • -numNeg <负样本数量> :每个分类器阶段使用于训练的负样本数量。
    • -numStages <级联阶段数量> :应当进行训练的级联阶段数量。
    • -precalcValBufSize <预计算值缓冲区大小(单位:兆字节)> :预计算特征值缓冲区大小(单位:兆字节)。您分配的内存越大,训练过程就会越快,但是请谨记 -precalcValBufSize-precalcIdxBufSize 合并不应超出系统可用内存。
    • -precalcIdxBufSize <预计算索引缓冲区大小(单位:兆字节)> :预计算特征索引缓冲区大小(单位:兆字节)。您分配的内存越大,训练过程就会越快,但是请谨记 -precalcValBufSize-precalcIdxBufSize 合并不应超出系统可用内存。
    • -baseFormatSave :此参数在 Haar 特征的情况下有效。如果指定此参数,则级联将以旧格式保存。此参数仅出于向后兼容性原因而提供,并且允许坚持使用旧版弃用界面的用户至少使用新的界面训练模型。
    • -numThreads <最大线程数量> :训练期间应当使用到的最大线程数量。请注意,实际使用线程的数量可能会较少,这取决于计算机和编译选项。默认情况下,如果使用 TBB 支持构建 OpenCV(这是此优化所必需的),则会选择最多可用线程。
    • -acceptanceRatioBreakValue <中断值> :此参数用于确定模型应当多久继续学习以及何时停止。一个好的准则是不要进行超过 10e-5 的训练,以确保模型不会对您的训练数据进行过度训练。默认情况下,此值设为 -1 以禁用此功能。
  • 级联参数
    • -stageType <BOOST(默认)> :阶段类型。目前仅支持以提升分类器做为阶段类型。
    • -featureType<{HAAR(默认), LBP}> :特征类型:HAAR - Haar 样特征,LBP - 局部二元模式。
    • -w <样本宽度> :训练样本宽度(单位:像素)。必须与训练样本创建期间(opencv_createsamples 功用程序)使用的值完全相同。
    • -h <样本高度> :训练样本高度(单位:像素)。必须与训练样本创建期间(opencv_createsamples 功用程序)使用的值完全相同。
  • 提升分类器参数
    • -bt <{DAB, RAB, LB, GAB(default)}>:增强分类器的类型:DAB - 离散 AdaBoost、RAB - 实时 AdaBoost、LB - LogitBoost、GAB - Gentle AdaBoost。
    • -minHitRate <min_hit_rate>:分类器每一阶段所需的最小命中率。总命中率可估计为 (min_hit_rate ^ number_of_stages),[285] §4.1。
    • -maxFalseAlarmRate <max_false_alarm_rate>:分类器每一阶段所需的最大误报率。总误报率可估计为 (max_false_alarm_rate ^ number_of_stages),[285] §4.1。
    • -weightTrimRate <weight_trim_rate>:指定是否使用修剪及其权重。0.95 是一个不错的选择。
    • -maxDepth <max_depth_of_weak_tree>:弱树的最大深度。1 是一个不错的选择,即残桩情况。
    • -maxWeakCount <max_weak_tree_count>:每个级联阶段的弱树最大数量。增强分类器(阶段)将具有如此多的弱树(<=maxWeakCount),以达到给定的 -maxFalseAlarmRate
  • Haar 类似特征参数
    • -mode <BASIC (default) | CORE | ALL>:选择训练中使用的 Haar 特征集的类型。BASIC 只使用竖直特征,而 ALL 使用竖直和 45 度旋转特征集的完整集。有关详细信息,请参阅 [167]
  • 局部二元模式参数:局部二元模式没有参数。

在 opencv_traincascade 应用程序完成工作后,训练后的级联将保存在 -data 文件夹中的 cascade.xml 文件中。此文件夹中的其他文件为中断训练的情况创建,因此您可以在训练完成后删除它们。

训练完成,您可以测试您的级联分类器!

级联分类器的可视化

偶尔,可视化训练后的级联非常有用,以查看级联选择了哪些特征以及其各个阶段有多复杂。为此,OpenCV 提供了一个 opencv_visualisation 应用程序。此应用程序具有以下命令

  • --image (必需):对象模型的参考图像的路径。这应该带有 opencv_createsamples 和 opencv_traincascade 应用程序传递的尺寸 [-w,-h] 的注释。
  • --model (必需):训练后的模型的路径,该路径应位于传递给 opencv_traincascade 应用程序的 -data 参数的文件夹中。
  • --data (可选):如果提供了一个数据文件夹(必须事先手动创建),将储存阶段输出和特征视频数据。

示例命令如下所示

opencv_visualisation --image=/data/object.png --model=/data/model.xml --data=/data/result/

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

  • 仅支持级联分类器模型,使用 opencv_traincascade 工具进行训练,其中包含作为决策树的 [默认设置]。
  • 提供的图像需要是具有原始模型尺寸的样本窗口,传递给 --image 参数。

安吉丽娜·朱莉给定窗口上运行的 HAAR/LBP 人脸模型示例,该窗口与级联分类器文件具有相同的预处理 -->24x24 像素图像灰度转换和直方图均衡

针对每个阶段生成一段视频,可视化每个特征

每个阶段都被存储为图像,以便将来验证这些特征

这件作品由 Packt Publishing 创造,创建者为 StevenPuttemans,但 Packt Publishing 同意将其集成到 OpenCV 中。