import cv2 #import libraries for opencv
import numpy as np # np is a name for numpy
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] #get the height and width of the image
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
# Creating VideoCapture object which Reads the video
cap = cv2.VideoCapture("Lanevd.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()