# Implementation of Python road lane detection

Time：2022-5-13

Lane line detection is a key component of autonomous vehicle and general computer vision. This concept is used to describe the path of a autonomous vehicle and to avoid the risk of entering another lane.

In this paper, we will build a machine learning project to detect lane lines in real time. We will use the opencv library to do this using the concept of computer vision. In order to detect the lane, we must detect the white marks on both sides of the lane. Road lane line detection using Python and opencv
Using the computer vision technology in Python, we will identify the road lane lines that autonomous vehicle must travel. This will be a key part of autonomous vehicle, because autonomous vehicle should not cross its lane or enter the opposite lane to avoid accidents.

Frame mask and Hough line transform
To detect white markings in the lane, first, we need to mask the rest of the frame. We use frame masking to do this. This frame is just a numpy array of image pixel values. In order to mask unnecessary pixels in the frame, we only need to update these pixel values in the numpy array to 0.

After production, we need to check the lane line. The technique used to detect such mathematical shapes is called Hough transform. Hough transform can detect rectangle, circle, triangle and straight line.

Follow these steps to detect lane lines in Python:

1. Import package

``````
import matplotlib.pyplot as plt

import numpy as np
import cv2
import os
import matplotlib.image as mpimg
from moviepy.editor import VideoFileClip
import math
``````

2. Apply frame masking and find the region of interest:

``````
def interested_region(img, vertices):
if len(img.shape) > 2:
else:

return cv2.bitwise_and(img, np.zeros_like(img))
``````

3. Pixel to line conversion in Hough transform space:

``````
def hough_lines(img, rho, theta, threshold, min_line_len, max_line_gap):
lines = cv2.HoughLinesP(img, rho, theta, threshold, np.array([]), minLineLength=min_line_len, maxLineGap=max_line_gap)
line_img = np.zeros((img.shape, img.shape, 3), dtype=np.uint8)
lines_drawn(line_img,lines)
return line_img
``````

4. Create two lines in each frame after Hough transform:

``````
def lines_drawn(img, lines, color=[255, 0, 0], thickness=6):
global cache
global first_frame
slope_l, slope_r = [],[]
lane_l,lane_r = [],[]

α =0.2
for line in lines:
for x1,y1,x2,y2 in line:
slope = (y2-y1)/(x2-x1)
if slope > 0.4:
slope_r.append(slope)
lane_r.append(line)
elif slope < -0.4:
slope_l.append(slope)
lane_l.append(line)
img.shape = min(y1,y2,img.shape)
if((len(lane_l) == 0) or (len(lane_r) == 0)):
print ('no lane detected')
return 1
slope_mean_l = np.mean(slope_l,axis =0)
slope_mean_r = np.mean(slope_r,axis =0)
mean_l = np.mean(np.array(lane_l),axis=0)
mean_r = np.mean(np.array(lane_r),axis=0)

if ((slope_mean_r == 0) or (slope_mean_l == 0 )):
print('dividing by zero')
return 1

x1_l = int((img.shape - mean_l - (slope_mean_l * mean_l))/slope_mean_l)
x2_l = int((img.shape - mean_l - (slope_mean_l * mean_l))/slope_mean_l)
x1_r = int((img.shape - mean_r - (slope_mean_r * mean_r))/slope_mean_r)
x2_r = int((img.shape - mean_r - (slope_mean_r * mean_r))/slope_mean_r)

if x1_l > x1_r:
x1_l = int((x1_l+x1_r)/2)
x1_r = x1_l
y1_l = int((slope_mean_l * x1_l ) + mean_l - (slope_mean_l * mean_l))
y1_r = int((slope_mean_r * x1_r ) + mean_r - (slope_mean_r * mean_r))
y2_l = int((slope_mean_l * x2_l ) + mean_l - (slope_mean_l * mean_l))
y2_r = int((slope_mean_r * x2_r ) + mean_r - (slope_mean_r * mean_r))
else:
y1_l = img.shape
y2_l = img.shape
y1_r = img.shape
y2_r = img.shape

