Python Opencv基础版车道线检测1.0

文章目录

  • 概要
  • 整体架构流程
  • 技术名词解释
  • 技术细节
  • 小结
  • 概要

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

    作者:Dream_orz

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python Opencv基础版车道线检测1.0

    发表回复