车道线检测1.0(Python+Opencv基础版)

avatar
作者
猴君
阅读量:2

文章目录

概要

1.什么叫做车道线检测?

        车道线检测是指在道路上自动检测和识别车道线的过程。车道线是道路上的标记,用于指示车辆行驶的方向和位置。

        通过对车道线进行检测和识别,自动驾驶和智能驾驶系统可以实现车辆的自动导航、车道保持、车道偏离警告等功能。

2. 车道线的检测方式有哪些?

  1. 基于图像处理的方法:这是最常见的车道线检测方法之一。它通过对摄像头捕获的图像进行预处理、边缘检测、霍夫变换等图像处理技术,来检测并提取车道线。

  2. 基于机器学习的方法:这种方法使用机器学习算法,如支持向量机(SVM)、随机森林(Random Forest)或深度学习网络(如卷积神经网络)来训练模型,从而实现车道线检测。

  3. 基于传感器融合的方法:这种方法结合了多种传感器的数据,如摄像头、激光雷达、毫米波雷达等。通过融合各种传感器的信息,可以提高车道线检测的准确性和鲁棒性。

  4. 基于特征匹配的方法:这种方法通过提取车道线特征,并与预先定义的模板进行匹配来实现检测。常用的特征包括车道线的颜色、纹理和形状等。

  5. 基于深度学习的方法:深度学习在车道线检测中也取得了很大的成功。通过使用深度学习网络,如卷积神经网络(CNN),可以直接从图像中学习车道线的特征,并进行检测和跟踪。

整体架构流程

  1. 将图像转换为灰度图像。(简化图像处理的复杂性并提高算法的效率)
  2. 对灰度图像进行高斯模糊处理,以降低噪声的影响。(减少对车道线判定的干扰)
  3. 使用Canny边缘检测算法提取图像的边缘。
  4. 定义感兴趣区域,使用region_of_interest函数提取该区域的边缘。(这个区域的选取很重要)
  5. 使用霍夫变换检测直线,得到车道线的坐标。(也很重要)
  6. 创建一个空白图像,并使用draw_lines函数在空白图像上绘制检测到的车道线。
  7. 将绘制了车道线的图像与原图像叠加,得到最终结果。

 以上ROI区域的选取,Canny的阙值控制和霍夫变换的阙值的控制,这些都是比较重要的取值,需要根据环境不断测试,直到达到一个较好的效果。


技术名词解释

ROI(Region of Interest):

ROI是指图像中的感兴趣区域,也就是我们希望在图像中进行特定处理或分析的区域。通过定义ROI,我们可以限制算法的作用范围,提高计算效率。

Canny:

Canny边缘检测算法是一种经典的边缘检测算法。它包含以下几个步骤:

  1. 对图像进行灰度化处理。
  2. 对灰度图像应用高斯模糊,以减少噪声。
  3. 计算图像中每个像素的梯度幅值和方向。
  4. 应用非最大抑制,将边缘像素细化为单像素线条。
  5. 应用双阈值处理,将边缘像素分类为强边缘、弱边缘和非边缘。
  6. 使用连接强边缘和弱边缘的过程来形成完整的边缘。

霍夫变换:

霍夫变换是一种用于检测图像中的直线、圆或其他形状的技术。对于检测直线,霍夫变换将每个像素点转换为参数空间中的曲线。当参数空间中的曲线相交时,表示图像中存在共线的像素点,从而检测出直线。对于检测圆或其他形状,霍夫变换会在参数空间中找到曲线的交点。


技术细节

1.定义一个提取ROI的函数

# 提取ROI,并与原图像取与 def region_of_interest(img, vertices):     # 创建一个与输入图像相同大小的全黑掩膜图像     mask = np.zeros_like(img)          # 在掩膜图像上绘制多边形ROI区域,填充为白色(255)     cv2.fillPoly(mask, vertices, 255)          # 对原图像和掩膜图像进行按位与操作,提取ROI区域     masked_image = cv2.bitwise_and(mask, img)          # 返回提取的ROI图像     return masked_image

2.定义绘制车道线的函数 

# 绘制车道线 def draw_lines(img, lines, color=(0, 0, 255), thickness=3):     if lines is not None:         # 遍历每条检测到的线段         for line in lines:             # 提取线段的起点和终点坐标             for x1, y1, x2, y2 in line:                 # 在原图像上绘制直线                 cv2.line(img, (int(x1), int(y1)), (int(x2), int(y2)), color, thickness)

其中第一个判断是重要的,你可以思考一下为什么。

 3.车道线检测函数(将使用上边两个函数)

