利用Opencv实现adaboost(cascade)训练及检测

        写在前面的话:这篇文章主要是总结一下使用方法,至于数学原理的话,大家请在网上找自己能看得懂的资料学习一下吧。至于adaboost和cascade是什么意思,或者你想搞清楚他们之间的联系与区别,网上也有很多资料可以查找,本文不再赘叙。那么你阅读本文之前所要知道的就是:adaboost是用很多不太好的分类器组合成一个好一些的联级分类器,cascade是也是出于同样的思想一个联级分类器单页有一些改进,兼具adaboost的功能,却有比adaboost更出色的特性。本文中提供命令行方式训练模型,然后在VS下基于C++实现检测。

 

0、前期准备

首先就是在Opencv中找到样本制作和模型训练的工具,在Opencv2.4.9的\\build\x86\vc10\bin的路径下面会有四个.exe文件,如下图所示。

 

 这里之所以选择基于Opencv2.4.9来介绍,就是因为要简单解释一下以上四个应用程序在不同版本的Opencv中的情况。第一个和最后一个在Opencv3以后依然被保存,中间两个抛弃了。而Opencv2.4以前的版本我也没用过,所以也不知道情况,但是从Opencv的版本更新角度来看,中间两个在以后的版本中是不再保留的。

因此,我们在文章中也只用到了第一个和最后一个应用程序,这样大家也可以很方便的在最新版本的Opencv中使用我们的方法(至少在Opencv3.3.0版本中依然是在使用这两个)。

首先建立一个adaboost的文件夹,把需要用到的两个.exe文件copy到文件夹里,方便调用。

 

1、制备训练样本

训练adaboost(cascade)模型,需要准备正负两个样本集,从网上搜集到的资料来看,一般推荐正负样本比率在1:2至1:3,也就是说负样本要比正样本多几倍的数量才比较好。

对样本的要求如下:

1)正样本要尺寸一致,而且不要太大。

网上有说24x24,或者28x28的,太大的尺寸会降低训练的速度,我在实践中使用的是30x30的样本。我用的RGB图像,灰度图也一样的,没什么影响,因为主要提取的是结构特征。在adaboost文件内再新建立一个文件夹pos,存放所有的正样本,我大约收集了1700多个正样本。

2)负样本不需要归一化尺寸,但内容要不包含正样本中物体的图像。

例如,我要检测汽车,正样本中都是各种汽车图像,负样本就选花花草草,马路路面,房屋建筑等等,总之不含有汽车才行。在adaboost下新建一个neg存放所有的负样本,我搜集了大约6600多个负样本。

3)生成正样本描述文件。

在cmd中首先进入pos的路径下面,然后输入dir /b > pos.txt

就会在pos中生成一个pos.txt文件,再用notepad++之类的编辑软件打开它,删除最后一行的pos.txt字样

此时,剩余的文字内容就会是“XXX.bmp”这样子的格式了,下面要把它修改成

“XXX.bmp 目标数 目标框起点x坐标 起点y坐标 框的width 框的height”这样子的格式

由于我的正样本每幅图像是30x30的,并且每幅图像中只有一个目标物体,因此我直接改成了

“XXX.bmp 1 0 0 30 30”

样子的格式,方便起见,大家也可以这样做。修改的方法就是notepad++中的“替换”指令。

4)生成负样本描述文件。

同样在neg路径下输入dir /b > neg.txt

然后在neg中生成的neg.txt文件内删除最后一行的neg.txt字样。负样本不用修改名称格式。

5)创建正样本vec文件。

traincascade训练需要输入正样本的vec文件,这里使用opencv自带的opencv_createsamples程序将正样本转换为vec文件。在adaboost文件路径下输入

opencv_createsamples.exe -vec pos.vec -info pos\pos.txt -bg neg\neg.txt -w 30 -h 30 -num 1716

最后num的参数应该是你正样本的真实数量。关于opencv_createsamples各参数的含义和使用,大家可以自行去看Opencv的详细解释,这里主要为了展示使用方法过程,就不一一展开了。

之后会在adaboost文件下生成一个pos.vec文件。负样本不需要此操作。

 

2、训练样本

1)首先在adaboost文件下新建一个classifier文件,作为存放模型的路径。

2)调用opencv_traincascade.exe进行训练,它除了训练Haar之外可以训练别的特征,如HOG、LBP等。

在adaboost路径下输入下述指令。

opencv_traincascade -data classifier -vec pos.vec -bg neg\neg.txt -numPos 1500 -numNeg 4000 -numStages 15 -precalcValBufSize 1024 -precalcIdxBufSize 1024 -featureType LBP -w 30 -h 30 -maxDepth 1

同样参数含义需要大家自己去查文档学习,这里说明一下正样本数量numPos要比你准备的正样本少一些,不要一次用上所有的样本,负样本数量numNeg应该是正样本数量的2-3倍比较合理。

一般来讲,需要比较长的时间来训练样本的,大家耐心等待哦。训练结束之后就会在classifier文件夹下生成一堆.xml文件,除了cascad.xml是模型外,其他的都是中间过程,只有在训练被打断后重新启动时才有用。

 

3、测试

我们使用在VS环境下基于C++编辑了一小段测试程序,大家可以拿去直接用啊。

  1. // 【1】加载分类器    
  2. CascadeClassifier cascade;    
  3. cascade.load("D:\\adaboost\\classifier\\cascade.xml");    
  4. Mat srcImage, grayImage, dstImage;   
  5.   
  6. // 【2】读取图片    
  7. srcImage = imread("D:\\image\\221.bmp");    
  8. dstImage = srcImage.clone();     
  9.   
  10. // 【3】检测    
  11. vector<Rect> rect;    
  12. cascade.detectMultiScale(dstImage, rect, 1.1, 3, 0);  
  13. printf("检测到车的个数:%d\n", rect.size());   
  14.   
  15. // 【4】标记    
  16. for (int i = 0; i < rect.size();i++)    
  17. {     
  18.   rectangle(dstImage, Point(rect[i].x, rect[i].y), 
  19.             Point(rect[i].x + rect[i].width, rect[i].y + rect[i].height),   
  20.   Scalar(0, 0, 255), 2, 8, 0);  
  21. }    
  22.   
  23. // 【5】显示    
  24. imshow("【汽车检测算法】", dstImage);   
  25. waitKey(0);   
  26. return 0;  

以上就是全部的内容,今天写的比较匆忙,以后有机会我再过来补几张图给大家说明一下吧。

 

  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值