Adaboost应用系列之三:Opencv2.4.X中利用Adaboost训练HOG特征产生xml分类器

来源:互联网 发布:windows怎么打开pages 编辑:程序博客网 时间:2024/05/17 07:54

         之前几篇博文写了自己使用Adaboost训练Harr特征和LBP特征得到分类器的实例(Harr,LBP),但是挺疑惑为什么没有支持HOG特征。后来发现OpenCV2.4.X版本都有支持级联分类器训练HOG特征,所以动手尝试了一下(这里采用的是OpenCV2.4.8版本,安装路径是:F:\Program Files\OpenCV2.4.8,级联分类器训练程序在:F:\Program Files\OpenCV2.4.8\build\x86\vc10\bin,级联分类器的相关代码在:F:\Program Files\OpenCV2.4.8\sources\apps\traincascade)。


1.采集样本

2.预处理样本

3.生成正负样本描述文件

4.创建正样本vec文件

前4个步骤参考我的另一篇文章:《Adaboost应用系列之一:Opencv2.0中利用Adaboost训练Haar特征产生xml分类器》。以上4个步骤的大体内容一致,需要区别的是这里训练HOG特征时使用的正样本尺寸为64*64,负样本不需要缩放,但是需要大于正样本的尺寸,否则容易造成训练中途卡死,参考这篇文章:http://blog.csdn.net/naruto0001/article/details/8064007。

5.训练样本

(1)对于HOG特征需要使用opencv_traincascade.exe来训练。将程序拷贝到工作目录:


注意:这里的正样本缩放到64*64(pos_64_64目录中),负样本没有缩放(neg目录中),但是比正样本尺寸要大。


(2)在当前目录的CMD输入如下命令:

opencv_traincascade.exe -data HOG_classifier -vec pos_64_64.vec -bg neg\neg.txt -numPos1200 -numNeg 1957 -numStages 20 -featureType HOG -w 64 -h 64


注意这里正样本实际个数为1416个,但是-numPos取1200。原因在于.vec文件中包含的正样本数目(即:实际的正样本个数)应该满足:.vec个数 >= (numPos + (numStages-1) * (1 - minHitRate) * numPos) + S。比如对于默认的numStages=20,minHitRate=0.995来说,那么.vec个数 >= 1.095numPos+S,估算numPos应该为1200左右。

参考:http://answers.opencv.org/question/776/error-in-parameter-of-traincascade/


(3)其中,opencv_traincascade.exe的命令行参数解释如下:

(由于2.4.0版本以上的文档都还没有添加级联分类器训练HOG的部分,所以还是参考旧的中文版文档吧:级联分类器训练 — OpenCV 2.3.2 documentation)

通用参数:

-data <cascade_dir_name>:目录用于保存训练产生的分类器xml文件和中间文件(对于上面的HOG_classifier),如不存在训练程序会创建它;

-vec <vec_file_name>:由 opencv_createsamples 程序生成的包含正样本的vec文件名(对应上面的pos_64_64.vec);

-bg <background_file_name>:背景描述文件,也就是包含负样本文件名的那个描述文件(对应上面的neg\neg.txt);

-numPos <number_of_positive_samples>:每级分类器训练时所用的正样本数目(默认值为2000,这里为1200个);
-numNeg <number_of_negative_samples>:每级分类器训练时所用的负样本数目,可以大于 -bg 指定的图片数目(默认值为1000,这里为1957个);

-numStages <number_of_stages>:训练的分类器的级数(默认值为20级);

-precalcValBufSize <precalculated_vals_buffer_size_in_Mb>:缓存大小,用于存储预先计算的特征值(feature values),单位为MB(默认值为256);
-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb>:缓存大小,用于存储预先计算的特征索引(feature indices),单位为MB(默认值为256);

