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

本文详细介绍了车道线检测的概念、常用方法(包括基于图像处理、机器学习、深度学习等),以及整体流程,重点讲解了ROI选择、Canny边缘检测和霍夫变换的应用。作者强调了在实际应用中工具使用的重要性,而非深入算法原理。
摘要由CSDN通过智能技术生成

概要

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算法,霍夫算法等算法背后的逻辑及处理,尽管理解算法原理是有帮助的,但在实际应用中,更重要的是掌握工具的使用方法。因此,在学习图像处理算法时,我们应该注重掌握工具的使用,并了解如何将它们应用到实际问题上。

  • 26
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值