传统车道线检测

来源:https://github.com/rslim087a/road-video/blob/master/test2.mp4
https://github.com/rslim087a/road-image

1、Convert Image to grayscale and Reduce Noise

#灰度处理
gray = cv2.cvtColor(lane_image,cv2.COLOR_RGB2GRAY)
#高斯模糊
blur = cv2.GaussianBlur(gray,(5,5),0)

模糊后图像:传统车道线检测_第1张图片

2、Canny edge detection and finding lane lines regoin of interest

canny = cv2.Canny(blur,50,150)

边缘检测图像:
传统车道线检测_第2张图片
需要的区域坐标:
传统车道线检测_第3张图片

#设定一个mask,只显示将需要的区域
def region_of_interest(image):
 	height = image.shape[0]
 	polygons = np.array([[(200,height),(1100,height),(550,250)]])
 	mask = np.zeros_like(image)
 	cv2.fillPoly(mask,polygons,255)
	 return mask

传统车道线检测_第4张图片

#将mask与canny图像合并
mask_image = cv2.bitwise_and(image,mask)
return mask_image

传统车道线检测_第5张图片
通过霍夫线变换画出车道直线

def display_lines(image,lines):
    line_image = np.zeros_like(image)
    if lines is not None:
        for line in lines:
            x1,y1,x2,y2 = line.reshape(4)
            cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
    return line_image
lines = cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),40,5)
line_image = display_lines(image,lines)
combo_image = cv2.addWeighted(image,0.8,line_image,1,1)

传统车道线检测_第6张图片

调整直线:

def average_slope_intercept(image,lines):
    left_fit = []
    right_fit = []
    for line in lines:
        x1,y1,x2,y2 = line.reshape(4)
        #拟合多项式,并且返回斜率和截距
        parameters = np.polyfit((x1,x2),(y1,y2),1)  #‘1’代表一次多项式
        #print(parameters)
        slope = parameters[0]
        intercept = parameters[1]
        #左车道直线斜率小于0,右车道直线斜率大于0
        if slope < 0 :
            left_fit.append((slope,intercept))
        else:
            right_fit.append((slope,intercept))
    #平均左车道线的斜率,平均右车道线的斜率
    left_fit_average = np.average(left_fit,axis=0)
    right_fit_averge = np.average(right_fit,axis=0)
    # 返回的是该斜率直线的两个端点
    left_line = make_coordinates(image,left_fit_average)
    right_line = make_coordinates(image,right_fit_averge)
    return np.array([left_line,right_line])
def make_coordinates(image,line_parameters):
    # 确定直线的两个端点(x1,y1),(x2,y2)
    slope,intercept = line_parameters
    y1 = image.shape[0]
    y2 = int(y1*(3/5))
    x1 = int((y1 - intercept)/slope)
    x2 = int((y2 - intercept) / slope)
    return np.array([x1,y1,x2,y2])
# 返回的两个端点
averaged_lines = average_slope_intercept(image,lines)
#将检测到的直线在图片上画出
line_image = display_lines(image,averaged_lines)
combo_image = cv2.addWeighted(image,0.8,line_image,1,1) 

传统车道线检测_第7张图片

import cv2
import numpy as np
import  matplotlib.pyplot as plt
def canny_image(image):
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    blur = cv2.GaussianBlur(gray, (5, 5), 0)
    canny = cv2.Canny(blur, 50, 150)
    return canny
def region_of_interest(image):
    height = image.shape[0]
    polygons = np.array([[(200,height),(1100,height),(550,250)]])
    mask = np.zeros_like(image)
    cv2.fillPoly(mask,polygons,255)
    mask_image = cv2.bitwise_and(image,mask)
    return mask_image
def display_lines(image,lines):
    line_image = np.zeros_like(image)
    if lines is not None:
        for x1,y1,x2,y2 in lines:
            cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)
    return line_image

def average_slope_intercept(image,lines):
    left_fit = []
    right_fit = []
    for line in lines:
        x1,y1,x2,y2 = line.reshape(4)
        #拟合多项式,并且返回斜率和截距
        parameters = np.polyfit((x1,x2),(y1,y2),1)  #‘1’代表一次多项式
        #print(parameters)
        slope = parameters[0]
        intercept = parameters[1]
        #左车道直线斜率小于0,右车道直线斜率大于0
        if slope < 0 :
            left_fit.append((slope,intercept))
        else:
            right_fit.append((slope,intercept))
    #平均左车道线的斜率,平均右车道线的斜率
    left_fit_average = np.average(left_fit,axis=0)
    right_fit_averge = np.average(right_fit,axis=0)
    # 返回的是该斜率直线的两个端点
    left_line = make_coordinates(image,left_fit_average)
    right_line = make_coordinates(image,right_fit_averge)
    return np.array([left_line,right_line])
def make_coordinates(image,line_parameters):
    # 确定直线的两个端点(x1,y1),(x2,y2)
    slope,intercept = line_parameters
    y1 = image.shape[0]
    y2 = int(y1*(3/5))
    x1 = int((y1 - intercept)/slope)
    x2 = int((y2 - intercept) / slope)
    return np.array([x1,y1,x2,y2])

'''''''''''''''''''''''''''''''''''''''''''''
                  图像检测
'''''''''''''''''''''''''''''''''''''''''''''
image = cv2.imread('test_image.jpg')
canny = canny_image(image)
#用plt求出所需区域的坐标
# plt.imshow(canny)
# plt.show()
#从边缘检测图像中画出车道线
cropped_image = region_of_interest(canny)
#霍夫线变换,检测直线
lines = cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),40,5)
# 返回的两个端点
averaged_lines = average_slope_intercept(image,lines)
#将检测到的直线在图片上画出
line_image = display_lines(image,averaged_lines)
combo_image = cv2.addWeighted(image,0.8,line_image,1,1)   #cv2.addWeighted图像混合叠加
cv2.imshow('result',combo_image)
cv2.waitKey(0)
'''''''''''''''''''''''''''''''''''''''''''''
                  图像检测
'''''''''''''''''''''''''''''''''''''''''''''


'''''''''''''''''''''''''''''''''''''''''''''
                  视频检测
'''''''''''''''''''''''''''''''''''''''''''''
# cap = cv2.VideoCapture('test2.mp4')
# while True:
#     ret, frame = cap.read()
#     canny = canny_image(frame)
#     # 从边缘检测图像中画出车道线
#     cropped_image = region_of_interest(canny)
#     # 霍夫线变换,检测直线
#     lines = cv2.HoughLinesP(cropped_image, 2, np.pi / 180, 100, np.array([]), 40, 5)
#     # 返回的两个端点
#     averaged_lines = average_slope_intercept(frame, lines)
#     # 将检测到的直线在图片上画出
#     line_image = display_lines(frame, averaged_lines)
#     combo_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)  # cv2.addWeighted图像混合叠加
#     cv2.imshow('result', combo_image)
#     if cv2.waitKey(1) & 0xff == ord('q'):
#         break
# cap.release()
# cv2.destroyAllWindows()
'''''''''''''''''''''''''''''''''''''''''''''
                  视频检测
'''''''''''''''''''''''''''''''''''''''''''''

你可能感兴趣的:(传统车道线检测)