Road Lane Line Detection Using OpenCV Py
Road Lane Line Detection Using OpenCV Py
Devs_Team
Team mebers:
1. Mirzakhmedov Shokhrukhmirzo – u1610230(Team leader)
2. Abbosjon Kudratov - u1610001
3. Solikh Mirzaev – u1610234
4. Boburjon Borataliyev – u1610053
Problem statement
To detect the lane lines in a road sample video and show the detected lines in the frame.
Make prediction according to detected lines about turns car is about make.
Algorithm
The process of lane lines detection can be divided into the following steps:
1) Image denoising
Pre-implementation steps:
We used in this project OpenCV library to do main tasks along with the help of other libraries
like numpy, imutils and matplotlib
import cv2
import numpy as np
import imutils
import matplotlib.pyplot as plt
We defined the function to process the frames of video. As video is a sequence of image
frames, first we need to load the video and we can process each frame as individual image.
while True:
# ret = frame capture result
# frame = captured frame
ret, frame = videofile.read()
frame = process_image(frame)
try:
# cv2.imshow("video", frame)
cv2.imshow('with lines', frame)
except:
pass
If the variable ret becomes false it means we reached the end of the video. To quit from the
loop we define waitKey() function with trigger some key pressed to break:
if ret is False:
print('end of video!!: break!')
break
All code about processing the frame image we defined inside the function process_image()
Passed as argument image has is shape property. As it is colored image frame it has inside
shape property height, width and channel count. With help of resize() function of cv2 we
resize and store the image and load to another variable:
def process_image(img):
# resize the frame image:
if img is not None:
h, w, d = img.shape
frame = cv2.resize(img, (int(w / 1.4), int(h / 1.4))) # store the resized image in another variable
To do denoising of image – one of the best ways to make it using Gaussian filter or
Gaussian Blur with kernel matrix 5x5:
lane_img = np.copy(frame)
# apply Gaussian filter to smooth the image:
blurred = cv2.GaussianBlur(lane_img, (5, 5), 1)
Before detecting edges we need to convert our colored 3-channel blurred image to 1-
channel grayscale image using cvtColor() function of cv2
# convert to grascale
gray = cv2.cvtColor(blurred, cv2.COLOR_BGR2GRAY)
Now to binarize the image we apply thresholding technique. This code determines the
threshold automatically from the image using Otsu's method and returns tuple of binarized
image with its threshold value:
Binarization takes all values till 128 – converts into black and other values greater than 128 till 255 ->
into white
Binarized image
To detect edges we use Canny edge technique. We need 1-channel image to detect edges.
We defined auto_canny() function to make the edge detection better that gives us additional
parameters (sigma and median values), but main thing here is Canny() of cv2:
We are interested in only some defined region of the image. To find our ROI (region of
interest) we need points to crop accordingly.
We display the image using matplotlib to find some points on it to define ROI. Find the
approximate locations of these red dots to crop road ROI:
ROI_frame = [
(200,500),
(800,500),
(450,350) ]
To mask the image means leave out only the ROI and cover other useless parts. To do so
we have defined the function ROI_area_masking()
Call this function and store the returned image:
This function is defined very simple. We need image and vertices(points) as arguments.
Channel count is not defined for our canny edge detected image so we comment it out. With
cv2.fillPoly() we fill the polynomial defined by edges and then make ‘bitwise AND’ to apply
as a mask:
So we receive the masked cropped image like this with only detected edges (because we
passed to it our canny edge detected image) in our ROI:
4) Lines detection using Hough transform technique
We should convert Lines from x,y space to polar mc space. But first we use HoughLinesP()
probabilistic function to determine points for us and store in lines variable:
So the function avg_slope_intercept() is defined like this: it takes 4 points from passed line
and fits into polyfit from where it gets the slope and intercept as parameters array:
The slope helps us to identify which points are on the left or right:
To be able to draw the continuous line we have to find averages of these left or right points
arrays:
left_points_avg = np.average(left_points,
axis=0) # axis should be 0 because we want averages of columns in array
right_points_avg = np.average(right_points, axis=0)
And to draw them we will also need the coordinates and then we can return the arrays of
lines left and right. For making coordinates we will have to define another function
make_coordinates()
make_coordinates() function helps us to make coordinates for the line with given slope and
intercept:
Defined like this - it takes the argument image and averaged lines with defined points and
draws using cv2.line() function:
We defined function morph_closing() to refine lines – make them thicker and connect by
using the effect of morphological closing:
def morph_closing(image):
# P.S. erosion and dilation => ONLY APPLIED TO GRAY IMAGES!
# create 5x5 kernel with 1s
kernel = np.ones((5, 5), np.uint8)
kernel2 = np.ones((7, 7), np.uint8)
# apply dilation
#morphological closing = dilation , then erosion
frame_dilation = cv2.dilate(image, kernel2, iterations=2)
frame_erosion = cv2.erode(frame_dilation, kernel2, iterations=2)
#or alternatively
closing = cv2.morphologyEx(image,cv2.MORPH_DILATE,kernel2,iterations=2)
return closing
The resulting image with drawn detected lines: we have a problem identifying points to draw
lines simultaneously for right and left sides with function cv2.HoughLinesP() and its
parameters minLineLength and maxLineGap – we could not find the optimal values.
The video demonstration has been uploaded to Youtube and the link is the following:
https://www.youtube.com/watch?v=d497UY59Uok
The source code also has been uploaded to Github for pulic use. Link to the repository:
https://github.com/abbosjon-kudratov/line_detection_opencv