前言

使用opencv自带的分类器效果并不是很好,由此想要训练自己的分类器,正好opencv有自带的工具进行训练。本文就对此进行展开。

步骤

1.查找工具文件;

2.准备样本数据;

3.训练分类器;

具体操作

注意,本文是在windows系统实现的,当然也可以在linux系统进行。

1.查找工具文件

opencv中的自带的分类器训练工具在开源库中以应用程序的类型呈现的,具体目录如下。

.\opencv2410\build\x64\vc12\bin

可以在该目录下查找到相关的工具文件,有opencv_createsamples、opencv_haartraining、opencv_performance、opencv_traincascade;

其中,opencv_haartraining和opencv_traincascade是opencv开源库用于训练级联分类器的两个程序。opencv_traincascade是一个较新的程序,使用OpenCV2.x API以c++编写,二者的主要区别是opencv_traincascade支持Haar和LBP两种特征,并易于增加其他特征。与Haar特征相比,LBP特征是整数特征,因此训练和检测过程都会比Haar特征快几倍。LBP和Haar特征用于检测的准确率是依赖训练过程中训练数据的质量和训练参数。训练一个与基于Haar特征同样准确度的LBP的分类器是可能的。

另外,opencv_traincascade和opencv_haartraining两个训练程序的输入参数有些微的差别,比如前者是numPos和numNeg,而后者是npos和nneg,同时二者所输出的分类器的文件格式也并不相同,注意区分。新的级联检测器接口(object模块中的CascadeClassifier类)支持这两种格式。opencv_traincascade可以旧格式导出训练好的级联分类器,但是在训练过程被中断后再重启训练过程时,二者不能装载和中断前不同的文件格式。另外,opencv_traincascade程序使用TBB(Threading Building Blocks)来处理多线程,如果希望使用多核并行运算加速,请使用TBB来编译opencv。

opencv_createsamples用来准备用于训练的正样本数据和测试数据,能够生成新旧两个训练程序支持的正样本数据。输出为以*.vec为扩展名的文件,该文件以二进制方式存储图像。

opencv_performance可以用来评估分类器的质量,但是只能评估opencv_haartraining输出的分类器。它读入一组标注好的图像,运行分类器并报告性能。

2.准备样本数据

训练需要一些样本数据,分别是正样本和负样本。负样本是指不包括目标的图像,正样本是只包含待检测目标的图像。负样本必须手工准备,而原始正样本可以使用opencv_createsamples创建训练器需要的正样本图像。样本图像可以是不同尺寸的,但是不能小于训练窗口的大小。

2.1样本数据要求;

正样本原始图像应该包含要检测的目标对象,比如人脸或者其他,而负样本图像不能包含要检测的目标。正样本图像的背景需要多样化,可以尝试用随机噪点填充背景,避免固定的背景。目标的像素数量肯定要多于背景像素数量的,原始正样本图像尺寸可以不同,但是应该有相同的高宽比。正负样本的格式、尺寸、通道数目可以不同,但是要保证尺寸不能小于训练的参数(即生成vec文件时输入的-w-h参数)。负样本不能包含目标,且应该多样化。正负样本的数目和比例的选取依赖于检测任务,建议在1:2-1:3之间,但这不是硬性规定的。建议开始使用小数目的样例生成级联器然后进行测试,如果效果不佳就可以增加正负样本数量。

2.2生成负样本描述文件;

负样本here(xte1);

在工程目录下,创建一个文件夹用于存放负样本图像,可以不同尺寸、不同通道数、不同格式,但尺寸不能小于正样本训练参数。负样本要尽量多样化,且不能包含要检测的目标对象。

负样本目录结构

/negimg
img1.jpg
img2.bmp
negimg.txt

其中,negimg.txt是负样本的描述文件,

E:\work\facedet\facedet-train\negall\GULF_99.bmp
E:\work\facedet\facedet-train\negall\u=,&fm=&gp=.jpg
E:\work\facedet\facedet-train\negall\u=,&fm=&gp=.jpg

生成方式是在图像目录下新建批量生成文件negimg.bat,双击即可;

dir /b/s/p/w *.bmp > num.txt

注意,1)不同的图像格式;       2)避免空行,将最后一行的空行删除;

2.3生成正样本描述文件*.vec;

