`

车道线检测实验笔记(一)---- 基于改进Hough变换的曲线检测方法

 
阅读更多

    一、问题引入和分析

    无人驾驶技术在今发展迅猛,而车道线识别检测则是无人驾驶技术的基础与保障。本篇博客将近期来博主所做的一些车道线检测的实验(无奈,有失败的,也有成功的,虽然效果一般)做一些描述,整理成笔记,一来如果能有人给出好的建议或者意见,指出我所做的是否科学合理是再好不过了,二来,也是帮助自己记忆研究历程,便于下一步研究。

    为了找到一个合适的模型,或者说是方法,能够完成车道线检测的如下几个部分:

    (1)直线检测

    (2)曲线检测

    (3)虚线、实线的检测

   我们可以简单分析一下:

    (1)图像预处理:首先,需要对图像进行逆透视变换,得到俯视图,同时对车道线的检测,前提条件是待检测图中尽量只有车道线信息,那么要尽可能地减少环境带来的噪声。预处理部分,后面会着重讨论到,这里只是进行场景模拟,来检验方法或者模型是否正确;

    (2)直线检测:直线检测在图像识别领域算是一个入门式的课题,如今主流的方法当然是使用Hough变换对直线进行检测,对于车道线检测,也可以使用该方法进行直线部分的检测。但是,要注意两个主要的问题(后续问题,后续再具体分析):

          1>重复检测:这里的重复检测主要指非极大值抑制后仍然出现的重复检测,而是指由于曲线的存在,而导致相近位置不同角度的检测:
                                                      

          2>错误检测:由于曲线的引入,导致检测出角度偏差很大的直线:
事实上,这些问题可以通过加上一些限制条件以及直线聚类的方法解决。本文暂不讨论这些问题,关于直线的筛选和聚类问题,后面文章会有详细阐述。

   (3)曲线检测:该部分较为复杂,也是本文现阶段重点讨论的问题;

   (4)虚线实线的检测:初步想法,可以通过直线部分,检测直线周围有效像素点所占比重来粗略估计,该部分,也不作为现阶段重点讨论的问题。

 

   总结来说,本文现阶段,主要讨论直线检测+曲线检测的模型和方法

 

   二、基于改进Hough变换的曲线检测模型

   (参考:http://d.wanfangdata.com.cn/Patent/CN201310717643.3/

    在原方法的基础上,进行了一定的调整和改进)

   2.1 基本思路

   为了检测曲线,首先人为设定一个场景(这个设定可以避开环境噪声的干扰,让模型\方法的验证变得更加简单),来模拟车道线:
如上图所示,表示一根弯曲的车道线,现在算法的目的就是要检测这根曲线。

根据参考文献,检测上图曲线的方法描述如下:
 (1)找到Hough空间中全局最大点A,作为图中曲线的主切线;

 (2)在Hough空间内,以A为基点,向四周进一步搜索,若附近有大于阈值的点,则加入队列;

 (3)四周均搜索不到有效点,则搜索结束,判断队列中像素点的个数,大于阈值则表示是曲线,反之,小于阈值则表示是直线;

 (4)若得到结果是曲线,将队列中的像素点从Hough空间反变换到x-y坐标系下,得到最终的曲线。

           2.2 具体实现

   (1)对上述图像进行Hough变换,得到对应的Hough空间信息,然后遍历Hough图,得到全局最大点A,标记在图中:

              (图中蓝色小点代表Hough空间中的全局最大值点)

全局最大值点代表着曲线的主切线方向;

    (2)在(1)的基础上,在Hough空间中,向四周寻找大于阈值的像素点,(实际上,这里的思想是:一条直线在Hough空间中近似是一个亮点,一条曲线在Hough空间中是近似一条连续的曲线),规定向左向右搜索的方法如下:

     向左搜索:搜索当前点的上、左上、左、左下、下五个点;

     向右搜索:搜索当前点的上、右上、右、右下、下五个点;

     向左\向右搜索退出条件:为了避免偶然性的漏检(可能恰好一段连续的曲线中间缺了一点),我们引入一个容错因子Theta

同时,考虑到曲线方向的不确定性(可能出现方向变换),如下图:
               

               先向右后向左          先向左后向右
这种情况下,若只单纯搜索一边,很可能漏去变化方向的那一部分,如下图:
                
所以,为了能一次性全方位地检测出Hough空间的曲线,我们在规定如下搜索方法: 
1>起始搜索点为A点

2>向右搜索,直到退出,退出点为B

3>从B点向左搜索,直到退出

4>起始搜索点回到A点

5>向左搜索,直到退出,退出点为C

6>从C点向右搜索,直到退出

结束

部分代码如下: 

向左搜索:

 

CvPoint searchRight(int **HoughArea, IplImage* hough, CvPoint point, Lines* line)
{//找当前点的上、右上、右、右下、下
	//循环搜索,直到两个方向搜索均无结果,则退出开始下一步判断
	CvPoint start;//搜索的初始点
	start = point;//先将point作为当前的初始点
	int Max = 0;//找局部最大值
	CvPoint last = start;//记录上一次最大值,本次搜索排除当前点和上一次点
	int mistakes = 0;//引入一个容错因子
	//****************************搜索上,右上,右,右下,下*****************************8
	while(1)
	{
		CvPoint temp;
		if(start.x >= hough->width-1 || start.y <= 0||start.y >= hough->height-1)//超出搜索范围,退出搜索
			break;
		//cout << "curve1" << endl;
		for(int xx = 0;xx < 2; xx++)
		{
			for(int yy = -1;yy < 2;yy++)
			{
				if((xx == 0 && yy == 0)||(start.y + yy == last.y && start.x + xx == last.x))//不包括当前点
					continue;
				//cout << HoughArea[start.y + yy][start.x + xx] << endl;
				if(HoughArea[start.y + yy][start.x + xx] > Max)
				{
					Max = HoughArea[start.y + yy][start.x + xx];
					temp.x = start.x + xx;
					temp.y = start.y + yy;
				} 
			}
		}
		if(Max > Threshold)
		{
			//cout << Max << "  ";
			mistakes = 0;//容错清零
			cout << "find1:"<< Max << endl;
			Max = 0;
			(*line).houghpoint.push_back(temp);
			last = start;//保存上一次最大值
			start = temp;//找到的点作为当前点继续搜索
			CvScalar s;    
			s.val[0]=0;
			s.val[1]=255;
			s.val[2]=0;
			//cvSet2D(hough,temp.y,temp.x,s);//set the (i,j) pixel value
		}
		else if(mistakes <= 5)//容错,三次
		{
			mistakes++;
			Max = 0;
			start.x = start.x + 1;
		}
		else//退出条件
			break;//没有找到符合条件的点,退出搜索
	}
	//*******************************************************************************
	CvPoint final;
	final.x = start.x - mistakes;
	final.y = start.y;
	return final;
}
向右搜索与向左搜索类似,只是改变搜索方向,这里不赘述。

 

按照此方法得到Hough空间内的曲线检测结果:

                        (阈值:5)

可以看出检测效果不是很理想。由上述方法,可以看出,如果不是一个单纯连续的曲线,而有大量的噪声,则检测效果会非常差。

如此一来,为了消除“环式误检”,将检测步骤简化:

1>起始搜索点为A点

2>向右搜索,直到退出

3>起始搜索点回到A点

4>向左搜索,直到退出

结束

得到结果:
                         (阈值:5)
尝试其他的参数,效果不佳。实际上可以猜测得出来,右边的像素点值要比曲线下部分的大,所以检测才会跑偏。这里的结论是,噪声对Hough空间曲线检测的效果影响甚大!  

     (3)这里构造一个直线的结构体,含有一系列参数。

//定义一个表示曲线的结构体(包括直线)
struct Lines
{
	bool curve;//是否是曲线,1表示是曲线,0表示是直线
	vector<CvPoint> point;//曲线上的点,控制点
	vector<CvPoint> houghpoint;//直线在hough空间是一个点,曲线在hough空间中应该是一条连续的曲线,x表示Dist,y表示Angle
	bool dashed;//是否是虚线,1表示是虚线,0表示是实线
	Lines()
	{
		this->curve = false;//默认是直线
		this->dashed = false;//默认是实线
	}
};

 其中,Houghpoint就是步骤(2)中有效点的队列。设置一个阈值,队列长度大于阈值则判断该线是曲线,否则为直线。

             (4)从Hough空间反变换到X-Y坐标系下。

方法一:参考专利中的还原公式如下:
其中求出来的x,y坐标为Hough空间中(Theta,r)对应的切点。

程序中,我做出了该公式下的尝试,得到结果如下
                                        
                                               得到结果                                                   原图

当然,上述解算我做出了一些调整。实验发现,如果使用连续的三个点进行计算,结果是散乱无章的,所以,我间隔一定距离,取三个点进行计算。(下式MaxDist可见我博客 Hough变换(自写))

 

double theta1 = line.houghpoint[i].y*P/180;
double theta2 = line.houghpoint[i+5].y*P/180;
double theta3 = line.houghpoint[i+2].y*P/180;
double rho1 = line.houghpoint[i].x - MaxDist;
double rho2 = line.houghpoint[i+5].x - MaxDist;
double rho3 = line.houghpoint[i+2].x - MaxDist;
x = 0.5*cos(theta2)*rho2 + sin(theta2)*((rho1-rho2*cos(theta2-theta1))/sin(theta2-theta1)) 
+ 0.5*cos(theta3)*rho3 + sin(theta3)*((rho2-rho3*cos(theta3-theta2))/sin(theta3-theta2));
y = 0.5*sin(theta2)*rho2 - cos(theta2)*((rho1-rho2*cos(theta2-theta1))/sin(theta2-theta1))
+ 0.5*sin(theta3)*rho3 - cos(theta3)*((rho2-rho3*cos(theta3-theta2))/sin(theta3-theta2));
 方法二:可以想象,在Hough空间中的点代表着的X-Y轴上曲线的切线点,而Hough空间中相近的两个点实际上也代表着X-Y空间中曲线上相近的两个切线点。道理很i简单,相近两个切点的rho和theta都变换得很小。所以,我们可以用相邻两点所构成的直线代替其中一点的切线,想法实际上和微元法有点点类似!
                                          
                                                  得到结果                                                   原图

可以看到,无论是哪个还原方法,得到的X-Y坐标系下的结果都不是连续曲线,而是离散的点,当然,这些点看上去很接近原图曲线的趋势。
 

 

结论:

1.该方法,Hough空间下的曲线检测受噪声影响大!Hough变换实际上市将一个个像素点映射到Hough空间累加器中,不同角度的直线在Hough空间中不可能只是一个点,而是有很多其他的纵声干扰,而且实验测试,干扰不小,甚至有些角度的直线会被误检成曲线,如下图


2.该方法,从Hough空间还原到X-Y坐标系下,得到的几乎是离散的点。这主要也是因为Hough空间中的检测不准确造成的。

 

考虑解决方案:

1.对于直线的误检,考虑动态阈值的方法;

2.对于离散点的问题,看看可不可以引入曲线拟合的方法,结合使用,得到比较合理的结果。

  • 大小: 3.6 KB
  • 大小: 3.7 KB
  • 大小: 3.6 KB
  • 大小: 1.2 KB
  • 大小: 33.5 KB
  • 大小: 2.7 KB
  • 大小: 2.4 KB
  • 大小: 2.2 KB
  • 大小: 2.1 KB
  • 大小: 30.7 KB
  • 大小: 32.5 KB
  • 大小: 33.4 KB
  • 大小: 9.3 KB
  • 大小: 12.7 KB
  • 大小: 14.8 KB
  • 大小: 28.9 KB
分享到:
评论

相关推荐

    基于改进Hough变换的车道线检测技术

    为了解决上述问题,本研究提出了一种基于改进Hough变换的车道线检测方法,主要包括以下几个方面: 1. **图像预处理阶段**:首先,根据光照强度对道路图像进行分类处理,然后采用适当的算法进行预处理和边缘增强,...

    基于Matlab和优化Hough变换的高速公路车道线检测方法①.docx

    基于Matlab和优化Hough变换的高速公路车道线检测方法①.docx基于Matlab和优化Hough变换的高速公路车道线检测方法①.docx基于Matlab和优化Hough变换的高速公路车道线检测方法①.docx基于Matlab和优化Hough变换的高速...

    基于加强版Hough变换的车道线识别

    本文将详细解析一个基于加强版Hough变换的车道线识别算法,该算法采用Matlab实现,具有高识别率和无断点的特点。 首先,我们需要了解Hough变换的基本原理。Hough变换是一种在图像中寻找直线、圆等几何形状的方法,...

    基于MATLAB和改进Hough变换的车道线检测

    基于matlab的车道线检测程序,对比不同边缘检测算法,通过改进hough变换来检测视频中的车道线,每一步算法都具有详细的解释说明

    【图像检测】基于 Hough变换实现视频车道线检测matlab源码.md

    【图像检测】基于 Hough变换实现视频车道线检测matlab源码.md

    基于边缘检测与Hough变换的车道线检测毕业论文.docx

    基于边缘检测与Hough变换的车道线检测是计算机视觉和图像处理领域的热点研究方向之一。随着自动驾驶和智能交通系统的发展,车道线检测技术变得越来越重要。该技术可以帮助驾驶员实时监控车道线,避免交通事故的发生...

    基于matlab的Hough变换进行直线车道和弯曲车道线检测源码+详细说明.zip

    一般道路主要由直道和弯道两部分构成,故车道线也相应的分为直车道线和弯曲车道线两种类型,本节首先对道路图像划定感兴趣区以提高运算效率,然后针对两种不同类型的车道线选取不同的检测方法。对于直车道线,利用...

    基于Matlab的车道线检测.完整代码+数据

    本资源提供了一个基于Matlab的完整车道线检测解决方案,包括代码和所需的数据集,为学习和研究提供了便利。 在Matlab环境中进行车道线检测,主要涉及到以下几个关键知识点: 1. 图像预处理:在进行车道线检测之前...

    基于 Canny算子和 Hough变换的夜间车道线检测.docx

    本文主要介绍了一种基于 Canny 算子和 Hough 变换的夜间车道线检测方法。该方法首先对预处理后的图像采用 Laplacian 算子进行边缘增强,然后结合 Otsu 算法进行 Canny 边缘检测,再在边缘图像底部 1/3 区域中利用 ...

    改进hough变换检测椭圆.zip

    标题"改进的Hough变换检测椭圆"暗示了这篇论文提出了一种优化的方法,旨在简化和加速椭圆检测过程。这种改进通常涉及到参数空间的转换,以减少计算量并提高准确性。在描述中提到,这种方法将原本5维的椭圆参数空间...

    基于tuSimple Lane Dataset实现车道线检测源码+项目说明(运用方法边缘提取、hough变换等).zip

    【资源说明】 1、该资源包括项目的全部源码,下载可以...基于tuSimple Lane Dataset实现车道线检测源码+项目说明(图像的输入输出调用OpenCV)(运用数字图像处理的基本方法,如边缘提取、hough变换、空域滤波等).zip

    基于改进的Hough变换图像分割方法

    Hough变换作为一种广泛应用于图像处理和计算机视觉的技术,在检测图像边缘方面具有重要作用。然而,传统Hough变换算法存在着存储容量需求大、计算复杂度高、运行速度慢等问题,并且无法准确确定曲线的端点和长度。...

    matlab 车道线检测

    Matlab 车道线检测是基于改进的 Hough 变换和区域生长法的图像处理技术。该技术可以实时检测车道线,具有重要的应用价值。 车道线检测的原理 车道线检测是计算机视觉和图像处理领域中的一个重要研究方向。车道线...

    基于Python实现的车道线检测完整代码

    6. Hough变换:通过`cv2.HoughLinesP()`或`cv2.HoughLines()`进行霍夫变换,从边缘图像中检测直线,这是找到车道线的关键步骤。 7. 图像绘制:`cv2.line()`和`cv2.polylines()`用于在原始图像上画出检测到的车道线。...

    基于opencv传统数字图像处理实现车道线检测-python-c++源码+项目说明.zip

    车道线检测方法,主要包括获取感兴趣区域(ROI)、形态学闭运算、基于Hough变换的直线检测。 基于opencv传统数字图像处理实现车道线检测_python_c++源码+项目说明.7z 【实现方法】 实现车道线检测,主要包含两部分...

    基于Hough变换的人眼虹膜定位方法.zip

    本文将详细探讨一种基于Hough变换的人眼虹膜定位方法,该方法利用了Hough变换的强大功能来检测直线特征,进而确定虹膜的位置。Hough变换是一种在图像中寻找特定形状(如直线、圆)的有效工具,即使在存在噪声或部分...

Global site tag (gtag.js) - Google Analytics