Lane detection is a crucial task in self-driving cars and other automated driving systems. It helps the vehicle to stay within the lane boundaries and avoid accidents. In this blog, we will explore how to detect lanes using OpenCV and Python. OpenCV (Open Source Computer Vision Library) is a popular computer vision library used for image and video processing. We will use OpenCV to detect and draw lanes on the road.
What is Lane Detection?
Lane detection is the process of identifying the lane boundaries on the road. It is an essential task for autonomous driving systems and driver assistance systems.
These systems use sensors, cameras, and computer vision algorithms to detect the lane markings and determine the vehicle’s position relative to the lane boundaries.
Lane Detection Techniques
There are various techniques used for lane detection. Some of the popular techniques are:
- Edge Detection: Edge detection techniques are used to identify the edges of the lane markings. It involves finding the gradient of the image intensity at each pixel and identifying the locations where the gradient is high. The edges are then connected to form a continuous line.
- Hough Transform: The Hough transform is a popular technique for detecting lines in an image. It works by converting the image into a parameter space, where each line in the image corresponds to a point in the parameter space. The lines in the image can then be detected by finding the peaks in the parameter space.
- Machine Learning: Machine learning techniques are also used for lane detection. These techniques involve training a model on a dataset of images and their corresponding lane markings. The model can then be used to detect lane markings in new images.
Lane Detection using OpenCV and Python
In this section, we will explore how to detect lanes using OpenCV and Python. We will use edge detection and the Hough transform to detect the lanes.
Step 1: Import Libraries
We will start by importing the required libraries. We will use the OpenCV library for image processing and Matplotlib for visualization.
import cv2
import numpy as np
import matplotlib.pyplot as plt
Step 2: Read Image
Next, we will read the image on which we want to detect the lanes. We will use the imread()
function of OpenCV to read the image.
image = cv2.imread('road.jpg')
Step 3: Convert Image to Grayscale
We will convert the color image to grayscale using the cvtColor()
function of OpenCV.
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
Step 4: Apply Gaussian Blur
We will apply Gaussian blur to the grayscale image to reduce the noise using the GaussianBlur()
function of OpenCV.
blur = cv2.GaussianBlur(gray, (5, 5), 0)
Step 5: Detect Edge Using Canny
We will use the Canny edge detection algorithm to detect the edges of the lane markings. We will use the Canny()
function of OpenCV for this.
edges = cv2.Canny(blur, 50, 150)
Step 6: Region of Interest
We will define a region of interest (ROI) in the image where we expect the lane markings to be present. We will mask the rest of the image to focus only on the ROI. We will use the fillPoly()
function of OpenCV to create a mask and the bitwise_and()
function to apply the mask to the image.
mask = np.zeros_like(edges)
Next, we will define the vertices of the ROI polygon. We will use the fillPoly()
function of OpenCV to create a mask and the bitwise_and()
function to apply the mask to the image.
height, width = image.shape[:2]
roi_vertices = [(0, height), (width/2, height/2), (width, height)]
mask_color = 255
cv2.fillPoly(mask, np.array([roi_vertices], dtype=np.int32), mask_color)
masked_edges = cv2.bitwise_and(edges, mask)
Step 7: Hough Transform
We will use the Hough transform to detect the lines in the masked image. We will use the HoughLinesP()
function of OpenCV for this. The function returns a list of lines, where each line is represented by its endpoints.
lines = cv2.HoughLinesP(masked_edges, rho=6, theta=np.pi/60, threshold=160, minLineLength=40, maxLineGap=25)
The rho
parameter specifies the distance resolution of the Hough accumulator in pixels. theta
parameter specifies the angular resolution of the Hough accumulator in radians.
The threshold
parameter specifies the minimum number of votes (intersections) required for a line to be detected.
minLineLength
parameter specifies the minimum length of a line in pixels. The maxLineGap
parameter specifies the maximum gap between two lines to be considered as a single line.
Step 8: Draw Lines on the Image
We will draw the detected lines on the original image using the line()
function of OpenCV.
line_image = np.zeros_like(image)
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(line_image, (x1, y1), (x2, y2), (0, 255, 0), 5)
Step 9: Overlaying the Lines on the Original Image
Finally, we will overlay the detected lines on the original image using the addWeighted()
function of OpenCV.
final_image = cv2.addWeighted(image, 0.8, line_image, 1, 0)
Step 10: Display Result
We will use the imshow()
function of Matplotlib to display the final result.
plt.imshow(final_image)
plt.show()
Here’s the complete source code for Lane Detection in OpenCV Python:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Step 1: Importing Libraries
image = cv2.imread('road.jpg')
# Step 2: Reading the Image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Step 3: Converting to Grayscale
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# Step 4: Gaussian Blur
edges = cv2.Canny(blur, 50, 150)
# Step 5: Canny Edge Detection
height, width = image.shape[:2]
roi_vertices = [(0, height), (width/2, height/2), (width, height)]
mask_color = 255
mask = np.zeros_like(edges)
cv2.fillPoly(mask, np.array([roi_vertices], dtype=np.int32), mask_color)
masked_edges = cv2.bitwise_and(edges, mask)
# Step 6: Region of Interest
lines = cv2.HoughLinesP(masked_edges, rho=6, theta=np.pi/60, threshold=160, minLineLength=40, maxLineGap=25)
# Step 7: Hough Transform
line_image = np.zeros_like(image)
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(line_image, (x1, y1), (x2, y2), (0, 255, 0), 5)
# Step 8: Drawing the Lines
final_image = cv2.addWeighted(image, 0.8, line_image, 1, 0)
# Step 9: Overlaying the Lines on the Original Image
plt.imshow(final_image)
# Step 10: Display Image
plt.show()