2.3.1 创建文件夹的过程和负样本基本一样,此处不再赘述。生成正样本描述文件之后,打开描述文件,将jpg全部替换成jpg 1 0 0 20 20,其中jpg是图像格式,1表示对应图像中检测目标数目,[0 0 20 20]表示对应图像中目标位置分别是[left top width height];注意可以有多个目标,不同图像对应的目标数目和位置可能不同,可能需要分别处理;可以使用相对路径,也可以是绝对路径。

正样本描述文件将每张图像上的目标数目,以及每个目标对象的位置信息进行描述,按照以下格式描述。本质上讲,正样本描述文件是用来加速机器学习的。

positive_image_name  num_of_objects x y width height x y width height …

如果一张图像有多个目标,则文件内容为

img/img_with_faces_1.jpg
img/img_with_faces_2.jpg

2.3.2 生成*.vec正样本描述文件;

这个时候就要使用opencv_createsample生成vec文件啦!训练图像正样本目标尺寸的高宽参数一般设置为20*20或者24*24,本文设置为20*20.

opencv_createsamples.exe -vec pos.vec -info posimg.txt -num  -w  -h 

-vec是输出文件,内含用于训练的正样本;-info是描述目标所在图像及大小位置的描述文件;-num是生成正样本的数目(应该是所有图像中的目标数目吧?);

-w和-h是输出样本的目标尺寸,以像素为单位;

3.训练分类器

3.1 本文使用opencv_traincascade训练一个级联分类器。现在正负样本、正负样本描述文件都已准备好,开始进行训练,只需要设置想要的参数即可;

opencv_traincascade.exe -data xml -vec posall.vec -bg negall.txt -numPos  -numNeg  -mem  -mode ALL -w  -h 

其中,xml是存放训练结果的目录;注意,参数-w和-h应该与在生成.vec文件时候设置的-w和-h保持一致,同时写在-numPos和-numNeg的正负样本图像应该都是真正可用的,可打开的。各个参数的意义可参考here,有通用参数、级联参数、Boosted分类器参数、类Haar特征参数、LBP参数;

  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>

      训练的分类器的级数。一般取值15-25。

    • -precalcValBufSize <precalculated_vals_buffer_size_in_Mb>

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

    • -precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>

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

    • -baseFormatSave

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

  2. 级联参数:

    • -stageType <BOOST(default)>

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

    • -featureType<{HAAR(default), LBP}>

      特征的类型: HAAR - 类Haar特征; LBP - 局部纹理模式特征。

    • -w <sampleWidth>

    • -h <sampleHeight>

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

  3. 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。一般取值0.95-0.995。

    • -maxFalseAlarmRate <max_false_alarm_rate>

      分类器的每一级希望得到的最大误检率。总的误检率大约为 max_false_alarm_rate^number_of_stages.一般取值0.4-0.5。

    • -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.

  4. 类Haar特征参数:

    • -mode <BASIC (default) | CORE | ALL>

      选择训练过程中使用的Haar特征的类型。 BASIC 只使用右上特征, ALL 使用所有右上特征和45度旋转特征。

  5. LBP特征参数:

    LBP特征无参数。

训练完成之后,打开保存-data对应目录,即可看到训练结果。cascade.xml文件即为最终的训练结果,可以用来进行目标检测。

3.2训练过程相关问题;

问题1:

Train dataset for temp stage can not be filled. Branch training terminated.

原因:训练数据在中间训练阶段没有filled,训练分支被终止。此时可以生成cascade.xml文件,终止的原因是训练数据不足,一般已经训练了多个stage。

还有一个原因可能是图像数据的路径有问题,这种情况一般stage0即出现错误。

问题2:

Required leaf false alarm rate achieved. Branch training terminated

原因:负样本数据中包含要检测的目标对象,导致错误预警率过高。此时可以检查正负训练样本数据,是否有误。

接下来就要测试训练的模型能否得到较好的检测效果,请参看here。

参考

1.opencv人脸检测训练分类器及其常见问题-译文-Good

2.FAQ-opencv-haartraining-原文

3.人脸检测训练心得

4.opencv_traincascade支持Haar和LBP特征

5.如何使用opencv自带工具训练分类器

6.如何使用工具进行训练

7.如何训练详解

8.opencv中文论坛-级联分类器训练

9.opencv官网-原文

10.模型训练简介

