参考资料:
http://blog.csdn.net/zhuangxiaobin/article/details/25476833
【图像处理】Haar Adaboost 检测自定义目标(视频车辆检测算法代码)
http://www.cnblogs.com/ello/archive/2012/04/28/2475419.html
浅析人脸检测之Haar分类器方法
http://blog.csdn.net/zhuangxiaobin/article/details/26075667
【机器学习】AdaBoost算法详解
?
三个步骤:
- 创建样本
- 训练分类器
- 利用训练好的分类器进行目标检测
?
1、什么是Haar分类器
Haar分类器属于无监督学习的一种,属于聚类,不知道数据本来的分类数目。这要区别于分类。它是属于一种聚类算法,基于统计的聚类算法。
Haar分类器 = Haar-like特征 + 积分图方法 + AdaBoost + 级联
算法要点:
- 使用Haar-like特征检测
- 使用积分图对Haar-like特征求值并进行加速
- 使用Adaboost算法区分人脸和非人脸的强分类器
- 使用筛选式级联把分类器级联到一起,提高准确率
?
Haar-like特征:
边界特征、线特征、中心特征
Boosting做的工作就是用什么样的矩形特征怎样的组合到一起区分非人脸与人脸的一种算法。
它是一种弱学习分类算法,但是它可以组合成一个高精度的强学习分类算法。但是呢,如何确定阈值。
为了解决boosting自适应的问题,出现了adaboosting算法
弱分类器是由决策树来实现的,基本的弱分类器只包含一个harr-like特征,决策树只有一层。
强分类器是在弱分类器的基础上,进行多次T次迭代,然后组合T个最优弱分类器得到。
综上,adaBoost算法其实是一个弱分类器从孵化到化蝶的过程。
?
通过弱分类器的民主投票得到一个强分类器,强分类器在经过级联得到检测正确率较高的级联分类器,它就是我们最终的目标Harr分类器。
2、利用opencv上面的人脸检测demo,编写自己的车辆检测实例,检测结果如下图所示:
检测结果如下所示:每帧耗时100ms左右。
代码如下:
- static CvMemStorage* storage = 0; //存储相关
- static CvHaarClassifierCascade* cascade = 0;//决策树
- void detect_and_draw(IplImage* image);
- ?
- const
char* cascade_name = "model.xml"; - const
char* input_name = "car.avi"; - int main()
- {
- ???CvCapture* capture = NULL;
- ???IplImage* frame = 0,*frame_copy = 0;
- ?
- ????cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name,0,0,0);
- ???if (!cascade)
- ???{
- ??????cout << "load fail" << endl;
- ???}
- ???else
- ???{
- ??????capture = cvCreateFileCapture(input_name);
- ???}
- ???storage = cvCreateMemStorage(0);//必须初始化
- ???cvNamedWindow("result",1);
- ???int frame_num = cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT);
- ?
- ???while(frame_num)
- ???{
- ??????DWORD tick = GetTickCount();
- ??????frame = cvQueryFrame(capture);
- ?
- ??????detect_and_draw(frame);
- ?
- ??????cout << "use time: " << GetTickCount() - tick << endl;
- ??????frame_num--;
- ?
- ???}
- ???cvReleaseCapture(&capture);
- ???cvDestroyWindow("result");
- ???return 0;
- }
- ?
- void detect_and_draw(IplImage* image)
- {
- ???int scale = 1.3;
- ???CvPoint pt1,pt2;
- ???cvClearMemStorage(storage);
- ???if (cascade)
- ???{
- ??????CvSeq* cars = cvHaarDetectObjects(image,cascade,storage,1.1,3,CV_HAAR_DO_CANNY_PRUNING,cvSize(20,20));
- ??????for (int i = 0; i < (cars ? cars->total : 0); ++i)
- ??????{
- ?????????CvRect* r = (CvRect*) cvGetSeqElem(cars,i);
- ?????????pt1.x = r->x*scale;
- ?????????pt1.y = r->y*scale;
- ?????????pt2.x = (r->x + r->width)*scale;
- ?????????pt2.y = (r->y + r->height)*scale;
- ?????????cvRectangle(image,pt1,pt2,CV_RGB(255,0,0),3,8,0);
- ??????}
- ???}
- ???cvShowImage("result",image);
- ???cvWaitKey(20);
- }
3、优化算法,提高检测速度
内存空间够大的话,理论上也可以提高速度。
- 从提高速率和准确性的角度出发,我们发现整张图探测汽车,耗时接近300ms,想着如何提高算法的实时性?
?
将雷达监测到的障碍物坐标,投影到图像当中,并将其窗口做限制,窗口大小200*200,从障碍物自身投影到图像中坐标算起,使用视觉大概在60ms左右。
再此,我们可以通过更改Haar函数里面的参数也可以提高速度。
(注意:雷达坐标不准的原因,条件tan,调小,也就是说pitch向下比较多,这个值对纵坐标影响太大。)
检测函数如下:
?
- 下一步往下做的问题:
1)我们是否可以通过车道线的限制条件来限制其检测范围只要车道线之内的图像,其他不要。
2)假如检测到多个障碍物,我们无法确定矩形框大小,因为我们不知道障碍物是什么?如何确定长与宽?
3)多个障碍物都用Haar的话,效率是个问题,因为检测一次耗时太长,还不如将窗口弄大一些,然后一次性检测。
?
?
- 一些小错误:
libboost_thread-vc100-mt-1_47.lib(tss_pe.obj) : error LNK2038: 检测到"_ITERATOR_DEBUG_LEVEL"的不匹配项: 值"0"
VS2010检测到"_ITERATOR_DEBUG_LEVEL"的不匹配项,这个错误是由于
生成release文件的时候链接到debug文件当中了,我们需要在附加属性里面加上*d.lib即可。而不是用*.lib,这样可能会导致链接的错误。
- 德尔福ESR与图像融合设备算法思路
图像输出行人、车辆、车道线信息(核心芯片用的mobieye的摄像头,可以直接输出车道线、行人以及车辆信息),然后雷达输出障碍物信息。
然后在某一个ECU里面融合这些数据,起到一个相互验证的作用,而且每辆车的高度与宽度可以说是一定的。我们可以通过识别出来的人和车信息来标记宽度信息。
?
关于德尔福ESR与图像融合设备算法思路这块,是我们学校当时采购过一套德尔福的融合设备,根据工程师描述,此套融合设备是德尔福与mobieye合作开发的,德尔福用的是mobieye的核心芯片,可以提供车道线,行人,车辆信息。而目前我们手里的mobieye摄像头只能以下提供:
1、车道线压线的报警信号(55km/h以上有效)
2、同车道内,车辆报警信号和时距信号(30km/h 以上有效)
3、同车道内,行人报警信号(7km/h --- 50km/h 之间有效)