级联分类器训练引言级联分类器的工作主要包括两个阶段:训练和检测。检测阶段被描述在一个常规的OpenCV文件的objdetect模块的文档里。文档介绍了级联分类器的一些基本信息。目前的指南描述了如何训练级联分类器:一个训练数据集和运行训练应用程序的准备。重要的笔记在OpenCV里有两个应用程序可以用来训练级联分类器:opencv_haartraining和opencv_traincascade。opencv_traincascade是一个较新的版本,用C++按照OpenCV2.xAPI的标准编写。但这两个应用程序之间的主要区别是,opencv_traincascade同时支持Haar[Viola2001]和LBP[Liao2007](局部二值模式)的特征。相比于Haar特征,LBP特征是整数,所以用LBP训练和检测比用Haar特征快好几倍。至于LBP和Haar的检测质量取决于训练:首先是训练数据集的品质还有训练参数。训练一个和基于Haar的分类有几乎相同的质量的基于LBP的分类是有可能的。opencv_traincascade和opencv_haartraining以不同的文件格式存储训练好的分类器。值得注意的是,较新的级联检测接口(见objdetect模块的级联分类器类)两种格式都支持。opencv_traincascade可以用旧格式保存(输出)训练好的级联。但opencv_traincascade和opencv_haartraining无法在中断后以另一种格式加载(输入)一个分类器来进一步训练。注意,opencv_traincascade应用程序可以使用TBB实现多线程。在多核模式下使用,OpenCV必须要用TBB来构建。并且这有一些和训练相关的辅助工具。·opencv_createsamples是用来准备正训练数据集和测试样本集的。opencv_createsamples产生一个opencv_haartraining和opencv_traincascade都支持的格式的正样本数据集。输出的是一个以*.VEC为后缀的文件,它是一种包含图像的二进制格式。·opencv_performance可用于评估分类器的质量,但是只能评估opencv_haartraining的训练。它需要一个图像标记的集合,运行分类器并且报告性能,即找到的对象的数量,没有对象的数量,错误警报的数量等信息。因为opencv_haartraining是一个过时的应用,只对opencv_traincascade进行进一步的讲解。为opencv_traincascade准备训练数据时opencv_createsamples工具是必需的,所以它也将被详述。opencv_createsamples工具一个opencv_createsamples工具提供了数据集的生成功能,写和读,用数据集这个术语作为训练集和测试集的统称。训练数据准备为了训练我们需要一组样本。有两种类型的样品:正和负。负样本对应于非目标图像。正样本对应于包含了被测物体的图像。集负样本必须手动创建,而一组正样本由opencv_createsamples工具创建。负样本负样品来自任意图像。这些图像必须不包含被检测对象。负样本被放在一个特殊的文件里。这是一个在它的每一行包含一个负样本图像的文件名的文本文件(相对于描述文件的目录)。这个文件必须手动创建。注意,负样本和样本图像也被称为背景样本或背景样本图像,并在此文件中是可交换的。被描述的图像可以具有不同的尺寸。但每个图像应该是(但不一定)大于训练窗口的大小,因为这些图像被用来进行再次抽取,变成具有训练尺寸的负面图像。描述文件的一个实例:目录结构:/imgimg1.jpgimg2.jpgbg.txt文件bg.txtimg/img1.jpgimg/img2.jpg正样本正样本用opencv_createsamples工具来创建。他们可能是从一个包含对象的单帧图像或先前标记的图像的集合中创建。请注意,你需要一个大的正样本数据集把它送给你之前提到的工具,因为它只适用于透视变换。例如,你可能只需要一个正样本,像opencv标志这样的一个明显的规则物体,但对于面孔这样的,你绝对需要成百上千个正样本。在面孔的这种情况下,你应该考虑所有的种族和年龄组,情绪又或者胡子的风格。因此,一个单帧的物体图像可能包含公司徽标。那么一大组的正样本被通过随机旋转从而给定的对象的图像创造,改变标志的强度以及放置标志的任意背景的数量和范围的随机性可以通过opencv_createsamples工具的命令行参数控制。命令行参数:-vecvec_file_name输出文件的名字中包含正的训练样本。-imgimage_file_name源对象的图像(如,公司标志)。-bgbackground_file_name背景描述文件;列出了作为背景的随机扭曲版本的对象的图像。-numnumber_of_samples产生正样本的数量-bgcolorbackground_color背景颜色(目前灰度图像被假定);背景颜色为透明色。因为可能有压缩失真,颜色容错的数量可以通过-bgthresh被指定。所有像素在bgcolor-bgthresh到bgcolor+bgthresh的范围内被认为是透明的。-bgthreshbackground_color_threshold-inv如果指定,颜色取反。-randinv如果指定,颜色将随机取反。-maxidevmax_intensity_deviation在最突出的样本像素的最大强度偏差。-maxxanglemax_x_rotation_angle-maxyanglemax_y_rotation_angle-maxzanglemax_z_rotation_angle给最大旋转角度一定的弧度。-show有用的调试选项。如果指定,每个样品将被显示。按ESC键结束创建样本过程。-wsample_width宽度(像素)的输出样本。-hsample_height高度(像素)的输出样本。-pngoutput使用此选项打开opencv_createsamples工具生成一个PNG样本集合和大量相关注释文件,而不是一个单一的vec(矢量)文件。opencv_createsamples工具可以以多个模式工作,即:从一个单一的图像和一个背景的集合中创建训练集:以一个单一的VEC文件作为输出;以一个JPG图片集合和注释列表文件作为输出;以一个的PNG图像集合和相关的文件注释作为输出;将采集样品标记为VEC格式;显示vec文件的内容。从一个单一的图片和背景的集合中创建训练集并以一个单一的VEC文件作为输出下面的程序是一个用来创建一个样本对象的实例:源图像被随机的绕着三个轴旋转。选择的角度被-max?angle限制。然后在[bg_color-bg_color_threshold;bg_color+bg_color_threshold]强度范围内的像素解释为透明。白噪声添加到前景的强度上。如果-inv参数被指定然后指定前景像素强度取反。如果-randinv的值被指定随后指定算法随机选择是否在该样本上进行取反。最后,得到的图像放置到从背景描述文件中任意抽取出的背景上,调整到所需的大小,通过-w和-h来指定随后存储到通过命令行选项指定的VEC文件中。创建训练集作为一个PNG图像的集合为了获得这种行为,-img,-bg,-info和-pngoutput键值应指定。用-info的键值指定文件名,应包括至少一个水平层次的目录,该目录将作为训练集的顶层目录。例如,调用opencv_createsamples如下所示:opencv_createsamples-img/home/user/logo.png-bg/home/user/bg.txt-info/home/user/annotations.lst-pngoutput-maxxangle0.1-maxyangle0.1-maxzangle0.1输出将具有以下结构:/home/user/annotations/0001_0107_0099_0195_0139.txt0002_0107_0115_0195_0139.txt...neg/backgroundfilesherepos/0001_0107_0099_0195_0139.png0002_0107_0115_0195_0139.png...annotations.lst在TXT格式的注释目录里包含样品中关于以下一个文件格式的对象包围盒的信息:Imagefilename:/home/user/pos/0002_0107_0115_0195_0139.pngBoundingboxforobject1PASperson(Xmin,Ymin)-(Xmax,Ymax):(107,115)-(302,254)创建测试集设置为JPG图像的集合这种变异的用法非常类似于上一个,但是以不同的格式产生输出;获得这样的行为-img,-bg和-info的值应指定。例如,调用opencv_createsamples如下:opencv_createsamples-img/home/user/logo.png-bg/home/user/bg.txt-infoannotations.lst-maxxangle0.1-maxyangle0.1-maxzangle0.1目录结构:info.datimg1.jpgimg2.jpg文件info.datimg1.jpg11401004545img2.jpg2100200505050302525将样品的标记集合变为VEC格式正样本也可以从之前的标记图像集合中获得。这个系列是由一个类似背景描述文件的文本文件描述。此文件的每一行对应一个图像。该行的第一个元素是文件名。其次是对象实例的数量。下面的数字是对象的边界矩形的坐标(x,y,宽度,高度)。描述文件的一个实例:目录结构:/imgimg1.jpgimg2.jpginfo.dat文件info.dat:img/img1.jpg11401004545img/img2.jpg2100200505050302525图像img1.jpg包含单独的对象实例的边框坐标:(140,100,45,45)。图像img2.jpg包含两个对象实例。为了从这样的集合建立正样品,-info应该被指定而非-IMG:-infocollection_file_name文件标注图像集合的描述。在这种情况下,样品的创建的方案如下。对象的实例是从图像中采集。然后调整到目标样本的大小和存储在输出的矢量文件。应用不变形,所以唯一的影响参数是-w,-h,-show和-num.显示VEC(矢量)文件内容opencv_createsamples工具可用于检查存储在正样本文件中的样本。为了做到这点,只有-vec,-w和-h的参数应被指定。为了训练要注意的是,怎样生成带有正样本的vec文件不重要。但opencv_createsamples工具是唯一能通过OpenCV收集/创建一个正样本矢量文件的方式,。可以在这里找到VEC文件的例子opencv/data/vec_files/trainingfaces_24-24.vec它可以用下面的窗口大小训练的人脸检测:-w24-h24。级联训练下一步是分类器的训练。正如上面提到的opencv_traincascade或opencv_haartraining可以用来训练一个级联分类器,但只有较新的opencv_traincascade被将进一步描述。对opencv_traincascade应用程序的命令行参数进行有目的归类:常见的参数:-datacascade_dir_name被训练好的分类器应该被存储在哪里。-vecvec_file_name带有正样本的VEC文件(由opencv_createsamples工具创建的)。-bgbackground_file_name背景描述文件。-nu