【计算机视觉】如何使用opencv自带工具训练人脸检测分类器的更多相关文章

  1. opencv人脸检测分类器训练小结

    这两天在初学目标检测的算法及步骤,其中人脸检测作为最经典的算法,于是进行了重点研究.该算法最重要的是建立人脸检测分类器,因此我用了一天的时间来学习分类器的训练.这方面的资料很多,但是能按照一个资料运行 ...

  2. 基于AdaBoost算法——世纪晟结合Haar-like特征训练人脸检测识别

      AdaBoost 算法是一种快速人脸检测算法,它将根据弱学习的反馈,适应性地调整假设的错误率,使在效率不降低的情况下,检测正确率得到了很大的提高.   系统在技术上的三个贡献: 1.用简单的Haa ...

  3. opencv利用Cascade Classifier训练人脸检测器

    opencv默认提供了haar特征和lbp特征训练的人脸分类器,但是效果不太好,所以我们可以用opencv提供的跑opencv_traincascade函数来训练一个LBP特征的分类器.(由于open ...

  4. opencv 比较直方图方式 进行人脸检测对比

    完整opencv(emgucv)人脸.检测.采集.识别.匹配.对比 //成对几何直方图匹配               public static string MatchHist()         ...

  5. OpenCV神技——人脸检测,猫脸检测

    简介   OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 C 函数和少量 ...

  6. opencv 美白磨皮人脸检测<转>

    1. 简介 这学期的计算机视觉课,我们组的课程项目为“照片自动美化”,其中我负责的模块为人脸检测与自动磨皮.功能为:用户上传一张照片,自动检测并定位出照片中的人脸,将照片中所有的人脸进行“磨皮”处理, ...

  7. 基于OpenCV读取摄像头进行人脸检测和人脸识别

    前段时间使用OpenCV的库函数实现了人脸检测和人脸识别,笔者的实验环境为VS2010+OpenCV2.4.4,opencv的环境配置网上有很多,不再赘述.检测的代码网上很多,记不清楚从哪儿copy的 ...

  8. 如何利用OpenCV自带的级联分类器训练程序训练分类器

    介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...

  9. 如何用OpenCV自带的adaboost程序训练并检测目标

    参考博文: 1.http://blog.csdn.net/wuxiaoyao12/article/details/39227189 2.http://www.cnblogs.com/easymind2 ...

随机推荐

  1. Mysql 统计查询

    SELECT ub.telphone, SUM(IF(b.type = 1 AND b.level = 1, 1, 0)) AS type11, SUM(IF(b.type = 1 AND b.lev ...

  2. python里的apply,applymap和map的区别

    apply,applymap和map的应用总结: apply 用在dataframe上,用于对row或者column进行计算: applymap 用于dataframe上,是元素级别的操作: map  ...

  3. Java基础十一--多态

    Java基础十一--多态 一.多态定义 简单说:就是一个对象对应着不同类型. 多态在代码中的体现: 父类或者接口的引用指向其子类的对象. /* 对象的多态性. class 动物 {} class 猫 ...

  4. CentOS配置iptables规则并使其永久生效

    1. 目的 最近为了使用nginx,配置远程连接的使用需要使用iptable是设置允许外部访问80端口,但是设置完成后重启总是失效.因此百度了一下如何设置永久生效,并记录.  2. 设置 2.1 添加 ...

  5. Lightoj Halloween Costumes

    题意:给出要n个时间穿的服装.服装脱下就不能再穿.问最少要准备多少? dp[i][j]表示i到j之间最少花费.如果n=1(n指长度),肯定结果为1,n=2时,也很好算.然后n=3的时候dp[i][j] ...

  6. Andorid 之日历控件,可左右滑动,包含公历,农历,节假日等

    公司项目需要日历这个功能,经过查阅资料写了个demo,包含公历,农历,节假日等,还可左右滑动. 效果图: 代码: public class MainActivity extends AppCompat ...

  7. 『Json』常用方法记录

    json模块可以把字典结构改写为string然后保存,并可以反向读取字典 pickle模块则可以持久化任意数据结构 但是即使同样是字典数据结构,两个包也是有差别的, json字典value不支持其他对 ...

  8. hdu-1907-反nim博弈

    John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  9. create view

    create view View_count as SELECT     spkfk.spid, pf_ckmx.rq, pf_ckmx.spid AS Expr1, pf_ckmx.shl, spk ...

  10. python运维之使用python进行批量管理主机

    1. python运维之paramiko 2. FABRIC 一个与多台服务器远程交互的PYTHON库和工具 3. SSH连接与自动化部署工具paramiko与Fabric 4. Python批量管理 ...