MATLAB基于图像处理的车道线检测

目的是识别图像中的车道线,然后将该算法扩展到视频中,从而有效地识别左右车道线,不管它是什么形状(实线与虚线),什么颜色(白色与黄色),坡度多大(直线、角度或曲线)。该项目使用的图像/视频是在美国一条高速公路上拍摄的,这条路上车道线标记得很清楚,车道线大多是直的,没有太多弯曲。

以下特征用于识别:

  1. 颜色:车道线通常为浅色(白色/黄色),而道路则为深色(深灰色)。因此,黑白图像效果更好,因为车道可以很容易地从背景中分离出来。
  2. 形状:车道线通常是实线或虚线,所以可以将它们与图像中的其他对象分开。可以用Canny等边缘检测算法找到图像中的所有边缘/线条。然后我们可以使用进一步的信息来决定哪些边可以被限定为车道线。
  3. 方向:公路车道线更接近于垂直方向,而不是水平方向。因此,在图像中检测到的直线的斜率可以用来检查它是否可能是车道。
  4. 在图像中的位置:在一个由行车记录仪拍摄的常规公路图像中,车道线通常出现在图像的下半部分。因此,可以将搜索区域缩小到感兴趣的区域,以减少噪声。

颜色选择

每个图像都由不同的色彩通道组成。在RGB配色方案中,图像中的每个像素都由红、绿、蓝三个通道的值组成。这些值在0到255之间变化,0是最暗的,255是最亮的。这样,白色为[255,255,255],黑色为[0,0,0]。如果取三者的平均值并将该值运用到每个像素上,那么就会得到一个灰度图像。

为了得到一个灰度图像,我使用了以下代码:

这里,在变量“red_threshold”,“green_threshold”, “blue_threshold”中定义颜色阈值(rgb_threshold)。此向量包含选择中允许的红色、绿色和蓝色(R、G、B)的最小值,任何高于这些值的数值都会归为零(禁用)。在车道线与道路形成对比的情况下,这种方法尤其有效,因此我们可以设置最小值。

最后,在“color_select”生成的图像中,高于阈值的像素被保留,低于阈值的像素被遮住。

区域遮罩

下一个任务是区域遮罩。如果我们假设图像来自安装在车上固定位置的行车记录仪,那么车道线只会出现在行车记录仪上的某个特定区域。这可以用来缩小搜索范围。在这里我们可以定义一个三角形,如下图所示,并且只使用其中的区域进行搜索。

在下面的代码中,变量“left_bottom”、“right_bottom”和“apex”用作三角形区域的顶点,我希望保留该区域用于颜色选择,同时屏蔽其他区域。我这里使用三角形选择兴趣区域,但原则上,使用任何多边形都是可以的。

应用区域遮罩后,最终图像将如下所示:

我们可以将这两种策略结合起来,如下代码所示:

将颜色和区域遮罩后的图像放到原始图像上,以指示车道线,如下所示:

如图所示,颜色检测能够标记车道线。然而,这仍然不是车道线检测的好方法。如果车道线是只有一种颜色的话,比如车道线是白色的,路面是黑色的,那么检测就更容易。然而,很多时候车道线不只一种颜色(黄色、白色等),它们可能是实线或虚线。因此,我们需要一种更智能的算法来寻找视频中的车道线,而这正是边缘检测的切入点。

Canny边缘检测

有时在计算机视觉项目中,可以通过物体的形状检测到物体。为了确定图像中物体的形状,需要进行边缘检测。

Canny边缘检测器是一种边缘检测算子,它使用多阶算法尽可能多地检测图像的边缘。它是由John F. Canny在1986年提出的。——维基百科

通常使用灰度图像,因为在灰度图像中,更容易检测到图像边缘。灰度图像可以想象成一个二维矩阵函数,每个像素都是包含x和y值的矩阵元素。因此我们可以进行数学运算,比如在x和y方向上取一个梯度。边缘只是像素亮度的瞬时变化。

在x和y方向上取一个表示像素亮度的斜率。斜率通常会给出一个粗略的边缘,然后在此基础上应用阈值以获得实际像素。

Canny边缘检测算法由以下步骤组成:

  1. 降噪:由于该算法所涉及的数学模型主要是基于导数的,所以边缘检测结果对图像噪声非常敏感。去除图像噪声的一种方法是应用高斯模糊对其进行平滑处理。为此,使用图像卷积技术和高斯函数(3x3、5x5、7x7等)。预期的模糊效果决定内核的大小。基本上,内核越小,模糊越不可见。
  2. 梯度计算:平滑后的图像用Sobel算子在水平方向和垂直方向上进行滤波,得到两个方向的一阶导数。从这两幅图像中,我们可以找到每个像素的边缘梯度和方向,如下所示:

  1. 非极大值抑制:在得到梯度大小和方向后,对图像进行整体扫描,以去除可能不构成边缘的所有不需要的像素。为此,在每个像素处,检查像素是否是在其邻域内沿梯度方向的局部最大值。
  2. 滞后边缘跟踪:这个阶段决定哪些是真正的边缘,哪些不是。为此,我们需要两个阈值,最小值和最大值。强度梯度大于最大值的边肯定是实际边缘,小于最小值的边肯定不是实际边缘,所以舍去。那些位于这两个阈值之间的是基于连通性的边缘或非边缘。

