OpenCV3训练分类器
一、简介
目标检测方法最初由Paul Viola [Viola01]提出,并由Rainer Lienhart [Lienhart02]对这一方法进行了改善。该方法的基本步骤为: 首先,利用样本(大约几百幅样本图片)的 harr 特征进行分类器训练,得到一个级联的boosted分类器。
分类器中的”级联”是指最终的分类器是由几个简单分类器级联组成。在图像检测中,被检窗口依次通过每一级分类器, 这样在前面几层的检测中大部分的候选区域就被排除了,全部通过每一级分类器检测的区域即为目标区域。
分类器训练完以后,就可以应用于输入图像中的感兴趣区域(与训练样本相同的尺寸)的检测。检测到目标区域(汽车或人脸)分类器输出为1,否则输出为0。为了检测整副图像,可以在图像中移动搜索窗口,检测每一个位置来确定可能的目标。为了搜索不同大小的目标物体,分类器被设计为可以进行尺寸改变,这样比改变待检图像的尺寸大小更为有效。所以,为了在图像中检测未知大小的目标物体,扫描程序通常需要用不同比例大小的搜索窗口对图片进行几次扫描。
目前支持这种分类器的boosting技术有四种: Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost。
“boosted” 即指级联分类器的每一层都可以从中选取一个boosting算法(权重投票),并利用基础分类器的自我训练得到。
根据上面的分析,目标检测分为三个步骤:
1、 样本的创建
2、 训练分类器
3、 利用训练好的分类器进行目标检测。
二、样本创建
训练样本分为正例样本和反例样本,其中正例样本是指待检目标样本(例如人脸或汽车等),反例样本指其它任意图片,所有的样本图片都被归一化为同样的尺寸大小(例如,24×24)。
负样本
负样本可以来自于任意的图片,但这些图片不能包含目标特征。负样本由背景描述文件来描述。背景描述文件是一个文本文件,每一行包含了一个负样本图片的文件名(基于描述文件的相对路径)。该文件必须手工创建。
正样本
正样本由程序opencv_createsamples程序来创建。该程序的源代码由OpenCV给出,并且在bin目录下包含了这个可执行的程序。
正样本可以由单个的目标图片或者一系列的事先标记好的图片来创建。
opencv_createsamples程序源码,有兴趣看一下,当然在OpenCV源码中也可以找到
https://github.com/opencv/opencv/tree/master/apps/createsamples
个人收集的正样本,贡献给大家:
https://download.csdn.net/upload/10931689
负样本:
https://download.csdn.net/upload/10931738
先创建一个文件夹traincascade
$ mkdir traincascade
将下载的正负样本放入traincascade文件夹
分别是pos 和 neg
将样本信息写入文件,这里用Python处理
创建文件createpositive.py
#!/usr/bin/env python3
import os
import cv2 as cv
POSTIVE_DIR = ‘pos/’
NEGATIVE_DIR = ‘neg/’
INFO_FILENAME = ‘info.dat’
BG_FILENAME = ‘bg.txt’
this_dir = os.path.abspath(os.path.dirname(__file__))
postive_url = os.path.join(this_dir, POSTIVE_DIR)
negative_url = os.path.join(this_dir, NEGATIVE_DIR)
# create info.dat
img_list = os.listdir(postive_url)
with open(os.path.join(this_dir, INFO_FILENAME), ‘wb’) as file:
for img_name in img_list:
img_url = os.path.join(postive_url, img_name)
img = cv.imread(img_url)
cols, rows = img.shape[:2]
file.write( bytes(POSTIVE_DIR + img_name + ‘ 1 0 0 %s %s\n’ % (str(cols), str(rows)),’UTF-8′))
# create bg.txt
img_list = os.listdir(negative_url)
with open(os.path.join(this_dir, BG_FILENAME), ‘wb’) as file:
for img_name in img_list:
file.write( bytes(negative_url + img_name + ‘\n’, ‘UTF-8’))
这里正样本用的相对路径,负样本使用绝对路径
运行程序 python3 createpositive.py
生成 bg.txt info.dat
下一步生成正样本:
$ opencv_createsamples -info info.dat -vec train.vec -num 5061 -w 24 -h 24
成功,生成正样本文件 train.vec
参数解释如下:
命令行参数:
-
-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>
:输出样本的高度(以像素为单位)。
注:正样本也可以从一个预先标记好的图像集合中获取。这个集合由一个文本文件来描述,类似于背景描述文件。每一个文本行对应一个图片。每行的第一个元素是图片文件名,第二个元素是对象实体的个数。后面紧跟着的是与之匹配的矩形框(x, y, 宽度,高度)。
三. 训练分类器
下一步是基于事先准备的正负数据集训练级联分类器。
opencv_traincascade应用程序的命令行参数:
参考
https://blog.csdn.net/giantchen547792075/article/details/7404261
县创建输出文件夹output
$ mkdir output
运行命令训练
$ opencv_traincascade -data output -vec train.vec -bg bg.txt -numPos 1000 -numNeg 2000 -numStages 15 -w 24 -h 24
cascade.xml文件即为最终的训练结果,即可拿来进行目标检测;参考上一篇文章。
关于命令行参数解释:
按目的分组的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
:这个论点在类似哈尔特征的情况下是实际的。如果已指定,则级联将以旧格式保存。这仅用于向后兼容性原因,并允许用户坚持旧的已弃用接口,至少使用较新的接口训练模型。 -
-numThreads <max_number_of_threads>
:训练期间使用的最大线程数。请注意,实际使用的线程数可能会更低,具体取决于您的计算机和编译选项。默认情况下,如果您使用TBB支持构建OpenCV,则会选择最大可用线程,这是此优化所需的。 -
-acceptanceRatioBreakValue <break_value>
:此参数用于确定模型应该保持学习的准确程度以及何时停止。一个好的指导方针是训练不超过10e-5,以确保模型不会超过您的训练数据。默认情况下,此值设置为-1以禁用此功能。
-
-
级联参数:
-
-stageType <BOOST(default)>
:阶段类型。目前仅支持增强分类器作为阶段类型。 -
-featureType<{HAAR(default), LBP}>
:特征类型:HAAR – 类似Haar的特征,LBP – 本地二进制模式。 -
-w <sampleWidth>
:训练样本的宽度(以像素为单位)。必须具有与创建训练样本期间使用的值完全相同的值(opencv_createsamples实用程序)。 -
-h <sampleHeight>
:训练样本的高度(以像素为单位)。必须具有与创建训练样本期间使用的值完全相同的值(opencv_createsamples实用程序)。
-
-
提升的分类参数:
-
-bt <{DAB, RAB, LB, GAB(default)}>
:增强分类器的类型:DAB – 离散AdaBoost,RAB – Real AdaBoost,LB – LogitBoost,GAB – Gentle AdaBoost。 -
-minHitRate <min_hit_rate>
:分类器的每个阶段的最小期望命中率。总体命中率可以估计为(min_hit_rate ^ number_of_stages),
[164]
§4.1。 -
-maxFalseAlarmRate <max_false_alarm_rate>
:分类器的每个阶段的最大期望误报率。总体误报率可估计为(max_false_alarm_rate ^ number_of_stages),
[164]
§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度旋转功能。有关详细信息,请参见
[97]
。
-
- 本地二进制模式参数:本地二进制模式没有参数。
在opencv_traincascade应用程序完成其工作后,经过训练的级联将保存在
cascade.xml
文件
-data
夹中的文件中。此文件夹中的其他文件是针对中间训练阶段创建的,在完成训练后删掉即可。