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

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

简介

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

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

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

重要提示

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

训练数据准备

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

负样本

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

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

此类负描述文件示例

目录结构

/img
img1.jpg
img2.jpg
bg.txt

文件 bg.txt

img/img1.jpg
img/img2.jpg

您的负窗口样本集将用于告诉机器学习步骤(在本例中为增强)在尝试查找您感兴趣的对象时,不应寻找什么。

正样本

正样本由opencv_createsamples应用程序创建。它们被增强过程用于定义模型在尝试查找您感兴趣的对象时应实际查找什么。该应用程序支持两种生成正样本数据集的方式。

  1. 您可以从单个正对象图像生成大量正样本。
  2. 您可以自行提供所有正样本,只使用该工具来裁剪它们、调整它们的大小并将它们放入opencv所需的二进制格式。

虽然第一种方法对于固定对象(如非常刚性的徽标)效果良好,但对于不那么刚性的对象,它很快就会失效。在这种情况下,我们建议使用第二种方法。网络上许多教程甚至指出,100张真实对象图像可以通过opencv_createsamples应用程序生成比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

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

额外说明

  • opencv_createsamples 工具可用于检查存储在任何给定正样本文件中的样本。为此,只需指定 -vec-w-h 参数。
  • vec文件的示例可在opencv/data/vec_files/trainingfaces_24-24.vec找到。它可用于训练人脸检测器,窗口大小为:-w 24 -h 24

使用OpenCV的集成标注工具

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

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

  • --annotations (必需) :注释txt文件的路径,您希望在此存储注释,然后将其传递给-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 <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> :训练期间使用的最大线程数。请注意,实际使用的线程数可能更少,具体取决于您的机器和编译选项。默认情况下,如果您的OpenCV是在支持TBB的情况下构建的(此优化需要TBB支持),则会选择最大可用线程数。
    • -acceptanceRatioBreakValue <break_value> :此参数用于确定模型应学习的精确程度以及何时停止。一个好的指导方针是训练不超过10e-5,以确保模型不会在您的训练数据上过拟合。默认情况下,此值设置为-1以禁用此功能。
  • 级联参数
    • -stageType <BOOST(默认)> :阶段类型。目前仅支持增强分类器作为阶段类型。
    • -featureType<{HAAR(默认), LBP}> :特征类型:HAAR - Haar-like特征,LBP - 局部二值模式。
    • -w <sampleWidth> :训练样本的宽度(像素)。必须与训练样本创建(opencv_createsamples工具)时使用的值完全相同。
    • -h <sampleHeight> :训练样本的高度(像素)。必须与训练样本创建(opencv_createsamples工具)时使用的值完全相同。
  • 增强分类器参数
    • -bt <{DAB, RAB, LB, GAB(默认)}> :增强分类器类型:DAB - 离散AdaBoost,RAB - 真实AdaBoost,LB - LogitBoost,GAB - Gentle AdaBoost。
    • -minHitRate <min_hit_rate> :分类器每个阶段的最小期望命中率。总命中率可以估计为 (min_hit_rate ^ number_of_stages),[289] §4.1。
    • -maxFalseAlarmRate <max_false_alarm_rate> :分类器每个阶段的最大期望误报率。总误报率可以估计为 (max_false_alarm_rate ^ number_of_stages),[289] §4.1。
    • -weightTrimRate <weight_trim_rate> :指定是否应使用修剪及其权重。一个不错的选择是0.95。
    • -maxDepth <max_depth_of_weak_tree> :弱树的最大深度。一个不错的选择是1,即树桩的情况。
    • -maxWeakCount <max_weak_tree_count> :每个级联阶段的弱树最大数量。增强分类器(阶段)将拥有达到给定-maxFalseAlarmRate所需的弱树数量(<=maxWeakCount)。
  • Haar-like特征参数
    • -mode <BASIC (默认) | CORE | ALL> :选择训练中使用的Haar特征集类型。BASIC只使用直立特征,而ALL使用直立和45度旋转特征的完整集。更多详情请参见[170]
  • 局部二值模式参数:局部二值模式没有参数。

当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参数。

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

制作了一个视频,其中每个阶段的每个特征都进行了可视化

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

此作品由StevenPuttemans为OpenCV 3 Blueprints创建,Packt Publishing同意将其集成到OpenCV中。