车道线检测实验笔记(二)---- 基于Catmull_Rom样条曲线的车道线检测

一、Catmull_Rom样条曲线模型引入

Catmull_Rom样条曲线拟合是曲线插值技术的一种,该插值技术能经过所给的所有控制点。BY THE WAY,很多插值技术可以参考http://www.cnblogs.com/WhyEngine/p/4020390.html

Catmull_Rom样条曲线拟合方法需要至少四个控制点,公式如下:

其中,t属于[0,1](也就是0-1中每个t值可能对应所求曲线中的某点,其取值越多,曲线越密)。实际上,四个控制点,曲线只会经过其中两个控制点,如现在有控制点A,B,C,D,则最后的曲线拟合结果将如下:
得到的事BC之间的拟合曲线。那么若要得到ABCD的拟合曲线应该怎么办呢。实际上,引入两个新的控制点A',D'即可,A'由AB计算而得,D'由CD计算而得,例如,A'计算如下:

                   A'.x = A.x + (A.x - B.x)

                   A'.y = A.y + (A.y - B.y)

B'点计算类似。于是,由A'ABC可以得到AB曲线,由ABCD可以得到BC曲线,由BCDD'可以得到CD曲线,经过三次计算,可以得到ABCD曲线。

在一张空白图上,计算经过(50,50),(90,120),(70,200)三点的Catmull_Rom样条曲线,程序如下:

 

	IplImage* img = cvCreateImage(cvSize(300,300), 8, 1);
	for (int i = 0; i < img->height; ++i)
	{
		for (int j = 0; j < img->width; ++j)
		{
			((char *)(img->imageData + img->widthStep * (i)))[j] = 0;
		}
	}
	CvPoint point0,point1,point2,point3,point4;//3个控制点来做
	point1.x = 50;
	point1.y = 50;
	point2.x = 90;
	point2.y = 120;
	point3.x = 70;
	point3.y = 200;
	point0.x = point1.x+(point1.x-point2.x);
	point0.y = point1.y+(point1.y-point2.y);
	point4.x = point3.x+(point3.x-point2.x);
	point4.y = point3.y+(point3.y-point2.y);
	
	((char *)(img->imageData + img->widthStep * (point1.y)))[point1.x] = 255;
	((char *)(img->imageData + img->widthStep * (point2.y)))[point2.x] = 255;
	((char *)(img->imageData + img->widthStep * (point3.y)))[point3.x] = 255;

	 for (int i = 1; i < 500 ; i++) {

            float t = (float) i * (1.0f / (float) 500);
            float tt = t * t;
            float ttt = tt * t;
			CvPoint pi;
			pi.x = 0.5 * (2*point1.x+(point2.x-point0.x)*t + (2*point0.x-5*point1.x+4*point2.x-point3.x)*tt + (3*point1.x-point0.x-3*point2.x+point3.x)*ttt);
            pi.y = 0.5 * (2*point1.y+(point2.y-point0.y)*t + (2*point0.y-5*point1.y+4*point2.y-point3.y)*tt + (3*point1.y-point0.y-3*point2.y+point3.y)*ttt);
			((char *)(img->imageData + img->widthStep * (pi.y)))[pi.x] = 255;
	 }
	 
	 for (int i = 1; i < 500 ; i++) {

            float t = (float) i * (1.0f / (float) 500);
            float tt = t * t;
            float ttt = tt * t;
			CvPoint pi;
			pi.x = 0.5 * (2*point2.x+(point3.x-point1.x)*t + (2*point1.x-5*point2.x+4*point3.x-point4.x)*tt + (3*point2.x-point1.x-3*point3.x+point4.x)*ttt);
            pi.y = 0.5 * (2*point2.y+(point3.y-point1.y)*t + (2*point1.y-5*point2.y+4*point3.y-point4.y)*tt + (3*point2.y-point1.y-3*point3.y+point4.y)*ttt);
			((char *)(img->imageData + img->widthStep * (pi.y)))[pi.x] = 255;
	 }
	cvShowImage("scr", img);
	cvWaitKey(0);
	return 0;

 得到结果:
拟合效果较好。
二、基于Catmull_Rom样条曲线的车道线检测

 2.1 基本思路

为了更好地模拟车道线情况,给出下图进行模拟实验:
          
            模拟情形1                   模拟情形2

有了Catmull_Rom样条曲线的基础,那么车道线检测实际上就是找到合适的控制点!

给出基于Catmull_Rom样条曲线的车道线检测的基本方法(除去预处理过程):

参考:《基于Catmull-Rom 样条曲线的弯曲车道线检测研究,何 鹏,高 峰,魏厚敏》

(1)Hough变换直线检测,将两条主车道线检测出来,直线记为L1,L2;

(2)判断是车道线是直线还是曲线;

(3)若车道线是曲线,找到三个控制点P1,P2,P3;

(4)通过三个控制点,拟合Catmull_Rom样条曲线,得到结果

结束

 2.2 具体实现

(1)Hough变换直线检测:

首先,我们要将曲线车道线分为两个部分,一个是直线部分,一个是曲线部分,如下图,直线部分在近区域端,看作是主车道线。
对主车道线进行直线检测,为了避免角度偏差过大的误检,我们限定检测的角度范围为0°- 70°以及130°- 180°。(可以看到误检曲线角度往往在90°附近)
            
                (可能的误检情况,绿色线代表误检线)
进行角度限制的Hough变换检测直线,得到结果:
              
(2)判断直线还是曲线:

 若是直线,那么Hough变换检测的结果应该和实际直线吻合;而若是曲线,那么,由(1)中可知,Hough变换实际上检测的是直线部分,而曲线部分则会漏检。
      
 
 
            直线检测吻合                  曲线检测漏检 

按照此特性,若从上往下检测(即从(x = 0,y = 0)开始 x++,y++到(x = w,y = h)),直线的Hough检测结果将会基本吻合实际结果,即在检测结果点的周围,都将有实际点的存在;而曲线的Hough检测结果,将会先出现检测结果周围没有实际点,直到上图P3点后,检测结果点周围才会有实际点存在。

定义:1>.检测结果点吻合:若检测点周围八领域内存在实际点,则代表检测点结果吻合

    
于是该问题转化为:从图顶向下搜索,能否找到P3点,使得P3点上部分一段区域(给定一个长度阈值alph1)检测结果点都不吻合(引入容错因子,防止噪声theta),P3点下部分一段区域(同样给定一个长度阈值alph2)检测结果点吻合。若能找到P3点,则该车道线是曲线,否则,该车道线是直线!

 

(3)找到控制点P1,P2,P3:

P3控制点:实际上,步骤(2)中已经找到了其中一个控制点P3,P3点可以作为直线部分和曲线部分的分界点,P3以上部分拟合曲线,P3一下部分保留Hough变换的直线检测结果;

 

P1控制点:我们注意到,可以取远端两车道的消失点作为控制点P1。
具体搜索方法:

1>找到Hough变换得到的两直线的交点O。

2>从O点所在行向下搜索,找到P1。(从左往右搜索,第一个遇到的点即为P1点)

 

P2控制点:得到了P1,P3两点,则取P1,P3中间的一行搜索两车道的P2点!

得到结果:  
  
 

(4)经过三个控制点P1,2,3,使用Catmull_Rom样条曲线拟合得到结果:
       
 

结论:

(1)从结果上来看,能得到曲线,拟合效果并不是很好,但是提升空间很大,比如增多控制点会让曲线拟合更为精准!

(2)控制点寻找的方法仍需要斟酌,因为道路的情况及其复杂,所以需要针对可想的所有情况进行模拟!

接下来,将继续实验

 

猜你喜欢

转载自lps-683.iteye.com/blog/2329251