在openCV中,cv2.Canny函数可以用来寻找灰度平滑图像的边缘。以下是完整代码:

边缘检测后得到的图像:

目前得到的图像中的所有边都是可见的,但是如何从边缘检测到的图像中提取车道线?现在我们有了所有代表边的点,需要把这些点连起来。这就是霍夫变换的用武之地。

霍夫变换

在图像空间中,一条线可以用x,y来表示,但是在1962年,Paul Hough设计了一种在参数空间中表示线的方法,我们称之为“霍夫空间”,以纪念他为此做出的贡献。

直线方程可以表示为y=mx+b,其中m是斜率,b是截距。在“霍夫空间”中,可以将图像空间中的点(x0,mx0+b0)表示为(m0,b0)。霍夫变换就是从图像空间到霍夫空间的转换。因此,图像空间中的直线的特征就是霍夫空间中(m,b)位置上的一个点。

有很多条线可能会穿过图像空间中的一个点,但并非任意一条线,只有那些具有m和b参数的特定组合的线。重新排列直线方程,我们发现一个单点(x,y)对应于直线b=y-xm。因此,图像空间中的一个点对应于霍夫空间中的一条直线。因此,如果我们在图像空间中画出各种可能的点,并在霍夫空间中画出相应的直线,那么在霍夫空间中各种直线的交点就是图像空间里通过这些点的直线。这个概念用于识别图像中的各种线条。

现在使用笛卡尔坐标表示的直线可能会在直线垂直的情况下产生问题,因为坡度大于无穷大。为了消除这种异常,使用极坐标。

要在OpenCV中应用霍夫变换,需要使用一个名为HoughLinesP的函数,该函数有多个参数。

在这种情况下,我们对图像屏蔽的边缘(Canny的输出)进行操作,HoughLinesP的输出将是线,它将只是一个数组,包含通过霍夫变换检测到的所有线段的端点(x1、y1、x2、y2)。其他参数定义了我们要寻找的线段类型。

首先,rho和theta是霍夫空间中网格的距离和角分辨率。需要以像素为单位指定rho,以弧度为单位指定theta。

Threshold(阈值)参数指定候选行进入输出所需的最小投票数(给定网格单元中的交叉点)。空的np.数组([])只是一个占位符,无需更改。min_line_length是你将在输出中接受的一条线的最小长度(以像素为单位),max_line_gap是允许连接成一条直线的线段之间的最大距离(同样以像素为单位)。然后,你可以迭代输出行并将它们绘制到图像上,以查看最终结果!

以下是最终代码:

应用Canny边缘检测和霍夫变换后得到的图像:

总结

现在,所有这些概念都被用来识别视频中的车道线。该流程使用以下步骤标记车道线:

  1. 将图像转换为灰度图像:使用OpenCV函数cv2.cvtColor()将图像转换为灰度。这使得识别车道更加容易,也有助于下一步的边缘检测。采用高斯模糊算法对单元值进行平均化处理,以减少噪声。
  2. Canny边缘检测:接下来利用图像的梯度来计算图像中物体的边界或边缘。Canny(模糊灰度、低阈值、高阈值)是用于执行Canny边缘检测的函数,其中低阈值和高阈值是用于检测边缘的强度的阈值。我们使用的值为low_threshold=50 high_threshold=150。
  3. 选择兴趣区域:接下来定义一个四边形来遮罩感兴趣的区域。如前所述,可以找到车道线的图像部分被识别出来,在我们的例子中,是图像下半部分,用多边形对搜索区域进行限定,而图像的其他区域则被屏蔽。
  4. 霍夫转换:一旦在图像中检测到像素边缘,就会运用霍夫变换连接这些边缘像素点,以组成车道线。HoughLinesP是一个函数,它从Canny获取输入图像和一些其他参数,以便定义车道线。霍夫变换的输出包含所有车道线(实线/虚线)。下一步是找到一条共同的平均线来平滑所有车道线。
  5. 求直线的平均方程和平滑:一旦线条在图像中被识别出来,它们就被传递到绘制线(line_img,lines)函数中,该函数可以找到直线的平均方程。它通过计算坡度来划分左右车道线。负值对应于从右到左的正值(基于图像坐标)。 一旦有了独立的左/右直线,则通过累积每个左/右线中的所有点并通过这些点找到平均拟合来计算每个左/右直线的坡度和截距。
  6. 外推法:一旦有了平均左/右线,他们将外推生成一个共同的平均车道线(实线)。一旦流程开始处理测试图像。对视频的每一帧进行相同的操作,以生成整个视频中的车道线。

即使车道线颜色不同(黄色、白色),形状不同(实线、虚线等),这个流程最终也能在视频中检测到车道线。

即使代码在车道线是直线的情况下效果很好,但当直线更弯曲时,效果就不太理想了,我们在方程中拟合直线。另外,当灯光变化时,该算法很难检测到车道。未来可以通过使用二次多项式来解释曲线车道,以及使用不同的车道识别技术以获得更精确的结果这两种方法来改进目前的方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值