`

车道线检测实验笔记(二)---- 基于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)控制点寻找的方法仍需要斟酌,因为道路的情况及其复杂,所以需要针对可想的所有情况进行模拟!

 

接下来,将继续实验

 

  • 大小: 10.8 KB
  • 大小: 3.7 KB
  • 大小: 15.5 KB
  • 大小: 3.2 KB
  • 大小: 3.1 KB
  • 大小: 5.2 KB
  • 大小: 4.8 KB
  • 大小: 5.1 KB
  • 大小: 22.2 KB
  • 大小: 19.1 KB
  • 大小: 3 KB
  • 大小: 11.7 KB
  • 大小: 10 KB
  • 大小: 24.1 KB
  • 大小: 23.1 KB
  • 大小: 22.7 KB
  • 大小: 19.8 KB
分享到:
评论

相关推荐

    catmull-rom样条插值算法1

    在实际应用中,Catmull-Rom 样条插值算法可以用于绘制一条样条线,从而实现图形的平滑插值。例如,在计算机视觉中,该算法可以用于图像插值,生成一条平滑的曲线,从而实现图像的平滑插值。 Catmull-Rom 样条插值...

    Android使用Catmull_Rom插值算法画光滑曲线图源代码

    首先,Catmull-Rom插值算法基于四边形的四个顶点(P0, P1, P2, P3),其中P1是当前需要计算插值的点,而其他三个点作为邻接点。算法的核心在于通过一个公式来计算出P1处的插值点: \[ P(t) = 0.5 * (2*P1 + P0 - P2...

    Matlab_spline_catmull-rom_

    "Matlab_spline_catmull-rom_" 的主题聚焦于 Catmull-Rom 样条,这是一种特殊类型的样条曲线,常用于创建平滑连续的曲线路径。在 MATLAB 中实现 Catmull-Rom 样条算法,可以方便地处理一维到多维的数据集。 Catmull...

    2_样条曲线编程C语言_

    在C语言中,我们通常使用贝塞尔曲线(Bézier curves)或卡塞尔曲线(Catmull-Rom splines)等算法来实现样条曲线。贝塞尔曲线由控制点和权重决定,可以生成从简单直线到复杂曲线的各种形状。而卡塞尔曲线则是一种...

    论文研究-基于Canny边缘检测的Catmull-Rom图像放大.pdf

    为了较好地保持图像的边缘信息, 提出一种基于Canny边缘检测的Catmull-Rom图像插值放大算法。首先用Canny算子检测出原图像的边缘; 然后, 根据插值目标图像未知像素点时, 目标图像与原图像的相似性, 如果未知像素点为...

    CatmullRomSplineEditor:动画球沿着用户编辑的 Catmull-Rom 样条线加速

    Catmull-Rom样条线的数学基础是基于四节点插值的形式,它通过四个相邻的控制点来确定一个插值点。每个插值点都是这四个控制点的一个加权平均,权重分配依据于Catmull-Rom规则,确保了曲线的连续性和光滑性。在程序中...

    Catmull-Rom插值算法.pdf

    该算法基于Catmull-Rom样条曲线,是一种三次样条插值算法。Catmull-Rom样条曲线的特点在于它能通过所有给定的控制点,同时确保曲线在各点之间的连续性和光滑性。 **Catmull-Rom插值公式:** 对于一组控制点\( P_i ...

    三次参数样条曲线算法

    Catmull-Rom样条是一种特殊的三次参数样条,它保证了曲线在相邻控制点间总是通过中点,从而提供了良好的局部控制。B-spline则通过控制点和权重函数来定义,允许更大的灵活性,可以通过调整基函数的控制来改变曲线...

    利用B-Spline和Catmull-Rom Spline实现物体的移动

    需要有opengl,如何配置opengl请自行...利用B-Spline插值和Catmull-Rom插值实现物体的移动,物体的旋转由欧拉角或者四元数实现。 在Visual C++上实现的 效果视频请点击:https://www.youtube.com/watch?v=I2FgyMXiZvk

    VB+三次样条曲线+绘制示例+含代码

    这里的关键是选择合适的插值算法,如Catmull-Rom样条或Hermite样条。 在VB中实现三次样条曲线绘制时,通常会先计算出每个点的控制点,然后利用这些控制点和`DrawLine`方法逐段绘制曲线。这个过程涉及矩阵运算和插值...

    【Unity样条线插件】Curvy Splines 8 快速生成平滑的样条曲线和路径

    贝塞尔曲线和Catmull-Rom样条:支持多种样条曲线类型,包括贝塞尔和 Catmull-Rom 样条等,开发者可以根据需求选择最适合的曲线类型。 高精度曲线生成:所有曲线均经过高精度计算,确保曲线光滑且符合场景需求。 2....

    VS C++绘制Catmull-Rom曲线

    实验内容:给出任意四个控制点,绘一条穿过所有的曲线,采用Catmull-Rom曲线。

    数值计算中的样条曲线拟合问题

    2. **选择样条类型**:决定使用何种类型的样条曲线,如Cubic B-splines(三次B样条)、Linear splines(线性样条)或者Catmull-Rom splines等。选择的类型取决于对曲线光滑度、计算复杂性和数据分布的需求。 3. **...

    一种基于C2连续Catmull-Rom样条的图像放大方法 (2006年)

    针对图像高倍放大易出现block现象,文章构造了一类5次的Catmull-Rom样条用于图像放大,取得了较为满意的效果;与3次Catmull-Rom样条具有C1连续的性质相比,所构造的5次Catmull-Rom样条在不增加插值节点情况下达到C2...

    N Dimensional Cardinal Spline (Catmull-Rom) Spline Interpolation:N维三次Cardinal spline (Catmull-Rom) Interpolation-matlab开发

    Cardinal(Catmull-Rom) 使用统一参数化对给定的四个控制点进行样条插值。 每个控制点都可以是 N 维欧几里得空间。 ---------------------------------- 还给出了一个简单的测试程序 (main.m) 来执行给定数据的 1D、...

    图形学实验源码---基本图形及曲线绘制

    4. **曲线绘制**:可能涉及到贝塞尔曲线(如线性、二次、三次贝塞尔曲线)和样条曲线(如Catmull-Rom样条)的实现。这些曲线在游戏开发、动画制作等领域广泛应用。 5. **图形填充**:图形的填充算法,如扫描线算法...

    curve-editor:具有折线、贝塞尔曲线、Catmull-Rom 样条和拉格朗日曲线的计算机图形类曲线编辑器

    曲线编辑器要求C++11 和 freeglut ##Controls 通过在按住以下键之一的同时单击来绘制曲线: p:折线b:贝塞尔曲线r:Catmull-Rom 样条l:拉格朗日曲线单击要选择的曲线。 拖动曲线移动。 按住 'a' 将点添加到所选...

    Qt 通过输入控制点解析出样条曲线(源码)

    1. **理解样条曲线**:样条曲线通常有多种类型,如Bézier曲线(包括线性、二次和三次Bézier),Catmull-Rom样条等。这里提到的可能是基于控制点的三次Bézier曲线,因为这种类型的曲线可以提供良好的平滑度和灵活...

    cat-rom-spline:Catmull Rom样条插值变得容易

    Catmull Rom样条插值变得容易。 安装 $ npm install --save cat-rom-spline 用法 var catRomSpline = require ( 'cat-rom-spline' ) ; // Points are arrays in the form of [x, y] var p0 = [ 0 , 0 ] ; var p1 = ...

    CatmullRomSpline

    Catmull-Rom样条是一种在计算机图形学中广泛应用的插值算法,它主要用于创建平滑的曲线。这种样条曲线是由一系列控制点定义的,它能够提供一种连续且光滑的方式来连接这些点,使得在两点之间的过渡自然而流畅。在Lua...

Global site tag (gtag.js) - Google Analytics