codecamp

层叠分类器训练

介绍

使用弱分类器的升级层叠包括两个主要阶段:培训和检测阶段。使用HAAR或LBP的模型的检测阶段在对象检测教程中进行了描述。本文档概述了培训您自己的弱分类器层叠的功能。目前的指南将贯穿各个阶段:收集培训数据,准备培训数据和执行实际培训。

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

重要笔记

  • 如果您参考任何教程,提到旧的opencv_haartraining工具(已被弃用,仍然使用OpenCV1.x界面),请忽略该教程,并坚持使用opencv_traincascade工具。该工具是根据OpenCV 2.x和OpenCV 3.x API以C ++编写的较新版本。opencv_traincascade支持HAAR,如小波特征[181]和LBP(局部二进制模式)[103]特征。与HAAR功能相比,LBP功能产生整数精度,产生浮点精度,因此使用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所需的二进制格式中。

虽然第一种方法适用于固定对象,如非常刚性的标志,但是对于较不刚性的对象,它往往会失败。在这种情况下,我们建议使用第二种方法。通过使用opencv_createsamples应用程序,Web上的许多教程甚至可以指出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_c​​olor_threshold]范围被解释为透明。将白噪声添加到前景的强度。如果-inv指定了键,则前景像素强度被反转。如果-randinv指定了密钥,则算法随机选择是否应该对该样本应用反演。最后,所获得的图像被放置在从背景描述文件的任意的背景下,调整为所指定的所需的大小-w和-h并存储到由-vec命令行选项指定的vec文件中。

也可以从先前标记的图像的集合中获得正样本,这是构建鲁棒对象模型时的期望方式。该集合由与背景描述文件类似的文本文件描述。该文件的每行对应一个图像。该行的第一个元素是文件名,后跟对象注释的数量,后跟数字描述边界矩形(x,y,width,height)的对象的坐标。

描述文件的一个例子:

目录结构:

/ 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 (必需):注释文件的路径,您要存储注释的位置,然后传递给-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:这将退出注释软件

最后,您将得到一个可以传递给-infoopencv_createsamples参数的可用注释文件。

层叠训练

下一步是基于预先准备的正数和负数据集,对弱分类器进行升压层叠的实际训练。

opencv_traincascade应用程序的命令行参数按目的分组:

  • 共同点:
    1. -data <cascade_dir_name>:训练有素的分类器应存放在何处。预先手动创建该文件夹。
    2. -vec <vec_file_name> :具有正样本的vec文件(由opencv_createsamples实用程序创建)。
    3. -bg <background_file_name>:背景描述文件。这是包含负样本图像的文件。
    4. -numPos <number_of_positive_samples> :每个分类阶段培训使用的阳性样本数。
    5. -numNeg <number_of_negative_samples> :每个分类阶段训练中使用的阴性样本数。
    6. -numStages <number_of_stages> :要训练的层叠级数。
    7. -precalcValBufSize <precalculated_vals_buffer_size_in_Mb>:预先计算的特征值的缓冲区大小(以Mb为单位)。您指定的快训练过程中更多的内存,但是请记住,-precalcValBufSize并-precalcIdxBufSize结合不应超过您可用的系统内存。
    8. -precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>:预先计算的特征索引的缓冲区大小(以Mb为单位)。您指定的快训练过程中更多的内存,但是请记住,-precalcValBufSize并-precalcIdxBufSize结合不应超过您可用的系统内存。
    9. -baseFormatSave:这个说法在哈尔式的特征的情况下是实际的。如果指定,层叠将以旧格式保存。这仅适用于向后兼容性原因,并允许用户坚持旧的弃用接口,至少使用较新界面对模型进行训练。
    10. -numThreads <max_number_of_threads>:训练期间使用的最大线程数。请注意,根据您的机器和编译选项,使用的线程的实际数量可能会较低。默认情况下,如果您使用TBB支持构建OpenCV,则可以选择最大可用线程,这是该优化所需的。
    11. -acceptanceRatioBreakValue <break_value>:此参数用于确定您的模型应该如何精确地保持学习和何时停止。一个好的指导方针是训练不超过10e-5,以确保该模型不会超出您的训练数据。默认情况下,该值设置为-1以禁用此功能。
  • 层叠参数:-
    1. -stageType <BOOST(default)>:阶段类型 目前仅支持升级分类器作为舞台类型。
    2. -featureType<{HAAR(default), LBP}> :特征类型:HAAR - 类似Haar的功能,LBP - 本地二进制模式。
    3. -w <sampleWidth>:训练样本的宽度(以像素为单位)。必须具有与训练样本创建期间使用的完全相同的值(opencv_createsamples实用程序)。
    4. -h <sampleHeight>:训练样本的高度(以像素为单位)。必须具有与训练样本创建期间使用的完全相同的值(opencv_createsamples实用程序)。
  • 增强的分类参数:
    1. -bt <{DAB, RAB, LB, GAB(default)}> :提升分类器的类型:DAB - Discrete AdaBoost,RAB - Real AdaBoost,LB - LogitBoost,GAB - Gentle AdaBoost。
    2. -minHitRate <min_hit_rate>:分类器的每个阶段的最小期望命中率。总命中率可以估计为(min_hit_rate ^ number_of_stages),[182] §4.1。
    3. -maxFalseAlarmRate <max_false_alarm_rate>:分类器每个阶段的最大期望误报率。总误报率可以估计为(max_false_alarm_rate ^ number_of_stages),[182] §4.1。
    4. -weightTrimRate <weight_trim_rate>:指定是否使用修剪及其重量。一个体面的选择是0.95。
    5. -maxDepth <max_depth_of_weak_tree>:弱树的最大深度。一个体面的选择是1,就是树桩的情况。
    6. -maxWeakCount <max_weak_tree_count>:每个层叠阶段弱树的最大数量。提升的分类器(阶段)将具有如此多的弱树(<= maxWeakCount),以实现给定的需要-maxFalseAlarmRate。
  • 哈尔式功能参数:
    1. -mode <BASIC (default) | CORE | ALL>:选择训练中使用的Haar功能集的类型。BASIC仅使用直立功能,而ALL使用全套垂直和45度旋转功能集。详见[104]
  • 局部二进制模式参数:局部二进制模式没有参数。

opencv_traincascade应用程序完成工作后,训练好的层叠将被保存在cascade.xml文件-data夹中。此文件夹中的其他文件是针对中断训练的情况而创建的,因此您可以在完成培训后将其删除。

训练完毕,你可以测试你的层叠分类器!

可视化层叠分类器

有时可以可视化已训练的层叠,看看它选择了哪些功能以及它的阶段是多么复杂。为此OpenCV提供了一个opencv_visualisation应用程序。此应用程序具有以下命令:

  • --image (必需):对象模型的引用图像的路径。这应该是一个注释,其尺寸[ -w,-h]传递给opencv_createsamples和opencv_traincascade应用程序。
  • --model (必需):训练模型的路径,它应该在提供给-dataopencv_traincascade应用程序参数的文件夹中。
  • --data (可选):如果提供了必须事先手动创建的数据文件夹,则会存储舞台输出和功能的视频。

下面可以看到一个示例命令

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

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

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

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

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

层叠分类器训练

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

层叠分类器训练

这项工作是由StevenPuttemans 为OpenCV 3 Blueprints创建的,但Packt Publishing同意将OpenCV整合。


层叠分类器
加载Caffe框架模型
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

OpenCV教程

OpenCV高级GUI和媒体(highgui模块)

OpenCV图像输入和输出(imgcodecs模块)

对象检测(objdetect模块)

计算摄影(照片模块)

图像拼接(拼接模块)

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }