opencv训练分类器随笔

一、Opencv训练分类器一般要使用到OpenCV提供的几个工具:

opencv_annotation 用来在一张大图中标定一个或多个需要检测的目标
opencv_createsamples 用来制作positive sample的vec
opencv_traincascade 用来训练得到需要的cascade.xml


二、Opencv训练流程

  1. 收集需要训练的正、负样本。
  2. 对正样品归一化处理,负样本不处理,但是保证负像素尺寸 >=正样品像素尺寸(或者有的人也称作缩放处理,不过我感觉还是归一化处理比较好听)。
  3. 生成正、负样本描述文件。
  4. 样本训练。

2.1 收集样本

样本分两种: 正样本与负样本(也有人翻译成:正例样本和反例样本),其中正样本是指待检目标样本(例如人脸,汽车,鼻子等),负样本指其它任意图片。


负样本(Negtive Samples)

  • 注意点:

    1. 不应该包含所需检测的目标,不过可以是目标的一小部分,这样可以避免误检测;
    2. 必须大于等于窗口(即Positive Samples中的窗口大小,用-w -h两个参数指定的)的尺寸;
    3. 每一张negtive sample的大小不必相同
  • 描述文件 bg.txt(这个名字随意了,我只是按照官方的命名来的):

    1. 内容为negtive sample的文件名,每一行对应一个文件名,不应有空行;
    2. 根据bg.txt所处的位置,其内容也有变化。在bg.txt与opencv_traincascade处于同一目录的情况下bg.txt中每一行应该为negtive sample的绝对路径,例如:/home/allen/haar/neg/1.jpg
    3. 如果bg.txt是在Windows下生成的,而后拿到Linux下来使用,在执行opencv_traincascade后可能会报错Train dataset for temp stage can not be filled. Branch training terminated. 这是因为Windows和Linux中换行的符号是不同的,Windows下为\r\n, Linux下为\n. 解决方法是在Linux下重新生成bg.txt. 可以使用Python来生成
fp = open('/home/allen/bg.txt', 'w')
for i in range(1, 732): 
    fp.write('/home/allen/haar/neg/' + str(i) + '.jpg' + '\n')
fp.close()

总之,如果在执行opencv_traincascade后报的错为Train dataset for temp stage can not be filled. Branch training terminated.,则问题是出在bg.txt上了,导致程序无法找到对应的negtive samples。参考上述2,3两点进行修改。


正样本(Positive Samples)

创建的几个步骤:

  1. 准备自己拍的各种包含被检测物体的大图
  2. 使用opencv_annotation进行矩形框标定被检测物或者手动抠图正负描述文件
  3. 归一化处理
  4. 使用opencv_createsamples生成.vec文件
详解步骤1:这个不用多说,自己拍去吧,数量自己定
详解步骤2:
  • 使用命令:

opencv_annotation -annotations /home/allen/haar/pos/annotation.txt -images /home/allen/haar/grayImages

  对该命令的解释:

-annotations annotation文件的存储位置
-images 步骤1中图片的位置

opencv_annotation运行程序的时候会遍历文件夹下所有的图片,每次显示一张图片,点击鼠标左键,拖动鼠标确定区域,再点一次鼠标左键,结束。按键盘的字母C为确定选择(矩形框会由红色变为绿色),字母D为删除上一个选择,字母N为下一张图片。注意,程序之后在所有图片都遍历完后才会创建annotation.txt文件,中途退出是没有的。

正:
这里写图片描述

跟这里一样,第一列表示图片的名字,第二列表示该图片中有多少个正样例,一般为1,如果有很多(比如在人群中有很多人脸),那么有多少个这个参数就写几,比如是K个,那么接下来就要有4*k个数据,也就是k组数据,每组数据是这样的:x y width height。

负:
这里写图片描述
仅仅需要图片名字,不需要参数:

详解步骤3:归一化处理

这个是一个必要条件,当分类器在你想要检测的图片上寻找目标的时候,它不能所有位置、所有大小都各种乱找,那样一张图片的执行次数就会相当的巨大,而且如果正样品的大小不统一,那么彼此之间也就没有太大的可比性和联系性了,所谓归一化处理,就是让所有图片的像素尺寸一样,比如我的正样品全部是64*64像素的,处理方法,可以看看该大神的文章:http://www.cnblogs.com/tornadomeet/archive/2012/03/27/2420088.html

详解步骤4:

  首先使用命令:

opencv_createsamples -vec /home/allen/haar/pos/positive.vec -info /home/allen/haar/pos/annotation.txt -w 24 -h 50 -num 400

  对该命令的解释:

-vec  参数代表.vec文件的存储位置;
-img  输入图像文件名(例如一个公司的标志)。
-info  代表生成的annotation的位置;
-bg   背景图像的描述文件,文件中包含一系列的图像文件名,这些图像将被随机选作物体的背景。
-num  生成的正样本的数目
-w 窗口的宽度;
-h 窗口的高度;
-num 需要生成的positive samples的个数。

这里需要注意annotation.txt中图片名的格式,不需要包含路径,同时需要与positive samples在同一文件夹下。例如105.jpg 2 112 89 18 34 93 87 18 34,第一个是文件名,第二个代表在该张图片中被标记物体的个数,之后的四个数为对应矩形标记框在这张图片中的坐标位置。

2.2 训练级联分类器

下一步是训练分类器。如前面所述, opencv_traincascade 和opencv_haartraining 都可用来训练一个级联分类器,但是此处只介绍opencv_traincascade 。 opencv_haartraining 的用法与opencv_traincascade 类似。

下面是 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>
        每级分类器训练时所用的负样本数目,可以大于 -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特征时有效。如果指定这个参数,那么级联分类器将以老的格式存储。

级联参数:

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

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

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

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.

类Haar特征参数:
    -mode<BASIC(default)|CORE|ALL>
        选择训练过程中使用的Haar特征的类型。 BASIC 只使用右上特征, ALL 使用所有右上特征和45度旋转特征。更多细节请参考[Rainer2002] 。

LBP特征参数:
LBP特征无参数。

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

训练结束后,你就可以测试你训练好的级联分类器了!
[Viola2001] Paul Viola, Michael Jones. Rapid Object Detection using a Boosted Cascade of Simple Features. Conference on Computer Vision and Pattern Recognition (CVPR), 2001, pp. 511-518.
[Rainer2002] Rainer Lienhart and Jochen Maydt. An Extended Set of Haar-like Features for Rapid Object Detection. Submitted to ICIP2002.
[Liao2007] Shengcai Liao, Xiangxin Zhu, Zhen Lei, Lun Zhang and Stan Z. Li.Learning Multi-scale Block Local Binary Patterns for Face Recognition. International Conference on Biometrics (ICB), 2007, pp. 828-837.

  • 2
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值