车道线检测

本节我们使用opencv来完成一个车道线检测的案例,下图为案例最终处理的结果

完成这样的案例我们需要经历哪些步骤呢 ? 我们先来思考一下解决问题的思路.当前情况下,摄像头拍出了很多的东西,例如路边的杂草远方的山.但是在我们自动驾驶的过程中,我们并不需要这么多东西,所以我们要考虑提取感兴趣的区域.有了感兴趣的区域之后,我们接下来就需要来识别道路.大家可能会想道路可能会有弯道,但是在小范围内,它还是直线,所以我们可以使用前面我们学过的霍夫直线来进行检测

这张摄像头拍摄到的照片

这张是我们使用canny边缘检测算法得到的图片

然后使用多边形截去不感兴趣的区域

通过以上三个步骤之后,下面我们就可以使用霍夫直线的方式,提取到车辆直线啦!

示例代码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

def canny(image):
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY);
    blur = cv.GaussianBlur(gray,(5,5),0)
    canny= cv.Canny(blur,50,100)
    return canny

def roi(image):
    height = image.shape[0]
    polygons = np.array([[(200,height),(1100,height),(550,250)]])
    mask = np.zeros_like(image);
    cv.fillPoly(mask,polygons,255)

    masked_image = cv.bitwise_and(image,mask)
    return masked_image

def display_lines(image,lines):
    line_image = np.zeros_like(image);

    for line in lines:
        x1,y1,x2,y2 = line.reshape(4)
        cv.line(line_image,(x1,y1),(x2,y2),(255,255,0),10);

    return line_image

def make_coordinates(image,parameters):
    slope = parameters[0]
    intercept = parameters[1]

    y1 = image.shape[0]
    y2 = int(y1*0.6)

    x1 = int((y1 - intercept)/slope)
    x2 = int((y2 - intercept)/slope)

    return np.array([x1,y1,x2,y2])



def average_slop_intercept(image,lines):
    left_fit = []
    right_fit = []
    print(lines)
    for line in lines:
        x1, y1, x2, y2 = line.reshape(4)
        print(x1,y1,x2,y2)
        parameters = np.polyfit((x1,x2),(y1,y2),1)
        print(parameters)
        slope = parameters[0]
        intercept = parameters[1]

        if slope > 0 :
            left_fit.append((slope,intercept))
        else:
            right_fit.append((slope,intercept))


    #yong
    result_lines = []
    if len(left_fit):
        left_fit_average = np.average(left_fit, axis=0)
        left_line = make_coordinates(image,left_fit_average)
        result_lines.append(left_line)
    if len(right_fit)>0:
        right_fit_average = np.average(right_fit, axis=0)
        right_line = make_coordinates(image,right_fit_average)
        result_lines.append(right_line)

    return result_lines

cv.namedWindow("result",cv.WINDOW_NORMAL)

capture = cv.VideoCapture()
capture.open("test2.mp4")

if capture.isOpened():
    flag = True
    while flag:
        flag,image = capture.read();
        if not flag: break
        # image = cv.imread("test_image.jpg")
        lane_image = image # np.copy(image);
        print(lane_image.shape)
        canny_image = canny(lane_image)

        cropped_image = roi(canny_image)

        lines = cv.HoughLinesP(cropped_image,2,np.pi/180,100,minLineLength=40,maxLineGap=5)

        average_lines = average_slop_intercept(image,lines)
        lines_image = display_lines(lane_image,average_lines)

        combo_image = cv.addWeighted(lane_image,0.8,lines_image,1,1)

        cv.imshow("result",combo_image)
        cv.waitKey(10)

cv.waitKey(0)
cv.destroyAllWindows()