present_frame = np.array([x1_l,y1_l,x2_l,y2_l,x1_r,y1_r,x2_r,y2_r],dtype ="float32")

if first_frame == 1:
next_frame = present_frame
first_frame = 0
else :
prev_frame = cache
next_frame = (1-α)*prev_frame+α*present_frame

cv2.line(img, (int(next_frame), int(next_frame)), (int(next_frame),int(next_frame)), color, thickness)
cv2.line(img, (int(next_frame), int(next_frame)), (int(next_frame),int(next_frame)), color, thickness)

cache = next_frame
``````

5. Process each frame of video to detect the lane:

``````
def weighted_img(img, initial_img, α=0.8, β=1., λ=0.):
return cv2.addWeighted(initial_img, α, img, β, λ)

def process_image(image):

global first_frame

gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
img_hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)

lower_yellow = np.array([20, 100, 100], dtype = "uint8")
upper_yellow = np.array([30, 255, 255], dtype="uint8")

canny_edges=cv2.Canny(gauss_gray, 50, 150)

imshape = image.shape
lower_left = [imshape/9,imshape]
lower_right = [imshape-imshape/9,imshape]
top_left = [imshape/2-imshape/8,imshape/2+imshape/10]
top_right = [imshape/2+imshape/8,imshape/2+imshape/10]
vertices = [np.array([lower_left,top_left,top_right,lower_right],dtype=np.int32)]
roi_image = interested_region(canny_edges, vertices)

theta = np.pi/180

line_image = hough_lines(roi_image, 4, theta, 30, 100, 180)
result = weighted_img(line_image, image, α=0.8, β=1., λ=0.)
return result
``````

6. Clip the input video into frames and get the results. Output the video file:

``````
first_frame = 1
white_output = '__path_to_output_file__'
clip1 = VideoFileClip("__path_to_input_file__")
white_clip = clip1.fl_image(process_image)
white_clip.write_videofile(white_output, audio=False)
``````

GUI code of lane line detection items: ``````
import tkinter as tk
from tkinter import *
import cv2
from PIL import Image, ImageTk
import os
import numpy as np

global last_frame1
last_frame1 = np.zeros((480, 640, 3), dtype=np.uint8)
global last_frame2
last_frame2 = np.zeros((480, 640, 3), dtype=np.uint8)
global cap1
global cap2
cap1 = cv2.VideoCapture("path_to_input_test_video")
cap2 = cv2.VideoCapture("path_to_resultant_lane_detected_video")

def show_vid():
if not cap1.isOpened():
print("cant open the camera1")
frame1 = cv2.resize(frame1,(400,500))
if flag1 is None:
print ("Major error!")
elif flag1:
global last_frame1
last_frame1 = frame1.copy()
pic = cv2.cvtColor(last_frame1, cv2.COLOR_BGR2RGB)
img = Image.fromarray(pic)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, show_vid)

def show_vid2():
if not cap2.isOpened():
print("cant open the camera2")
frame2 = cv2.resize(frame2,(400,500))
if flag2 is None:
print ("Major error2!")
elif flag2:
global last_frame2
last_frame2 = frame2.copy()
pic2 = cv2.cvtColor(last_frame2, cv2.COLOR_BGR2RGB)
img2 = Image.fromarray(pic2)
img2tk = ImageTk.PhotoImage(image=img2)
lmain2.img2tk = img2tk
lmain2.configure(image=img2tk)
lmain2.after(10, show_vid2)

if __name__ == '__main__':
root=tk.Tk()
lmain = tk.Label(master=root)
lmain2 = tk.Label(master=root)

lmain.pack(side = LEFT)
lmain2.pack(side = RIGHT)
root.title("Lane-line detection")
root.geometry("900x700+100+10")
exitbutton = Button(root, text='Quit',fg="red",command=   root.destroy).pack(side = BOTTOM,)
show_vid()
show_vid2()
root.mainloop()
cap.release()
``````