Advertisement

自动驾驶:车道线检测及车位线检测

阅读量:

本文介绍了基于颜色分割和边缘检测的车道检测方法。首先,在环境搭建部分使用了Anaconda进行技术配置,并详细描述了从视频获取每一帧的过程(如读取帧数、灰度化处理等)。接着,在边缘检测方法中使用了Canny算法(代码示例),并通过霍夫变换进一步优化车道检测效果(代码示例)。整个流程包括颜色分割(处理白色车道)、Canny边缘检测以及霍夫变换结合的结果显示(如中间结果图片)。最终实现了对原始视频的输出效果并提供了对应的代码实现(如linesedges = cv2.addWeighted(coloredges, 0.8, line_image, 1, 0))。

文章目录

  • 环境搭建

    • anaconda
  • 步骤

    • 使用颜色分割
  • 边缘检测方法

  • 霍夫变换 + canny

  • 以下是部分源码

环境搭建

anaconda

步骤

从视频中提取出每一帧。
将所有帧转换为灰度图像。
通过Canny算法进行边缘检测。
利用霍夫变换识别车道线。
优化输出结果后生成新的视频文件。

中间结果图片
中间结果图片
中间结果
最终效果图

基于车道检测生成的视频输出结果, 百度网盘存储

使用颜色分割

复制代码
    车道的颜色通常是白色的。当日光充足时,您可以轻松地检测到白色车道,但请考虑一下夜晚。几乎无法检测到车道。但这不是拒绝颜色分割算法的唯一原因。您可以想象在现实世界中有很多物体接近白色或完全白色。对象具有某些特征,例如颜色,形状,方向,位置等,这将有助于我们检测它们。
    
    
      
    
    AI助手
  • 红绿蓝的值范围是0(黑)到255(白)
复制代码
    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    import numpy as np
    
    image = mpimg.imread('./test_images/test.jpg')
    print('This image is: ', type(image), ', and the size of image is: ', image.shape)
    ysize = image.shape[0]
    xsize = image.shape[1]
    region_select = np.copy(image)
    color_select= np.copy(image)
    line_image = np.copy(image)
    
    print(1)
    red_threshold = 200
    green_threshold = 200
    blue_threshold = 200
    rgb_threshold = [red_threshold, green_threshold, blue_threshold]
    
    left_bottom = [0, 540]
    right_bottom = [960, 540]
    apex = [480, 320]
    
    fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
    fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
    fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)
    
    color_thresholds = (image[:,:,0] < rgb_threshold[0]) | (image[:,:,1] < rgb_threshold[1]) | (image[:,:,2] < rgb_threshold[2])
    XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
    
    region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & (YY > (XX*fit_right[0] + fit_right[1])) & (YY < (XX*fit_bottom[0] + fit_bottom[1]))
    
    color_select[color_thresholds] = [0,0,0]
    line_image[~color_thresholds & region_thresholds] = [255,0,0]
    region_select[region_thresholds] = [255, 0, 0]
    
    plt.imshow(region_select)
    
    plt.imshow(color_select)
    plt.imshow(line_image)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手

边缘检测方法

Canny边缘检测器是一种用于图像处理的边界识别工具,在这一领域中具有重要地位。该方法源自John F. Canny于1986年提出的创新性算法。

复制代码
    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    import cv2
    import numpy as np
    
    image = mpimg.imread('./test_images/exit-ramp.jpg')
    plt.imshow(image)
    
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    plt.imshow(gray, cmap='gray')
    
    kernel_size = 9
    blur_gray = cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
    
    low_threshold = 30
    high_threshold = 100
    edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
    
    plt.imshow(edges)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手

霍夫变换 + canny

  • 霍夫变换是一种用于图像分析、计算机视觉以及数字图像处理中的特征提取技术。该方法旨在通过投票机制识别特定形状中对象的不完整实例,并在参数空间中执行这一过程。具体而言,在参数空间(即累加器空间)中寻找候选对象中的局部最大值点。经典的霍夫变换主要用于检测直线,在此基础上它已被扩展以识别圆形、椭圆形等其他形状的位置关系。在图像空间中的一条直线对应于参数空间中的一个点,在这种理论指导下我们得以检测图片中的线条特征。
  • 霍夫算法包含一些关键参数设置这些参数对于算法性能至关重要
  • 视频处理与图片处理具有相似性其共同点在于均需对连续的帧数进行图像数据的处理
    • 从视频中逐帧读取图像数据
复制代码
    video = cv2.VideoCapture('test_videos\solidWhiteRight.mp4')
    # This line extracts just one frame in each run.
    frame = video.read()
    
    
      
      
      
    
    AI助手
  • 对于虚线,不是连续的,霍夫算法通过方程来计算

以下是部分源码