# 车道线检测 def lane_detection(image):   gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)     # 将图像转换为灰度图像    blur = cv2.GaussianBlur(gray, (5, 5), 0)     # 对灰度图像进行高斯模糊处理,降低噪声影响    edges = cv2.Canny(blur, 175, 200)     # 使用Canny边缘检测算法提取图像边缘    height, width = edges.shape     # 获取边缘图像的尺寸   roi_vertices = [     (0, height),     (width * 0.5, height * 0.4),     (width * 0.5, height * 0.4),     (width, height) ]   roi_edges = regiong_of_interest(edges, np.array([roi_vertices], np.int32   ))    # 提取感兴趣区域的边缘    # 使用霍夫变换检测直线   lines = cv2.HoughLinesP(roi_edges, rho=2, theta=np.pi / 180, threshold=100, minLineLength=0, maxLineGap=175)    line_image = np.zeros_like(image)     # 创建一个空白图像,用于绘制检测到的车道线    draw_lines(line_image, lines)     # 绘制检测到的车道线    result = cv2.addWeighted(image, 0.8, line_image, 1, 0)     # 将绘制了车道线的图像与原图像叠加    return result

4.程序的主循环控制,输入与输出 

cap = cv2.VideoCapture(r"E:\User\素材\车道线识别素材\1-车道线识别素材.mp4")   # 创建VideoCapture对象,打开视频文件或连接摄像头  while(cap.isOpened()):   ret, frame = cap.read()   # 读取当前帧    if not ret:     print("1")     break   # 若读取失败,退出循环    result = lane_detection(frame)   # 对当前帧进行车道线检测    cv2.imshow("Lane Detection", result)   # 在窗口中显示结果图像    if cv2.waitKey(1) & 0xFF == 27:   # 按下键盘上的'ESC'键退出循环     print("2")     break  cap.release()  # 释放视频资源 cv2.destroyAllWindows()  # 关闭显示窗口

按ESC退出视频播放环节

5.完整代码 

import cv2 import numpy as np  # 提取ROI,并与原图像取与 def regiong_of_interest(img, vertices):   mask = np.zeros_like(img)   cv2.fillPoly(mask, vertices, 255)   masked_image = cv2.bitwise_and(mask, img)   return masked_image  # 绘制车道线 def draw_lines(img, lines, color=(0, 0, 255), thickness=3):     if lines is not None:         for line in lines:             for x1, y1, x2, y2 in line:                 cv2.line(img, (int(x1), int(y1)), (int(x2), int(y2)), color, thickness)  # 车道线检测 def lane_detection(image):   gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)     # 将图像转换为灰度图像    blur = cv2.GaussianBlur(gray, (5, 5), 0)     # 对灰度图像进行高斯模糊处理,降低噪声影响    edges = cv2.Canny(blur, 175, 200)     # 使用Canny边缘检测算法提取图像边缘    height, width = edges.shape     # 获取边缘图像的尺寸   roi_vertices = [     (0, height),     (width * 0.5, height * 0.4),     (width * 0.5, height * 0.4),     (width, height) ]   roi_edges = regiong_of_interest(edges, np.array([roi_vertices], np.int32   ))    # 提取感兴趣区域的边缘    # 使用霍夫变换检测直线   lines = cv2.HoughLinesP(roi_edges, rho=2, theta=np.pi / 180, threshold=100, minLineLength=0, maxLineGap=175)    line_image = np.zeros_like(image)     # 创建一个空白图像,用于绘制检测到的车道线    draw_lines(line_image, lines)     # 绘制检测到的车道线    result = cv2.addWeighted(image, 0.8, line_image, 1, 0)     # 将绘制了车道线的图像与原图像叠加    return result  cap = cv2.VideoCapture(r"E:\User\素材\车道线识别素材\1-车道线识别素材.mp4")  # 创建VideoCapture对象,打开视频文件或连接摄像头  while(cap.isOpened()):   ret, frame = cap.read()  # 读取当前帧   if not ret:     print("1")     break  # 若读取失败,退出循环    result = lane_detection(frame)  # 对当前帧进行车道线检测   cv2.imshow("Lane Detection", result)  # 在窗口中显示结果图像    if cv2.waitKey(1) & 0xFF == 27:  # 按下键盘上的'ESC'键退出循环     print("2")     break  cap.release()  # 释放视频资源 cv2.destroyAllWindows()  # 关闭显示窗口

6. 效果如下

视频链接在下边

车道线检测1.0-CSDN直播

弯道有点拉跨,不过直道还不错,素材可以自己搜着下,自己拍也行(手动滑稽)。 

小结

在这篇文章里,我们不需要深入了解Canny算法,霍夫算法等算法背后的逻辑及处理,尽管理解算法原理是有帮助的,但在实际应用中,更重要的是掌握工具的使用方法。因此,在学习图像处理算法时,我们应该注重掌握工具的使用,并了解如何将它们应用到实际问题上。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!