Opencv2.4.9源码分析——Cascade Classification(三)
- 格式:doc
- 大小:596.50 KB
- 文档页数:14
基于OpenCV2.4.9和Visual Studio2013的人脸自动识别程序冯丽娜,冯宇(昆明医科大学继续教育学院,云南昆明650031)【摘要】随着现代科学技术发展,人脸识别系统应运而生,逐渐成为现代智能化发展的重要表现方法。
在研究人脸识别系统过程中,因为受到全新技术和算法的影响,使得人脸识别系统的研究工作面临重重困难。
所以,本文详细介绍了一种人脸自动识别程序的设计思路,基于OpenCV2.4.9和Visual Studio2013软件收集一定数量的人脸数据,通过深度学习的方式对人脸识别模型进行训练,通过训练好的模型来进行人脸的识别。
通过本文的研究,旨在为当前人脸识别研究提供借鉴。
【关键词】人脸自动识别;OpenCV2.4.9;Visual Studio2013;深度学习【中图分类号】TP391【文献标识码】A【文章编号】1006-4222(2020)12-0188-04因为受到年龄因素、气色因素、光线因素、化妆水平因素、拍摄角度因素以及配饰挂件因素影响,即使是同一个人,在完成照片拍摄以后,所呈现出来的像素层面也存在很大的不同,专家可以在获取较高准确率特征值的时候,需要根据专业经验以及不断试错以获取。
因此,要实现计算机对人脸的识别,需要用到深度学习的算法。
深度学习在应用中,所呈现的最大优势是借助于训练算法对各参数权重实现自行调整,从而快速完成函数构建并保证准确率。
当给定一张照片时,通过数据计算能够捕获特征值,完成归类,最终实现对人脸的识别。
1自动识别程序的介绍本程序分为两大环节以及三个阶段。
为了实现人脸的自动识别,需要具有以下两个环节:人脸检测,即检测出照片中的人脸位置;人脸识别,即给定待检测人脸和一定规模的数据集,最终识别出人脸。
具体的实施分为三个阶段:人脸数据的收集和预处理、训练模型、人脸识别。
OpenCV有机整合了计算机视觉算法和图像处理算法等多种通用算法,作为计算机视觉库,在应用中还有很高的使用价值。
(5条消息)Opencv2.4.9源码分析相机镜头所呈现出的景物要比人类的视觉系统所看到的景物要狭小得多,因此一幅图像不可能捕获到我们所看到的整个景物。
全景图像拼接给出了这个问题的解决办法,它是把图像间重叠部分拿出来拼接起来,从而得到一幅更大的图像。
这种算法也可以用于把一幅图像插入到另一幅图像中。
图1 图像拼接执行过程及方法要想完成图像拼接,所要用到的算法较多,Opencv把这些算法用一张图呈现了处理,如图1所示。
下面我们就详细图像拼接算法。
1、计算特征点1.1 原理图像拼接的第一步是计算图像的特征,并得到它们的描述符。
好的特征检测的算法有SIFT和SURF,但它们都受到专利的保护,使用上有一定的限制。
而ORB算法是一种很好的替代方法,它是利用FAST检测特征,并生成BRIEF描述符。
关于局部特征检测方面的内容,我前面的文章中有一些算法的介绍,在这里就不再做过多的讲解。
1.2 源码Opencv中应用的是SURF算法和ORB算法,详细的内容为:class detail::FeaturesFinder表示寻找图像特征的类:1.class CV_EXPORTS FeaturesFinder2.{3.public:4.virtual ~FeaturesFinder() {}5.//寻找给定图像的特征6.void operator ()(const Mat &image, ImageFeatures &features);7.void operator ()(const Mat &image, ImageFeatures &features, const std::vector<cv::Rect> &rois);8.virtual void collectGarbage() {} //释放已被分配、但还没有被使用的内存9.10.protected:11.//虚函数,根据用户所选取的特征类别,调用不同子类的find函数,目前只实现了SURF特征和ORB特征12.virtual void find(const Mat &image, ImageFeatures &features) = 0;13.};在FeaturesFinder类中,重载( )运算符主要的任务是调用find函数来检测图像特征。
本文由我司收集整编,推荐下载,如有疑问,请与我司联系linux ubuntu 14.04下配置OpenCV 2.4.92015/04/01 688 感谢:cnblogs/shazi909/p/4132198.html:“ 网上使用Ubuntu12.04来装OpenCv还是挺多的,各种版本组合教程,都没能把Ubuntu12.04+OpenCv2.4.10成功合体。
”然后“ 建议不要用2.4.10,使用2.4.9就可以了。
”现在用14.04+2.4.9. 网上看了很多14.04+2.4.10的教程,但是发现到最后总有一个error:提示似乎是因为内核的冲突,不知是教程的错误还是我安装的问题,现在用2.4.9后,发现畅通无阻。
以下是步骤: 一、更新软件列表,升级sudo apt-get update sudo apt-get upgrade 二、安装依赖包sudo apt-get install build-essential libgtk2.0-dev libjpeg-dev libtiff4-dev libjasper-dev libopenexr-dev cmake python-dev python-numpy python-tk libtbb-dev libeigen2-dev yasm libfaac-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev libqt4-dev libqt4-opengl-dev sphinx-common texlive-latex-extra libv4l-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-devsudo apt-get install cmake-curses-gui //安装ccmake 下载opencv安装包2.4.9的版本 sourceforge/projects/opencvlibrary 三、解压unzip opencv2.4.9.zip cd opencv2.4.9 /*建议,我用的时候发现unzip不能解压,百度后发现说因为unzip解压文件的大小有限制,然后用jar解压,解压后有一个提示验证码的错误,忽略。
Opencv2.4.9源码分析——CascadeClassification(二)训练级联分类器的源码在OpenCV/sources/app/traincascade目录下。
首先我们给出级联分类器的特征类型的相关类和函数。
CvHaarFeatureParams、CvLBPFeatureParams和CvHOGFeatureParams分别表示HAAR状特征、LBP特征和HOG特征的参数类,它们都继承于CvFeatureParams:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片class CvFeatureParams : public CvParams{public://级联分类器能够使用三种特征类型用于训练样本:HAAR、LBP和HOGenum { HAAR = 0, LBP = 1, HOG = 2 };//缺省构造函数,赋值maxCatCount为0,featSize为1CvFeatureParams();//初始化maxCatCount和featSizevirtual void init( const CvFeatureParams& fp );//表示向params.xml文件写入一些信息:maxCatCount和featSize的值virtual void write( cv::FileStorage &fs ) const;//表示从params.xml文件内读取一些信息:maxCatCount和featSize的值virtual bool read( const cv::FileNode &node );//构建相应的特征参数,即级联分类器具体使用哪种特征,如果输入参数featureType=0,则应用HAAR,该函数返回CvHaarFeatureParams的指针;如果featureType=1,则应用LBP,该函数返回CvLBPFeatureParams的指针;如果featureType=2,则应用HOG,该函数返回CvHOGFeatureParams的指针。
Cascadeclassifier源码详解一、前言在计算机视觉和图像处理领域,Cascadeclassifier是一种常用的目标检测算法。
它可以用于人脸识别、物体检测等任务,被广泛应用于人工智能、安防监控、互联网等领域。
Cascadeclassifier引入了Haar-like特征和Adaboost算法,通过级联多个弱分类器构成的强分类器,来实现对目标的高效检测。
本文将对Cascadeclassifier源码进行详细解读,包括算法原理、代码结构、实现细节、优化技巧等方面的内容。
二、算法原理1. Haar-like特征Haar-like特征是Cascadeclassifier算法中的基础。
它通过对图像进行特征提取,将图像转换成一组特征值,用于表示图像中的区域。
Haar-like特征包括直方图、水平/垂直直线特征等,这些特征可以对目标的不同形状、纹理、边缘等进行描述。
2. Adaboost算法Adaboost算法是Cascadeclassifier的核心。
它通过训练一系列弱分类器,然后将这些弱分类器进行级联,构成一个强分类器。
Adaboost 算法的关键在于对训练样本进行加权,使得错误分类的样本在下一轮训练中得到更多重视,从而不断改进弱分类器的准确率。
3. 级联分类器级联分类器是Cascadeclassifier的特点之一。
它将多个弱分类器进行级联,当一个样本通过了第一个弱分类器,才会继续传递给下一个弱分类器。
这种级联结构能够在保证高检测率的大大减少了计算量,提高了算法的效率。
三、代码结构1. 源文件组织Cascadeclassifier的源码通常组织如下:- haarcascade_frontalface_alt.xml:前置摄像头人脸检测模型- haarcascade_frontalface_default.xml:默认人脸检测模型- haarcascade_eye.xml:眼部检测模型- haarcascade_upperbody.xml:上半身检测模型- haarcascade_licence_plate_rus_16stages.xml:车牌检测模型- haarcascade_smile.xml:微笑检测模型- haarcascade_fullbody.xml:全身检测模型2. 源码分析Cascadeclassifier的源码通常包括以下几个部分:- 加载模型:通过读取xml文件,加载预训练的级联分类器模型- 图像预处理:对输入图像进行灰度转换、归一化等预处理操作- 特征提取:利用Haar-like特征对图像进行特征提取- Adaboost分类:通过Adaboost算法对特征进行分类,得到分类结果- 级联分类:对多个弱分类器进行级联,得到较为精确的目标检测结果- 检测输出:将检测结果输出到图像上,或者返回目标的位置坐标四、实现细节1. Haar-like特征提取在Cascadeclassifier的源码中,Haar-like特征提取是一个关键的步骤。
win7下vs2012配置opencv2.4.91.准备工作:系统:Windows 7平台:Visual Studio 2012 UltimateOpenCV:2.4.9(点此下载/)选择这里的opencv forwindows,点击就会下载到opencv2.4.9.exe。
2.解压OpenCV-2.4.9.exe解压(不是安装)到放置OpenCV的位置,例如 E:\Program Files\OpenCV249可以看到,解压后在这个文件夹里面会生成一个文件夹“opencv”,里面就是OpenCV用到的全部文件了,比如“build ”、“include”等文件夹,如下图:3.设置用户变量。
计算机>属性>高级系统设置>环境变量>新建,新建一个用户变量,如变量名:Path,变量值:C:\opencv\build\x86\vc11\bin (1)变量值有如下选择:32位VS2008:C:\opencv\build\x86\vc9\bin64位VS2008:C:\opencv1\build\x64\vc9\bin32位VS2010:C:\opencv\build\x86\vc10\bin64位VS2010:C:\opencv\build\x64\vc10\bin32位VS2012:C:\opencv\build\x86\vc11\bin64位VS2012:C:\opencv\build\x64\vc11\bin32位VS2013:C:\opencv\build\x86\vc12\bin64位VS2013:C:\opencv\build\x64\vc12\binopencv2.4.9目录如下,没有vc9(vs2008):(2)打开软件安装目录查看vs版本,可以发现我安装的vs2012是在Microsoft Visual Studio 11.0里面,同时可以看到我没有安装vs2013(vc12).(3)打开计算机>属性>高级系统设置>环境变量>新建,新建一个环境变量,变量名:path;变量值E:\opencv\build\x86\vc11\bin,点击确定,保存变量。
Opencv2.4.9源码分析——NeuralNetworks一、原理神经网络(Neural Networks)是一种模仿生物神经系统的机器学习算法。
该算法的提出最早可追述至上个世纪四十年代,这几乎与电子计算机的历史同步。
但它的发展并非一帆风顺,也经历了初创阶段—黄金阶段—停滞阶段—复兴阶段,直到目前的高速发展阶段。
年初由Google公司开发的神经网络围棋——AlphaGo击败世界围棋冠军李世石,使神经网络技术更是受到世人的注目,因为它的意义要远大于1997年IBM的超级计算机——深蓝击败国际象棋大师卡斯帕罗夫。
与生物神经系统相似,人工神经网络也是由若干个神经元构成。
如图1所示,x1、x2、…xn 为该神经元的输入,y为该神经元的输出。
显然,不同的输入对神经元的作用是不同的,因此用权值w1、w2、…wn来表示这种影响程度的不同。
神经元内部包括两个部分,第一个部分是对输入的加权求和,第二个部分是对求和的结果进行“激活”,得到输出。
加权求和的公式为:对于MLP,我们可以用Backprop(backward propagation oferrors,误差的反向传播,简称BP)算法实现它的建模,该算法具有结构简单、易于实现等特点。
Backprop算法是一种监督的机器学习算法,输入层的神经元数量一般为样本的特征属性的数量,输出层的神经元的数量一般为样本的所有的可能目标值的数量,如果是分类问题,则为样本的分类数量,因此,与其他机器学习算法不同,在MLP中,样本对应的响应值应该是一个相量,相量的维数与输出层的神经元的数量一致。
而隐含层的层数以及各层神经元的数量则根据实际情况进行选取。
Backprop算法的核心思想是:通过前向通路(箭头的方向)得到误差,再把该误差反向传播实现权值w的修正。
MLP的误差可以用平方误差函数来进行表示。
设某个样本x对应的目标值为t,样本x有n 个特征属性,即x={x1, x2,…,xn},目标值t有J种可能的值,即t={t1, t2,…,tJ},因此该MLP 的输入层(即第一层)一共有n个神经元,输出层(即第L层,设MLP一共有L层)一共有J个神经元。
ffmpeg源码编译安装1、复制源代码cd ~mkdir ffmpegcd ffmpeg2、解压tar xjvf ffmpeg-1.2.tar.bz2cd ffmpeg-1.23、配置./configure --enable-shared --prefix=/usr/其中:--enable-shared 是允许其编译产生动态库,在以后的编程中要用到这个几个动态库。
--prefix设置的安装目录。
4、编译并安装makemake install5、安装之后在/usr/会看到有三个目录lib 动态链接库位置include 编程要用到头文件bin 执行文件所在的目录6、测试ffmpeg执行bin目录下的ffplay,可以去播放音频或者视频文件。
例如播放1.mp3./ffplay 1.mp3另外,bin目录下还有两个文件:ffmpeg和ffserverffmpeg是一个很好的视频和音频的格式转化工具。
网上有很多它的说明文档。
如果不想生成ffserver,只要在./configure的时候加--disable-ffserver即可。
安装openv需要的其他软件sudo apt-get install libgtk2.0-devsudo apt-get install pkg-configOpenCV2.4.9源码编译安装1、复制载源码cd ~mkdir opencvcd opencv2、解压文件unzip opencv-2.4.9/cd opencv-2.4.9/3、检查软件配置cmake CMakeLists.txt完成后在最后打印一下信息:-- Configuring done-- Generating done-- Build files have been written to: /opt/opencv-2.4.94、编译OpenCVmake5、安装OpenCV用root用户执行sudo make install6、更新动态连接库用root用户执行下面的操作sudo vim /etc/ld.so.conf在该文件中添加路径/usr/local/lib然後运行命令:sudo ldconfig将/usr/local/lib/pkgconfig中的opencv.pc 拷贝到/usr/lib/pkgconfig中(如果不做这步,根本编译不起) 命令如下:sudo cp /usr/local/lib/pkgconfig/opencv.pc /usr/lib/pkgconfig7、编译opencv程序的方法以编译test.c文件为例子(因为highgui中采用了c++,所以一定要用g++编译才可以)g++ test.cpp `pkg-config --cflags --libs opencv`。
Opencv2.4.9源码分析——SimpleBlobDetectorOpenCV中提供了SimpleBlobDetector的特征点检测方法,正如它的名称,该算法使用最简单的方式来检测斑点类的特征点。
下面我们就来分析一下该算法。
首先通过一系列连续的阈值把输入的灰度图像转换为一个二值图像的集合,阈值范围为[T1,T2],步长为t,则所有阈值为:T1,T1+t,T1+2t,T1+3t,……,T2 (1)第二步是利用Suzuki提出的算法通过检测每一幅二值图像的边界的方式提取出每一幅二值图像的连通区域,我们可以认为由边界所围成的不同的连通区域就是该二值图像的斑点;第三步是根据所有二值图像斑点的中心坐标对二值图像斑点进行分类,从而形成灰度图像的斑点,属于一类的那些二值图像斑点最终形成灰度图像的斑点,具体来说就是,灰度图像的斑点是由中心坐标间的距离小于阈值Tb的那些二值图像斑点所组成的,即这些二值图像斑点属于该灰度图像斑点;最后就是确定灰度图像斑点的信息——位置和尺寸。
位置是属于该灰度图像斑点的所有二值图像斑点中心坐标的加权和,即公式2,权值q等于该二值图像斑点的惯性率的平方,它的含义是二值图像的斑点的形状越接近圆形,越是我们所希望的斑点,因此对灰度图像斑点位置的贡献就越大。
尺寸则是属于该灰度图像斑点的所有二值图像斑点中面积大小居中的半径长度。
其中,H表示该斑点的凸壳面积在计算斑点的面积,中心处的坐标,尤其是惯性率时,都可以应用图像矩的方法。
下面我们就介绍该方法。
矩在统计学中被用来反映随机变量的分布情况,推广到力学中,它被用来描述空间物体的质量分布。
同样的道理,如果我们将图像的灰度值看作是一个二维的密度分布函数,那么矩方法即可用于图像处理领域。
设f(x,y)是一幅数字图像,则它的矩Mij为:下面给出SimpleBlobDetector的源码分析。
我们先来看看SimpleBlobDetector类的默认参数的设置:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片SimpleBlobDetector::Params::Params(){thresholdStep = 10; //二值化的阈值步长,即公式1的tminThreshold = 50; //二值化的起始阈值,即公式1的T1maxThreshold = 220; //二值化的终止阈值,即公式1的T2//重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点minRepeatability = 2;//最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点minDistBetweenBlobs = 10;filterByColor = true; //斑点颜色的限制变量blobColor = 0; //表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点filterByArea = true; //斑点面积的限制变量minArea = 25; //斑点的最小面积maxArea = 5000; //斑点的最大面积filterByCircularity = false; //斑点圆度的限制变量,默认是不限制minCircularity = 0.8f; //斑点的最小圆度//斑点的最大圆度,所能表示的float类型的最大值maxCircularity = std::numeric_limits<float>::max();filterByInertia = true; //斑点惯性率的限制变量//minInertiaRatio = 0.6;minInertiaRatio = 0.1f; //斑点的最小惯性率maxInertiaRatio = std::numeric_limits<float>::max(); //斑点的最大惯性率filterByConvexity = true; //斑点凸度的限制变量//minConvexity = 0.8;minConvexity = 0.95f; //斑点的最小凸度maxConvexity = std::numeric_limits<float>::max(); //斑点的最大凸度}我们再来介绍检测二值图像斑点的函数findBlobs。
opencv分类器原理OpenCV分类器原理详解OpenCV是一个开源的计算机视觉库,其中包含了众多的图像处理和计算机视觉算法,其中最常用的就是分类器。
分类器是一种用于将输入数据分为不同类别的算法,可以用于图像分类、目标检测等各种视觉任务。
OpenCV中最常用的分类器是基于机器学习的分类器,主要采用了两种流行的算法:支持向量机(Support Vector Machines, SVM)和级联分类器(Cascade Classifier)。
一、支持向量机(SVM)分类器支持向量机是一种二分类算法,其原理主要基于找到一个超平面,将不同的类别样本分开。
在训练过程中,支持向量机将样本转化为向量形式,并通过计算向量之间的距离来判定其所属类别。
SVM算法的核心是最大化间隔,即找到一个超平面,使得正负样本间的距离最大。
SVM分类器主要有以下几个步骤:1.数据准备:将输入的训练样本转化为向量形式,并标注其所属类别。
2.特征选择:选择合适的特征向量,即将原始数据转化为可计算的特征。
3.训练模型:通过训练样本,调整超平面的参数,使得正负样本间的距离最大。
4.预测类别:根据训练得到的模型,将测试样本转化为特征向量,并通过计算其在超平面上的位置,判断其所属类别。
二、级联分类器(Cascade Classifier)级联分类器是一种基于Haar特征和Adaboost算法的分类器,特别适用于目标检测任务。
其原理主要基于将分类过程分为多个级别,每个级别对应一个弱分类器,通过级联运行这些弱分类器来实现目标检测。
级联分类器主要有以下几个步骤:1. 数据准备:将目标和非目标的样本数据转化为Haar特征。
2. 训练正样本:通过Adaboost算法,选择合适的Haar特征和阈值,训练得到一系列的弱分类器。
3.联合分类器:将弱分类器按照预设的顺序进行级联,构建级联分类器。
4. 特征提取和判决:对输入的图像进行滑动窗口扫描,提取Haar特征,并依次运行级联分类器,直到达到一定的置信度阈值或者扫描窗口到达图片边缘,判断是否为目标。
Opencv2.4.9源码分析——CascadeClassification(三)下面我们以车牌识别为例,具体讲解OpenCV的级联分类器的用法。
在这里我们只对蓝底白字的普通车牌进行识别判断,对于其他车牌不在考虑范围内。
而且车牌是正面照,略微倾斜可以,倾斜程度太大也是不在识别范围内的。
我们通过不同渠道共收集了1545幅符合要求的带有车牌图像的照片(很遗憾,我只能得到这么多车牌照片,如果能再多一些就更好了!),通过ACDSee软件手工把车牌图像从照片中剪切出来,并统一保存为jpg格式。
为便于后续处理,我们把文件名按照数字顺序命名,如图8所示。
然后我们把这些车牌图像保存到pos文件夹内。
图8 蓝底白字车牌图像需要注意的是,在这里我们没有必要把车牌图像缩放成统一的尺寸(即正样本图像的大小),更没有必要把它们转换成灰度图像,这些工作完全可以由系统完成。
我们只需要告诉系统车牌图像文件、车牌的位置,以及车牌的尺寸大小即可。
为了高效的完成上述工作,我们编写了以下代码:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>#include <fstream>#include <string>using namespace cv;using namespace std;int main( int argc, char** argv ){ofstream postxt("pos.txt",ios::out); //创建pox.txt文件if ( !postxt.is_open() ){cout<<"can not creat pos txt file!";return false;}//N表示车牌图像的总数,c表示最终可以利用的车牌样本图像的数量int N = 1545, c = 0;int width, height, i;String filename;Mat posimage;for(i=0;i<N;i++) //遍历所有车牌图像{filename = to_string(i) + ".jpg"; //得到当前车牌图像的文件名posimage = imread("pos\\" + filename); //打开当前车牌图像if ( posimage.empty() ){cout<<"can not open "+ filename +" file!"<<endl;continue;}width = posimage.size().width; //当前车牌图像的宽height = posimage.size().height; //当前车牌图像的高//如果当前车牌图像的宽小于60,或高小于20,则剔除该车牌图像if(width < 60 || height < 20){cout<<filename +" too small!"<<endl;continue;}//把当前车牌图像的信息写入pos.txt文件内postxt<<"pos/" + filename + " 1 0 0 " + to_string(width) + " " + to_string(height)<<endl;c++; //累计}cout<<c; //终端输出c值postxt.close(); //关闭pos.txt文件return 0;}执行完该程序后,在终端输出得到的c值为1390,这说明有155(1545-1390)个车牌图像由于尺寸过小而被剔除。
另外,在当前目录下我们还得到了pos.txt文件,该文件正是系统所需要的,它的文件内容如图9所示。
图9 pos.txt文件在pos.txt文件中,每一行代表一个图像文件。
我们以第一行为例,它表示pos文件夹内的0.jpg文件,后面的“1”表示该文件只有一个样本图像(即车牌),再后面的“0 0”表示该样本图像的左上角坐标,由于我们已经对图像进行了剪切,每个jpg文件就是一幅完成的车牌,所以所有行的这三个变量都是“1 0 0”。
最后的“450 140”表示0.jpg文件的宽和高。
我们收集了10589幅大小不同的不含车牌图像的无水印、无logo、无日期的照片。
这些照片统一转换为jpg格式,并且也是按照数字的顺序命名,如图10所示。
然后我们把这些照片放入neg文件夹内。
图10 不含车牌图像的照片这些照片的尺寸没有要求,只要大于正样本图像的尺寸即可,因为系统是对这些照片进行剪切,从而得到与正样本图像尺寸相同的负样本图像,所以一幅照片可以得到若干个负样本图像。
这些照片尽量保证多样性,并且每幅照片的内容尽可能的丰富,当然最重要的一点是不能含有车牌信息。
我们还需要为系统提供一个保存有这些照片信息的文本文件。
同样的,我们也写了一段简单的程序来完成这个工作:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>#include <fstream>#include <string>using namespace cv;using namespace std;int main( int argc, char** argv ){ofstream negtxt("neg.txt",ios::out); //创建neg.txt文件if ( !negtxt.is_open() ){cout<<"can not creat neg txt file!";return false;}//N表示照片的总数,c表示最终得到的照片的数量int N = 10589, c=0;int i;String filename;Mat posimage;for(i=0;i<N;i++){filename = to_string(i) + ".jpg"; //照片文件名posimage = imread("neg\\" + filename); //打开当前照片if ( posimage.empty() ){cout<<"can not open "+ filename +" file!"<<endl;continue;}negtxt<<"neg/" + filename<<endl; //向neg.txt文件写入照片文件名c++; //累加}cout<<c; //终端输出c值negtxt.close(); //关闭neg.txt文件return 0;}执行完该程序后,在当前目录下得到了neg.txt文件,它的文件内容如图11所示。
以上内容准备好后,我们就可以利用Opencv提供的相关程序得到能够识别车牌的级联分类器了。
首先在D盘下新建plate文件夹,我们把前面提到的保存有大量照片图像的pos和neg这两个文件夹、以及pos.txt和neg.txt这两个文本文件复制到plate文件夹内,再在plate文件夹内新建data文件夹(后面需要)。
由于本人的电脑是64位win7系统,编译器使用的是Microsoft Visual Studio 2012,因此需要从opencv/build/x64/vc11/bin文件夹内复制opencv_createsamples.exe和opencv_traincascade.exe这两个文件到plate文件夹内。
opencv_createsamples.exe用于创建系统所需的正样本vec文件,opencv_traincascade.exe用于训练级联分类器。
这两个文件都需要在命令行下运行。
opencv_createsamples.exe所需的参数较多,这里我们只把要用到的参数进行讲解:-info:用于表示含有车牌照片的文本文件,即pos.txt-bg:用于表示不含车牌照片的文本文件,即neg.txt-vec:输出的正样本vec文件名,我们把这个文件命名为pos.vec-num:车牌照片图像的数量,即1390-w:正样本图像的宽(像素)-h:正样本图像的高(像素)后两个参数需要我们根据实际情况填写,由于我们只对蓝底白字的车牌进行识别,这类车牌的实际尺寸为440mm×140mm,我们必须要保持正样本图像的宽和高也是这个比例,而且宽和高不能过大,更不能过小。
综合考虑,我们选择:-w为58,-h为18。
在前面我们准备车牌照片时,并没有把车牌缩放成58×18这个尺寸,这是因为opencv_createsamples.exe会根据-w和-h这两个参数对图像进行统一缩放处理的,所以前面就没有处理。
最终的opencv_createsamples.exe命令为:opencv_createsamples.exe -info pos.txt -bg neg.txt -vec pos.vec -num 1390 -w 58 -h 18为方便起见,我们把这个命令保存到createsamples.bat批处理文件中,这样只要执行该文件即可。
执行的结果如图12所示,并且在plate文件夹内会生成pos.vec文件。
图12 opencv_createsamples.exe执行结果下面就要执行opencv_traincascade.exe来训练级联分类器,该命令所需要的参数也较多,但都很重要,它们的含义如下:-data:文件夹名,用于保存训练生成的各种xml文件,该文件夹一定要事先创建好,否则系统会报错,在这里,我们定义该文件夹名为data,它已在前面创建好-vec:由opencv_createsamples.exe程序生成的正样本vec文件,即pos.vec-bg:用于表示不含车牌照片的文本文件,即neg.txt-numPos:训练级联分类器的每一级分类器(即强分类器)时所用的正样本数目-numNeg:训练级联分类器的每一级分类器(即强分类器)时所用的负样本数目-numStages:最终得到的级联分类器的级数,我们设置为12-precalcValBufSize:用于存储预先计算特征值的内存空间大小,单位为MB-precalcIdxBufSize:用于存储预先计算特征索引的内存空间大小,单位为MB-stageType:强分类器的类型,目前只实现了AdaBoost,因此唯一的值(缺省值)为BOOST-featureType:特征类型,HAAR(缺省值),LBP或HOG-w:正样本图像的宽,必须与opencv_createsamples.exe命令的参数一致,即58-h:正样本图像的高,必须与opencv_createsamples.exe命令的参数一致,即18-bt:AdaBoost的类型,DAB,RAB,LB或GAB(缺省值)-minHitRate:原理部分提到的每级分类器的最小识别率-maxFalseAlarmRate:原理部分提到的每级分类器的最大错误率-weightTrimRate:用于决策树的剪枝,缺省值为0.95-maxDepth:决策树的最大深度,缺省值为1,即该决策树为二叉树(树墩形)-maxWeakCount:强分类器所包含的最大决策树的数量,该值也与最大错误率有关,我们定义该值为150-mode:如果特征为HAAR,则该参数决定了使用哪种HAAR状特征(见图1),BASIC(缺省值)、CORE或ALL下面我们就重点介绍几个重要参数的选取。