复制代码
    import cv2
    from matplotlib import pyplot as plt
    import matplotlib.image as mpimg
    import numpy as np
    from IPython.display import HTML
    from base64 import b64encode
    from math import floor
    
    # video = cv2.VideoCapture('test_videos\solidWhiteRight.mp4')
    # video = cv2.VideoCapture('test_videos\solidYellowLeft.mp4')
    video = cv2.VideoCapture('test_videos\challenge.mp4')
    nFrames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
    fps = video.get(cv2.CAP_PROP_FPS)
    waitPerFrameInMillisec = int(1/fps * 1000/1)
    frames_list = []
    # video_name = 'test_videos_output\output_solidWhiteRight.avi'
    # video_name = 'test_videos_output\output_solidYellowLeft.avi'
    video_name = 'test_videos_output\output_challenge.avi'
    success, image = video.read()
    height, width, layers = image.shape
    size = (width, height)
    out = cv2.VideoWriter(video_name, cv2.VideoWriter_fourcc(*'DIVX'), fps, size)
    
    def improve_lane(last_line, shape, top_line):
    x1 = last_line[0]
    y1 = last_line[1]
    x2 = last_line[2]
    y2 = last_line[3]
    y_bottom, x, layer = shape
    y_top = top_line + 10
    
    m = ((y2 - y1)/(x2 - x1))
    
    x_top = floor((1/m) * (y_top - y1) + x1)
    x_bottom = floor((1/m) * (y_bottom - y1) + x1)
    
    return [x_top, y_top, x_bottom, y_bottom]
    
    def run():
    success, image = video.read()
    if(success == True):
        line_image = np.copy(image) 
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        blur_gray = cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
        edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
        imshape = image.shape
    
        mask = np.zeros_like(edges)
        top_line = 320      #320
        left_line = 460     #460
        right_line = 500    #500
        vertices = np.array([[(0, imshape[0]), (left_line, top_line), (right_line, top_line), (imshape[1], imshape[0])]], dtype=np.int32)
        cv2.fillPoly(mask, vertices, ignore_mask_color)
        masked_edges = cv2.bitwise_and(edges, mask)
    
        lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)
        max_value_r = 0
        min_value_r = 100000
        max_value_l = 0
        min_value_l = 100000
        last_line_l_top = None
        last_line_l_bottom = None
        last_line_r_top = None
        last_line_r_bottom = None
        left_line_list = []
        right_line_list = []
        for line in lines:
            left_l = (line[0][0] < left_line) * line
            right_l = (line[0][0] > right_line) * line
            print('right_l: ', right_l)
            if left_l[0][0] != 0:
                left_line_list.append(left_l)
                if max_value_l < left_l[0][1]:
                    max_value_l = left_l[0][1]
                    last_line_l_bottom = left_l[0]
                    if max_value_l < left_l[0][3]:
                        max_value_l = left_l[0][3]
                        last_line_l_bottom = left_l[0]
    
                if min_value_l > left_l[0][1]:
                    min_value_l = left_l[0][1]
                    last_line_l_top = left_l[0]
                    if min_value_l > left_l[0][3]:
                        min_value_l = left_l[0][3]
                        last_line_l_top = left_l[0]
    
            if right_l[0][0] != 0:
                right_line_list.append(right_l)
                if max_value_r < right_l[0][1]:
                    max_value_r = right_l[0][1]
                    last_line_r_bottom = right_l[0]
                    if max_value_r < right_l[0][3]:
                        max_value_r = right_l[0][3]
                        last_line_r_bottom = right_l[0]
    
                if min_value_r > right_l[0][1]:
                    min_value_r = right_l[0][1]
                    last_line_r_top = right_l[0]
                    if min_value_r > right_l[0][3]:
                        min_value_r = right_l[0][3]
                        last_line_r_top = right_l[0]
    
        # for line in lines:
        #     for x1, y1, x2, y2 in line:
        #         cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
    
        x1_t, y1_t, x2_t, y2_t = improve_lane(last_line_l_top, image.shape, top_line)
        x1_b, y1_b, x2_b, y2_b = improve_lane(last_line_l_bottom, image.shape, top_line)
        x1 = floor((x1_t + x1_b) * 0.5)
        y1 = floor((y1_t + y1_b) * 0.5)
        x2 = floor((x2_t + x2_b) * 0.5)
        y2 = floor((y2_t + y2_b) * 0.5)
        cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
    
        if last_line_l_top is None:
            print('last_line_l_top')
    
        if last_line_l_bottom is None:
            print('last_line_l_bottom')
    
        f_valid = True
        if last_line_r_top is None:
            f_valid = False
    
        if last_line_r_bottom is None:
            f_valid = False
    
        if f_valid == True:
            x1 = last_line_r_top[0]
            x2 = last_line_r_top[2]
            if (x2 - x1) != 0:
                x1 = last_line_r_bottom[0]
                x2 = last_line_r_bottom[2]
                if (x2 - x1) != 0:
                    x1_t, y1_t, x2_t, y2_t = improve_lane(last_line_r_top, image.shape, top_line)
                    x1_b, y1_b, x2_b, y2_b = improve_lane(last_line_r_bottom, image.shape, top_line)
                    x1 = floor((x1_t + x1_b) * 0.5)
                    y1 = floor((y1_t + y1_b) * 0.5)
                    x2 = floor((x2_t + x2_b) * 0.5)
                    y2 = floor((y2_t + y2_b) * 0.5)
                    cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
    
        color_edges = np.dstack((edges, edges, edges))
        lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0)
        final_image = cv2.addWeighted(line_image, 0.8, image, 1, 0)
        out.write(final_image)
    
        image = None
        line_image = None
    
    # run()
    for i in range(0, nFrames - 1):
    run()
    
    
    out.release()
    
    print('Finished: ', len(frames_list))
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    AI助手

全部评论 (0)

还没有任何评论哟~