Java机器学习库(OpenCV)(训练人脸识别级联分类器)

样本

正样本

正样本是待检测的物体的图像。

正样本由opencv_createsamples工具生成。正样本可以由包含待检测物体的一张图片生成,也可由一系列标记好的图像生成。如果只有一张包含物体的图像,如一个公司的标志,那么可以通过对物体图像的随机旋转、改变标志亮度以及将标志放在任意的背景上而获得大量的正样本。生成的正样本数目以及随机的程度都可以通过 opencv_createsamples 的命令行参数控制。

需要注意的是你需要提供一个很大的负样本库给训练程序进行训练。如果是绝对刚性的物体,如一个公司的LOGO,你只有一张正样本图像;如果是人脸,你需要几百甚至几千个正样本。在待检测物体是人脸的情况下,你还需要考虑所有的人种、年龄、表情甚至胡子的样式。这些图像可以是不同的尺寸,但是图像尺寸应该比训练窗口的尺寸大,因为这些图像将被用于抠取负样本,并将负样本缩小到训练窗口大小。

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

负样本

负样本是指不包括物体的图像。负样本和样本图像也叫做背景样本,或者背景样本图像。

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

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_traincascade 和 opencv_haartraining 都可用来训练一个级联分类器。由于opencv_haartraining的用法与 opencv_traincascade 类似,所以我们此处只介绍 opencv_traincascade。

opencv_traincascade命令行参数

  1. 通用参数

-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>  每级分类器训练时所用的负样本数目,可以大于 -bg 指定的图片数目。

-numStages <number_of_stages>  训练的分类器的级数。

-precalcValBufSize <precalculated_vals_buffer_size_in_Mb>  缓存大小,用于存储预先计算的特征值(feature values),单位为MB。

-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>  缓存大小,用于存储预先计算的特征索引(feature indices),单位为MB。内存越大,训练时间越短。

-baseFormatSave  这个参数仅在使用Haar特征时有效。如果指定这个参数,那么级联分类器将以老的格式存储。

  1. 级联参数

-stageType <BOOST(default)>  级别(stage)参数。目前只支持将BOOST分类器作为级别的类型。

-featureType<{HAAR(default), LBP}>      特征的类型: HAAR - 类Haar特征; LBP - 局部纹理模式特征。

-w <sampleWidth>

-h <sampleHeight>  训练样本的尺寸(单位为像素)。必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致。

  1. Boosted参数

-bt <{DAB, RAB, LB, GAB(default)}>    Boosted分类器的类型: DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost。

-minHitRate <min_hit_rate>    分类器的每一级希望得到的最小检测率。总的检测率大约为 min_hit_rate^number_of_stages。

-maxFalseAlarmRate <max_false_alarm_rate>  分类器的每一级希望得到的最大误检率。总的误检率大约为 max_false_alarm_rate^number_of_stages.

-weightTrimRate <weight_trim_rate>    Specifies whether trimming should be used and its weight. 一个还不错的数值是0.95。

-maxDepth <max_depth_of_weak_tree>   弱分类器树最大的深度。一个还不错的数值是1,是二叉树(stumps)。

-maxWeakCount <max_weak_tree_count>  每一级中的弱分类器的最大数目。The boosted classifier (stage) will have so many weak trees (<=maxWeakCount), as needed to achieve the given -maxFalseAlarmRate.

  1. 类Haar特征参数

-mode <BASIC (default) | CORE | ALL>   训练过程中使用的Haar特征的类型。 BASIC 只使用右上特征, ALL 使用所有右上特征和45度旋转特征。

当opencv_traincascade程序训练结束以后,训练好的级联分类器将存储于文件cascade.xml中,这个文件位于 -data 指定的目录中。这个目录中的其他文件是训练的中间结果,当训练程序被中断后,再重新运行训练程序将读入之前的训练结果,而不需从头重新训练。训练结束后,你可以删除这些中间文件。

工作空间目录结构

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

构建正样本

第一步:

创建posdir.bat文件内容如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

双击posdir.bat执行,得到正样本中间文件pos.dat,使用文本编辑器打开pos.dat可以看到如下内容:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

第二步:

将.jpg替换成.jpg 1 0 0 20 20(1代表该图片上有一个样本,top=0,left=0,width=20,height=20)如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

第三步:

       创建opencv_createsamples.bat文件内容如下:

opencv_createsamples.exe -info pos.dat -vec pos.vec -num 18586 -w 20 -h 20

pause

双击opencv_createsamples.bat执行,得到正样本文件pos.vec。

构建负样本

与正样本第一步类似,创建negdir.bat文件内容如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

双击negdir.bat执行,得到正样本中间文件neg.dat,使用文本编辑器打开neg.dat可以看到如下内容:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

训练

创建opencv_traincascade.bat文件内容如下:

opencv_traincascade.exe -data data -vec pos.vec -bg neg.dat -numPos 3500-numNeg 10000-numStages 16 -minhitrate 0.99 -maxfalsealarm 0.5 -mode ALL -w 20 -h 20

pause

双击negdir.bat开始训练。

训练过程如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

注:为了尽快得出结果,笔者并没有使用上述中的参数进行训练,而是减小了每次训练的样本数量。这样做的缺点是:训练的结果定位目标物体不够准确。

opencv_traincascade.exe -data data -vec pos.vec -bg neg.dat -numPos 350 -numNeg 900 -numStages 16 -minhitrate 0.99 -maxfalsealarm 0.5 -mode ALL -w 20 -h 20

pause

训练结果如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

除cascade.xml之外其他全部是训练产生的中间文件,cascade.xml就是我们要的结果,内容如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

使用训练的结果进行人脸识别

Java机器学习库(OpenCV)(训练人脸识别级联分类器)

识别结果如下:

Java机器学习库(OpenCV)(训练人脸识别级联分类器)