Opencv目标检测之级联分类器训练与测试

来源:互联网 发布:数据库系统结构模型 编辑:程序博客网 时间:2024/04/29 20:38

 OpenCV提供了两个程序可以训练自己的级联分类器opencv_haartraining与opencv_traincascade。opencv_traincascade是一个新程序,使用OpenCV 2.x API 以C++编写。这二者主要的区别是opencv_traincascade支持 Haar和 LBP (Local Binary Patterns)两种特征,并易于增加其他的特征。与Haar特征相比,LBP特征是整数特征,因此训练和检测过程都会比Haar特征快几倍。LBP和Haar特征用于检测的准确率,是依赖训练过程中的训练数据的质量和训练参数。训练一个与基于Haar特征同样准确度的LBP的分类器是可能的。

     与其他分类器模型的训练方法类似,同样需要训练数据与测试数据;其中训练数据包含正样本pos与负样本neg。训练程序opencv_haartraining.exeopencv_traincascade.exe对输入的数据格式是有要求的,所以需要相关的辅助程序:

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

所以opencv级联分类器训练与测试可分为以下四个步骤:

  1.  准备训练数据
  2.  训练级联分类器
  3.  测试分类器性能
  4. 利用训练好的分类器进行目标检测

1、准备训练数据

注:以行人数据为例,介绍分类器的训练

1.1准备正样本

 正样本由opencv_createsamples生成。正样本可以由包含待检测物体的一张图片生成,也可由一系列标记好的图像生成。

 首先将所有的正样本放在一个文件夹,如图所示1。其中,pos.dat文件为所有图像的列表文件,格式如图2所示:其中,第一列为图像名,第二列为该图像中正样本的个数,最后的为正样本在图像中的位置以及需要抠出的正样本的尺寸。pos.dat文件的生成方式:在dos窗口进入pos文件夹,输入dir /b > pos.dat ; 这样只能生成文件名列表,后面的正样本个数与位置尺寸还需手动添加。


图1.正样本数据


图2

1.2 opencv_createsamples.exe生成.vec格式的正样本文件

可以在dos命令窗运行opencv_createsamples.exe程序,也可利用.bat批处理文件;利用.bat批处理文件的格式如下。

"D:\Program Files\opencv\build\x64\vc10\bin\opencv_createsamples.exe" -info "pos\pos.dat"   -vec pos.vec -num 500 -w 64 -h 128 pause 

opencv_createsamples.exe程序的命令行参数:

  • -info <collection_file_name> 描述物体所在图像以及大小位置的描述文件。
  •  -vec <vec_file_name>输出文件,内含用于训练的正样本。
  •  -img <image_file_name>输入图像文件名(例如一个公司的标志)。
  •  -bg<background_file_name>背景图像的描述文件,文件中包含一系列的图像文件名,这些图像将被随机选作物体的背景。
  • -num<number_of_samples>生成的正样本的数目。
  •  -bgcolor<background_color>背景颜色(目前为灰度图);背景颜色表示透明颜色。因为图像压缩可造成颜色偏差,颜色的容差可以由-bgthresh指定。所有处于bgcolor-bgthreshbgcolor+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>输出样本的高度(以像素为单位)。

1.3准备负样本

   负样本可以是任意图像,但是这些图像中不能包含待检测的物体。用于抠取负样本的图像文件名被列在一个neg.dat文件中。生成方式与正样本相同,但仅仅包含文件名列表就可以了。这个文件是纯文本文件,每行是一个文件名(包括相对目录和文件名)这些图像可以是不同的尺寸,但是图像尺寸应该比训练窗口的尺寸大,因为这些图像将被用于抠取负样本,并将负样本缩小到训练窗口大小。如图3所示。


图3

2、训练级联分类器

  OpenCV提供了两个可以训练的级联分类器的程序:opencv_haartraining与opencv_traincascade。opencv_haartraining是一个将被弃用的程序;opencv_traincascade是一个新程序。
opencv_traincascade程序的.bat批处理文件的格式如下:
"D:\Program Files\opencv\build\x64\vc10\bin\opencv_traincascade.exe"  -data "E:\2013Mycode\TrainCascadeClassification" -vec pos.vec -bg neg\neg.dat -numPos 29 -numNeg 29 -numStages 20 -mem 200 -featureType LBP  -w 64 -h 128Pause
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特征时有效。如果指定这个参数,那么级联分类器将以老的格式存储。

 2.级联参数:

  •        -stageType <BOOST(default)>级别(stage)参数。目前只支持将BOOST分类器作为级别的类型。
  •        -featureType<{HAAR(default), LBP}>特征的类型: HAAR - Haar特征; LBP - 局部纹理模式特征。
  •        -w <sampleWidth>
  •        -h <sampleHeight>训练样本的尺寸(单位为像素)。必须跟训练样本创建(使用 opencv_createsamples 程序创建)时的尺寸保持一致。

3.分类器参数:        

  •      -bt <{DAB, RAB, LB,GAB(default)}> Boosted分类器参数:
  • DAB - Discrete AdaBoost, RAB - Real AdaBoost, LB - LogitBoost, GAB -Gentle AdaBoostBoosted分类器的类型:
  •      -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 trimmingshould be used and its weight.一个还不错的数值是0.95
  •      -maxDepth <max_depth_of_weak_tree>弱分类器树最大的深度。一个还不错的数值是1,是二叉树(stumps)。
  •      -maxWeakCount<max_weak_tree_count>每一级中的弱分类器的最大数目。The boostedclassifier (stage) will have so many weak trees (<=maxWeakCount), as neededto achieve the given -maxFalseAlarmRate.