内存越大,训练时间越短。
-baseFormatSave:这个参数仅在使用Haar特征时有效。如果指定这个参数,那么级联分类器将以老的格式存储(默认不指定该参数项,此时其值为false;一旦指定则其值默认为true);

级联参数:CvCascadeParams类,定义于cascadeclassifier.h
-stageType <BOOST(default)>:级别(stage)参数。目前只支持将BOOST分类器作为级联的类型;
-featureType<{HAAR(default), LBP, HOG}>:特征的类型: HAAR - 类Haar特征; LBP - 局部纹理模式特征;HOG - 方向梯度特征(默认Harr);
-w <sampleWidth>:训练样本的宽(单位为像素,默认24,这里指定64);
-h <sampleHeight>:训练样本的高(单位为像素,默认24,这里指定64);
训练样本的尺寸必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致。

Boosted分类器参数:CvCascadeBoostParams类,定义于boost.h
-bt <{DAB, RAB, LB, GAB(default)}>:Boosted分类器的类型(DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB - Gentle AdaBoost为默认);
-minHitRate <min_hit_rate>:分类器的每一级希望得到的最小检测率(默认值为0.995),总的检测率大约为 min_hit_rate^number_of_stages;
-maxFalseAlarmRate <max_false_alarm_rate>:分类器的每一级希望得到的最大误检率(默认值为0.5),总的误检率大约为 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>:每一级中的弱分类器的最大数目(默认值为100)。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度旋转特征;
LBP特征参数:LBP特征无参数。

HOG特征参数:暂无参数。但是我们从代码中可以看出HOG特征的参数设置(主要是HOGfeatures.h和HOGfeatures.cpp文件):

-首先是HOGfeatures.h中定义每个block的cell数目=9和每个cell的bin数=4,如下:

#define N_BINS 9
#define N_CELLS 4

-然后是HOGfeatures.cpp中void CvHOGEvaluator::generateFeatures()给出了具体的cell划分过程:

void CvHOGEvaluator::generateFeatures(){    int offset = winSize.width + 1;    Size blockStep;    int x, y, t, w, h;    for (t = 8; t <= winSize.width/2; t+=8) //t = size of a cell. blocksize = 4*cellSize    {        blockStep = Size(4,4);        w = 2*t; //width of a block        h = 2*t; //height of a block        for (x = 0; x <= winSize.width - w; x += blockStep.width)        {            for (y = 0; y <= winSize.height - h; y += blockStep.height)            {                features.push_back(Feature(offset, x, y, t, t));            }        }        w = 2*t;        h = 4*t;        for (x = 0; x <= winSize.width - w; x += blockStep.width)        {            for (y = 0; y <= winSize.height - h; y += blockStep.height)            {                features.push_back(Feature(offset, x, y, t, 2*t));            }        }        w = 4*t;        h = 2*t;        for (x = 0; x <= winSize.width - w; x += blockStep.width)        {            for (y = 0; y <= winSize.height - h; y += blockStep.height)            {                features.push_back(Feature(offset, x, y, 2*t, t));            }        }    }    numFeatures = (int)features.size();}

-最小的cell大小为8*8,逐次增加8,一直到winSize.width的1/2;

-每个block有可能是2*2个cell,有可能是2*4个cell,也有可能是4*2个cell,这取决于winSize.width和blockSize.width的关系。由于最小的block是16*16,所以winSize必须>=16*16才有cell可以拿来计算HOG特征。以64*64的winSize为例,cell的尺寸可以是8*8、16*16、32*32,相应的block的尺寸可以是16*16、16*32、32*16、32*32、32*64、64*32、64*64。

-每个block的滑动步长(blockStep)一直是4*4


(4)训练时间很长,我这里训练了一周左右,图片的尺寸太大了,改成32*32的训练速度比较快。训练过程中每一级的输出结果大致如下(这里是20级):





6.使用分类器

使用CascadeClassifier类的load函数载入分类器xml文件,使用detectMultiScale函数进行目标检测。


1 0