# Project 4
### Task
1. Perform a lane detection operation for the given video by implementing Hough transform by extracting individual frames from the images. The video can be seen attached below.
2. Write a detailed report on the process involved and the nature of the output you obtain.
3. The output video for this project must have the lane lines highlighted on the original video.
##### Hint: Use cv2.VideoCapture for reading the video and cv2.VideoWriter to generate the output video.
###### Deliverables:
1. The output video, which has the lane lines, highlighted.
2. Detailed report on the codes, logic and explanation.
#########################################################################################
import cv2 # cv2 is the importing for Opencv
# Opencv is a library of Python bindings designed to solve computer vision problems
import numpy as np # np is an alias for numpy
# general-purpose array-processing package.
# It provides a high-performance multidimensional array object, and tools for working with these arrays
def gray_image(image):
# Convert image to grayscale
return cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
def gaussian_smoothing(image,kernel_dim = (5,5)):
# 5x5 gaussian blur to reduce noise
gaussian_smooth_image = cv2.GaussianBlur(image,kernel_dim,0)
return gaussian_smooth_image
def canny_EdgeDetector(image,lower_Th=50,upper_Th=150):
# Canny edge detector with lower Threshold of 50 and upper Threshold of 150
return cv2.Canny(image,lower_Th,upper_Th)
def ROI_mask(image):
# Region of interest(ROI) mask covers mainly only the lane lines
height = image.shape[0]
width = image.shape[1]
# A triangular polygon to segment the lane area and discarded other
# irrelevant parts in the image Defined by three (x,y) coordinates
polygons = np.array([[(0,height),(round(width/2),round(height/2)),(1000,height)]])
mask = np.zeros_like(image)
cv2.fillPoly(mask,polygons,255) # 255 is the mask color
# Bitwise AND between image and mask image
masked_image = cv2.bitwise_and(image,mask)
return masked_image
def get_coordinates(image,params):
try:
slope,intercept = params
except TypeError:
slope,intercept = 0.001,0
if slope < 0:
y1 = image.shape[0]
y2 = int(y1*(3/5))
x1 = np.clip(int(((y1-intercept)/slope)),50,image.shape[1])
x2 = int((y2-intercept)/slope)
else:
y1 = image.shape[0]
y2 = int(y1*(3/5)) # Setting y2 at 3/5th from y1
x1 = int((y1-intercept)/slope*0.82) # Derived from y = mx+c
x2 = int((y2-intercept)/slope)
return np.array([x1,y1,x2,y2])
def avg_lines(image,lines):
# Returns averaged lines on left and right sides of the image
left = []
right = []
for line in lines:
x1,y1,x2,y2 = line.reshape(4)
# Fit polynomial, find intercept and slope
params = np.polyfit((x1,x2),(y1,y2),1)
slope = params[0]
y_intercept = params[1]
if slope<0:
left.append((slope,y_intercept)) # Negative slope = left lane
else:
right.append((slope,y_intercept)) # Positive slope = right lane
left_avg = np.average(left,axis=0)
right_avg = np.average(right,axis=0)
# Finding x1,y1,x2,y2 coordinates for left and right lines
left_line = get_coordinates(image,left_avg)
right_line = get_coordinates(image,right_avg)
return np.array([left_line,right_line])
def draw_lines(image, lines,thickness):
line_image = np.zeros_like(image)
color = [0,0,255] # Red color
if lines is not None:
for line in lines:
line = line.astype(np.int32)
x1,y1,x2,y2 = line.reshape(4)
cv2.line(line_image,(x1,y1),(x2,y2),color,thickness)
# Merging the original image with drawn lines
combined_image = cv2.addWeighted(image,0.8,line_image,1.0,0.0)
return combined_image
################################## MAIN FUNCTION ##################################
# Creating VideoCapture object which Reads the video
cap = cv2.VideoCapture("Lane_video.mp4")
# Check if video is opened previously or not
if (cap.isOpened()== False):
print("Error opening video file")
# Set resolutions
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
size = (frame_width,frame_height)
# Creating VideoWriter object which create frame of defined resolution
# and the The output is stored in 'LaneDetection_Out.avi' file
output_vid = cv2.VideoWriter('LaneDetection_Out.avi',cv2.VideoWriter_fourcc(*'MJPG'),10, size)
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
grayImage = gray_image(frame)
filtered_image = gaussian_smoothing(grayImage)
edge_image = canny_EdgeDetector(filtered_image)
cropped_image = ROI_mask(edge_image)
lines = cv2.HoughLinesP(cropped_image,rho = 2,theta = 1*np.pi/180,threshold = 100,minLineLength = 40,maxLineGap = 25)
averaged_lines = avg_lines(frame, lines)
combined_image = draw_lines(frame,averaged_lines,10)
# Wirting the frame into the file 'LaneDetection_Out.avi'
output_vid.write(combined_image)
# Dsiplaying the frame
cv2.imshow('LaneDetection', combined_image)
# Press Q on keyboard to stop the process
if cv2.waitKey(25) & 0xFF == ord('q'):
break
# Break the loop
else:
break
# Release Video capture and Video writ objects
cap.release()
output_vid.release()
# Closes all the frames
cv2.destroyAllWindows()
### PFA of Output video