OpenCV Python 级联分类器训练
【介绍】
使用增强的弱分类器级联包括两个主要阶段: 训练和检测阶段。使用基于HAAR或LBP模型的检测,在object detection tutorial中进行了描述。本文档概述了训练您自己的增强弱分类器级联所需的功能。当前的手册将走过所有不同的阶段: 收集训练数据,准备训练数据和执行实际的模型训练。
为了支持本教程,将使用几个官方OpenCV应用程序: opencv_createsamples, opencv_annotation, opencv_traincascade and opencv_visualisation.
自OpenCV 4.0起,createsample和traincascade被禁用。考虑使用这些应用程序从3.4分支训练级联分类器。模型格式在3.4和4.x之间是相同的。
- 如果你遇到任何教程提到旧的
opencv_haartraining
工具(它已弃用,仍在使用OpenCV1.X 接口),然后请忽略该教程,并坚持使用opencv_traincascade
工具。该工具是一个较新的版本,根据OpenCV 2.x
和OpenCV 3.x
的API。opencv_traincascade
支持HAAR类小波特征和LBP
(局部二进制模式)特征。与HAAR
特征相比,LBP
特征产生整数精度,产生浮点精度,因此使用LBP
的训练和检测都比使用HAAR
特征快几倍。对于LBP
和HAAR
的检测质量,主要取决于使用的训练数据和选择的训练参数。在一定百分比的训练时间内,训练一个基于lbp
的分类器可以提供几乎与基于haar
的分类器相同的质量。OpenCV 2
中更新的级联分类器检测接口。OpenCV 2.x 和 OpenCV 3.x (cv::CascadeClassifier)支持使用新旧模型格式。Opencv_traincascade
甚至可以以旧格式保存(导出)训练好的级联,如果由于某种原因您无法使用旧的接口。至少训练模型可以在最稳定的接口中完成。opencv_traincascade
应用程序可以使用TBB
进行多线程。为了在多核模式下使用它,OpenCV必须在构建时启用TBB
支持。
【数据准备】
为了训练增强的级联弱分类器,我们需要一组正样本(包含您想检测的实际对象)和一组负图像(包含您不想检测的所有内容)。负样本集必须手动准备,而正样本集是使用 opencv_createssamples
应用程序创建的。
负样本
负样本取自任意图像,不包含要检测的对象。这些生成样本的负图像应该列在一个特殊的负图像文件中,每行包含一个图像路径(可以是绝对的或相对的)。请注意,负样本和样本图像也称为背景样本或背景图像,在本文档中可互换使用。
所描述的图像可能大小不同。然而,每个图像都应该等于或大于所需的训练窗口大小(对应于模型维度,大多数时候是对象的平均大小),因为这些图像用于将给定的负图像子抽样到具有此训练窗口大小的多个图像样本中。
一个这样的负样本描述文件的例子:
目录结构:
/img
img1.jpg
img2.jpg
...
bg.txt
文件 bg.txt
img/img1.jpg
img/img2.jpg
...
这些负样本主要就是告诉机器,这些样本将不被接受,在检测时会忽略掉。
正样本
正样本是由 opencv_creatsamples
应用程序创建的。它们被用于训练,告诉程序该识别哪些目标。该应用程序支持两种生成正样本数据集的方法。
-
- 你可以从单个正样本图像中生成一堆正样本图像。
-
- 你可以自己提供所有的正样本,只需要使用工具把它们剪下来,调整大小,然后把它们放在opencv需要的二进制格式中。
虽然第一种方法适用于固定物体,比如非常僵硬的logo,但它往往很快就会不适用于不那么僵硬的物体。在这种情况下,我们建议使用第二种方法。web上的许多教程甚至指出,通过使用 opencv_createssamples
应用程序,100
个真实物体图像可以产生比 1000
个人工生成的阳性更好的模型。如果你决定采用第一种方法,请记住以下几点:
- 请注意,在将其提供给上述应用程序之前,您需要多个正样本,因为它只应用透视图转换。
- 如果您想要一个健壮的模型,那么就采取涵盖对象类中可能出现的各种类型的样本。例如,对于人脸,你应该考虑不同的种族和年龄群体,情绪,也许还有胡须风格。这也适用于使用第二种方法。
第一种方法取一个带有公司标志的物体图像,通过随机旋转物体,改变图像强度以及将图像放置在任意背景上,从给定的物体图像中创建大量正样本。随机的数量和范围可以通过 opencv_createssamples
应用程序的命令行参数来控制。
参数如下:
-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 有一个目标,而图像 img2.jpg 有两个目标;
为了创建正样本, -info
代替 -img
;
…
opencv 自带的标注工具
从OpenCV 3.x 开始 社区一直在提供和维护一个开源标注工具,用于生成 -info
文件。如果构建OpenCV应用程序,可以通过 opencv_annotation
命令使用该工具。
使用该工具也是很直接的,有如下几个参数:
--annotations
(required) : 标注文件的路径[example - /data/annotations.txt]
--images
(required) : 包含图像的路径[example - /data/testimages/]
--maxWindowHeight
(optional) : 如果输入图像很大,可以进行调整高度--resizeFactor
(optional) : 调整图像缩放比例
opencv_annotation --annotations=/path/to/annotations/file.txt --images=/path/to/image/folder/
按键
- c: 确认标注和保存数据
- d: 删除上一个标注信息
- n: 下一张图片
- ESC: 退出软件
【训练】
下一步是基于事先准备好的正数据集和负数据集,对增强的级联弱分类器进行实际训练。
opencv_traincascade
应用程序的命令行参数按目的分组:
-
Common arguments:
-data <cascade_dir_name>
: 训练的分类器存储的位置,-vec <vec_file_name>
: 正样本-bg <background_file_name>
: 负样本描述文件-numPos <number_of_positive_samples>
: 每个分类器训练阶段的正样本数-numNeg <number_of_negative_samples>
: 每个分类器训练阶段的负样本数-numStages <number_of_stages>
: 训练的 stages 数量-precalcValBufSize <precalculated_vals_buffer_size_in_Mb>
: 缓冲区的大小(单位 Mb),内存越大,训练越快-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>
: 预计算的特征索引缓冲区大小,单位Mb,越大,训练越快-baseFormatSave
: 该参数实际在haar类特性的情况下使用的。如果指定该参数,级联将以旧格式保存。这只适用于向后兼容的原因,并允许用户坚持使用旧的已弃用的接口,至少可以使用更新的接口来训练模型。-numThreads <max_number_of_threads>
: 训练期间使用的最大线程数。注意,实际使用的线程数可能更低,这取决于您的机器和编译选项。默认情况下,如果您构建了支持TBB的OpenCV,则会选择最大可用线程,这是优化所需要的。-acceptanceRatioBreakValue <break_value>
:此参数用于确定您的模型应该保持学习的精确程度以及何时停止学习。一个很好的指导方针是训练不超过10e-5,以确保模型不会过度训练你的训练数据。默认情况下,该值被设置为-1以禁用该特性。
-
Cascade parameters:
-stageType <BOOST(default)>
: 阶段类型。目前只支持增强的分类器作为阶段类型。-featureType<{HAAR(default), LBP}>
: 特征类型:HAAR - HAAR样特征,LBP -局部二进制模式。-w <sampleWidth>
:训练样本的宽度(单位:像素)。必须与创建训练样本时使用的值完全相同(opencv_createsamples实用程序)。-h <sampleHeight>
:训练样本的高度(像素)。必须与创建训练样本时使用的值完全相同(opencv_createsamples实用程序)。
-
Boosted classifier parameters:
-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) [263] §4.1.-maxFalseAlarmRate <max_false_alarm_rate>
: 分类器每个阶段期望的最大误报率。总体误报率可估计为(max_false_alarm_rate ^ number_of_stages), [263] §4.1.-weightTrimRate <weight_trim_rate>
: 指定是否应该使用微调及其权重。一个不错的选择是0.95-maxDepth <max_depth_of_weak_tree>
: 弱树的最大深度。一个体面的选择是1,那是树桩的情况。-maxWeakCount <max_weak_tree_count>
: 每个级联阶段弱树的最大计数。增强的分类器(阶段)将有许多弱树(<=maxWeakCount),以实现给定的-maxFalseAlarmRate。
-
Haar-like feature parameters:
-mode <BASIC (default) | CORE | ALL>
: 选择用于训练的Haar特征集的类型。 BASIC 使用直立特征, ALL 使用所有的特征,包括 45度旋转特征,See [149] for more details.
-
Local Binary Patterns parameters: 局部二进制模式没有参数。
在opencv_traincascade
应用程序完成其工作后,训练好的级联分类器模型将保存在-data文件夹中的cascade.xml
文件中。该文件夹中的其他文件是为训练中断而创建的,请在训练结束后删除。
训练结束,你可以测试你的级联分类器!
【可视化】
在级联训练过程中,可视化总是有用的,可以看到哪些特征被选择了,以及每一个 stage 的复杂度,OpenCV
提供了一个 opencv_visualisation
软件,命令如下:
–image (required) : 目标模型测试用的图片
–model (required) : 训练的模型的路径
–data (optional) : 如果提供了一个数据文件夹(必须事先手动创建),则将存储每个阶段的输出,
opencv_visualisation --image=/data/object.png --model=/data/model.xml --data=/data/result/
当前可视化工具的一些局限性
- 只处理用
opencv_traincascade
工具训练的级联分类器模型,包含树桩作为决策树[默认设置]。 - 所提供的图像需要是一个具有原始模型尺寸的示例窗口,并传递给——image参数。
HAAR/LBP人脸模型的例子运行在给定的安吉丽娜·朱莉的窗口上,它有与级联分类器文件相同的预处理- >24x24像素图像,灰度转换和直方图均衡化:
制作了一个视频,每个阶段的每个特征都可视化了:
每个阶段保存成一个图像用于将来特征的验证。
【参考】
- OpenCV: Cascade Classifier Training