Challenge

Project 4

# 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 
Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.