4.Haar特征参数:

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

5.LBP特征参数:

      LBP特征无参数。

3.测试分类器性能

  opencv_performance 可以用来评估分类器的质量,但只能评估 opencv_haartraining 输出的分类器。它读入一组标注好的图像,运行分类器并报告性能,如检测到物体的数目,漏检的数目,误检的数目,以及其他信息。同样准备测试数据集test,生成图像列表文件,格式与训练者正样本图像列表相同,需要标注目标文件的个数与位置。

3.1  opencv_haartraining程序训练一个分类器模型

为了了解opencv_performance的用法,先用opencv_haartraining程序训练一个分类器模型,方法与opencv_traincascade相似。
opencv_haartraining程序的.bat批处理文件的格式如下:
"D:\Program Files\opencv\build\x64\vc10\bin\opencv_haartraining.exe"  -data "E:\2013Mycode\TrainCascadeClassification\cascade" -vec pos.vec -bg neg\neg.dat -npos 29 -nneg 29 -mem 200 -mode BASIC -w 64 -h 128Pause

opencv_haartraining 的命令行参数如下:

  • data<dir_name>存放训练好的分类器的路径名。
  • vec<vec_file_name>正样本文件名(由trainingssamples程序或者由其他的方法创建的)
  • bg<background_file_name>背景描述文件。
  • npos<number_of_positive_samples>
  • nneg<number_of_negative_samples>用来训练每一个分类器阶段的正/负样本。合理的值是:nPos = 7000;nNeg= 3000
  • nstages<number_of_stages>训练的阶段数。
  • nsplits<number_of_splits>决定用于阶段分类器的弱分类器。如果1,则一个简单的stump classifier被使用。如果是2或者更多,则带有number_of_splits个内部节点的CART分类器被使用。
  • mem<memory_in_MB>预先计算的以MB为单位的可用内存。内存越大则训练的速度越快。
  • symdefault
  • nonsym指定训练的目标对象是否垂直对称。垂直对称提高目标的训练速度。例如,正面部是垂直对称的。
  • minhitratemin_hit_rate》每个阶段分类器需要的最小的命中率。总的命中率为min_hit_ratenumber_of_stages次方。
  • maxfalsealarm<max_false_alarm_rate>没有阶段分类器的最大错误报警率。总的错误警告率为max_false_alarm_ratenumber_of_stages次方。
  • weighttrimming<weight_trimming>指定是否使用权修正和使用多大的权修正。一个基本的选择是0.9
  • eqw
  • mode<basic(default)|core|all>选择用来训练的haar特征集的种类。basic仅仅使用垂直特征。all使用垂直和45度角旋转特征。
  • wsample_width
  • hsample_height》训练样本的尺寸,(以像素为单位)。必须和训练样本创建的尺寸相同。

3.2 opencv_performance测试分类器模型

opencv_performance程序的.bat批处理文件的格式如下:

"D:\Program Files\opencv\build\x64\vc10\bin\opencv_performance.exe"  -data "E:\2013Mycode\TrainCascadeClassification\cascade.xml" -info test/test.dat -w 64 -h 128 -rs 30Pause
opencv_performance 的命令行参数如下所示:

  • -data <classifier_directory_name>训练好的分类器
  • -info <collection_file_name>   描述物体所在图像以及大小位置的描述文件
  • -maxSizeDiff <max_size_difference =1.500000>
  • -maxPosDiff <max_position_difference =0.300000>
  • -sf <scale_factor = 1.200000>
  • -ni 选项抑制创建的图像文件的检测
  • -nos <number_of_stages = -1>
  • -rs <roc_size = 40>]
  • -w <sample_width = 24>
  • -h <sample_height = 24>

4、利用训练好的分类器进行目标检测

#include "opencv2/core/core.hpp"  #include "opencv2/objdetect/objdetect.hpp"  #include "opencv2/highgui/highgui.hpp"  #include "opencv2/imgproc/imgproc.hpp"  #include <fstream>  #include <iostream>  #include <stdio.h>    using namespace std;  using namespace cv;    string Cascade_mode ="cascade.xml";   //已训练好的分类器CascadeClassifier Mycascade;  string window_name = "Pedestrain";    Mat detectAndDisplay( Mat);    int main()  {      Mat image,ROI;      if(!Mycascade.load( Cascade_mode ))  { printf("[error] 无法加载级联分类器文件!\n");   return -1;    }      image= imread("walk.jpg");//读取图片      if(!image.data)  {   printf("[error] 没有图片\n");   return -5;  }      ROI= detectAndDisplay(image);      waitKey(0);       return 4;  }    Mat detectAndDisplay( Mat frame)  {      std::vector<Rect> pedestrain;  Mat frame_gray(frame.size(),CV_8U);      cvtColor( frame, frame_gray, CV_BGR2GRAY );      equalizeHist( frame_gray, frame_gray );        Mycascade.detectMultiScale( frame_gray, pedestrain, 1.1, 2, 0, Size(64, 128) );        for( int i = 0; i < pedestrain.size(); i++ )  {            rectangle(frame,                   //图像.        pedestrain[i],                  Scalar(0, 255, 0),     //线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)                    1);                   //组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形     }     imshow( window_name, frame );    return frame;  }  

运行结果如图4:


更多资源:http://blog.csdn.net/wuxiaoyao12/article/details/39227189

http://note.sonots.com/SciSoftware/haartraining.html#x15ebd98

http://www.cnblogs.com/easymind223/archive/2012/07/03/2574826.html

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/user_guide/ug_traincascade.html




0 0
原创粉丝点击