【检测原理】
一、首先进行canny边缘检测,为获取车道线边缘做准备
二、进行ROI提取获取确切的车道线边缘(红色线内部)
三、利用概率霍夫变换获取直线,并将斜率正数和复数的线段给分割开来
四、离群值过滤,剔除斜率相差过大的线段
五、最小二乘拟合,实现将左边和右边的线段互相拟合成一条直线,形成车道线
六、绘制线段
【代码解读】
LaneDetector
类包含了几个用于车道线检测的关键方法。这些方法分别用于将图像转换为灰度图、应用高斯模糊、应用Canny边缘检测以及定义和应用感兴趣区域(ROI)。以下是这些方法的详细解释:
- grayscale(self, img):
- 这个方法接收一个彩色图像作为输入(通常是BGR格式),然后使用
cv2.cvtColor
函数将其转换为灰度图像。 - 转换后的图像只有一个颜色通道,像素值范围通常是0到255,其中0表示黑色,255表示白色。
- 这个方法接收一个彩色图像作为输入(通常是BGR格式),然后使用
- canny(self, img, low_threshold, high_threshold):
- 这个方法接收一个灰度图像和两个阈值作为输入。
- 使用
cv2.Canny
函数来检测图像中的边缘。这个函数使用两个阈值来检测强弱边缘,并返回一个二值图像,其中边缘用白色像素表示。
- gaussian_blur(self, img, kernel_size):
- 这个方法接收一个图像和一个核大小作为输入。
- 使用
cv2.GaussianBlur
函数对图像进行高斯模糊,以减少图像中的噪声和细节,这对于边缘检测等后续处理步骤是有益的。
- region_of_interest(self, img, vertices):
- 这个方法接收一个图像和一个由顶点组成的列表(通常是多边形)作为输入。
- 创建一个与输入图像大小和类型相同的零矩阵作为遮罩。
- 根据输入图像是彩色还是灰度,设置用于填充遮罩的颜色。对于彩色图像,这是一个三通道(或四通道,如果包括透明度)的元组,所有通道的值都设置为255(白色)。对于灰度图像,它只是一个标量值255。
- 使用
cv2.fillPoly
函数在遮罩上填充多边形内部,将多边形内部的像素设置为指定的填充颜色。 - 使用
cv2.bitwise_and
函数将输入图像和遮罩进行按位与操作,只保留遮罩中非零像素对应的图像部分。这实际上是将图像裁剪到多边形定义的ROI。
这个方法中的vertices
参数应该是一个包含多个点的列表,这些点定义了多边形的顶点。每个点都是一个包含两个坐标(x, y)的元组。例如,对于梯形ROI,vertices
可能看起来像这样(取决于图像的尺寸和所需的梯形大小):
vertices = [ [(x1, y1), (x2, y2), (x3, y3), (x4, y4)] # 四个顶点的坐标 ]
请注意,vertices
实际上是一个列表的列表,因为cv2.fillPoly
函数可以接受多个多边形,但在这个上下文中,我们只使用一个多边形来定义ROI。
这些方法构成了车道线检测算法的前置处理步骤。要完成整个车道线检测流程,您还需要实现直线检测(通常使用霍夫变换)和直线拟合(例如使用最小二乘法)。此外,您可能还需要实现一些后处理步骤,如过滤掉不相关的线、将检测到的线绘制在原始图像上等。
hough_lines
函数:这个函数接收一个Canny边缘检测后的图像、ρ值、θ值、阈值、最小线段长度和最大线段间隔作为输入,并返回一个画有霍夫线的图像。霍夫变换用于检测图像中的直线。weighted_img
函数:这个函数接收一个带有霍夫线的图像、初始图像以及三个权重参数(α、β、λ)作为输入,并返回一个根据给定公式计算得出的加权图像。这个公式将初始图像、带有霍夫线的图像以及一个常数λ相加,其中α和β是权重参数。filter_colors
函数:这个函数接收一个图像作为输入,并返回一个只包含黄色和白色像素的图像。它首先过滤出白色像素,然后过滤出黄色像素,最后将两个过滤后的图像以相同的权重相加。
这些函数一起工作,首先使用Canny边缘检测和霍夫变换检测车道线,然后使用加权图像合并原始图像和检测到的车道线,最后过滤出黄色和白色像素以进一步处理。
【效果展示】
【代码调用】
图像检测或者视频检测调用非常简单
ld = LaneDetector()
# ld.detect_image('test_images/solidWhiteCurve.jpg')
ld.detct_video('solidWhiteRight.mp4')
【测试环境】
anaconda3+python3.8
opencv-python==4.7.0.68
【源码下载】