Challenge

Project 4

# Python
# Programmer: Mark Omefe
# Date:01/11/2022

# Hough Transform for Lane detection

import cv2
import numpy as np
import matplotlib.pyplot as plt
import math
import warnings

from scipy import spatial
from PIL import Image

warnings.filterwarnings('ignore')


#function to convert BGR image to Gray
def gray_image(image):
    return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

#function to apply Gaussian filter on Gray Image 
def gaussian_filter(image, filter_size, sigma):
    return cv2.GaussianBlur(image, (filter_size, filter_size), sigma)

#function to detect edges using Canny Edge Detector
def canny_edge_detection(image, low_threshold, high_threshold):
    return cv2.Canny(image, low_threshold, high_threshold)

#To find just region of interest in the image
def ROI_masking(image):
    height = image.shape[0]
    width = image.shape[1]
    image =  np.array(image, dtype=np.float32)
    polygon_coords = np.array([(0, height), (0, round(height/1.25)), (round(width/2),round(height/2)),(width, height)])
    mask  = np.zeros((height, width))
    masked_image = cv2.fillPoly(mask, [polygon_coords], 255)
    masked_image = np.array(masked_image, dtype=np.float32)
    return cv2.bitwise_and(image, masked_image)

#To find hough lines using hough transformation
def hough_transformation(reg_of_int_img):
    image = cv2.convertScaleAbs(reg_of_int_img)
    return cv2.HoughLinesP(image, 1, np.pi/180, 50, None, 0, 1000)

#To get the get ordinates of lines on lanes
def get_coordinates(image, parameters):
    slope, intercept = parameters
    if slope<0:
        y1 = image.shape[0]
        y2 = int(y1*(3/5))
        x1 = np.clip(int((y1-intercept)/slope), 0, image.shape[1])
        x2 = int((y2-intercept)/slope)
    else:
        y1 = image.shape[0]
        y2 = int(y1*(3/5))
        x1 = int((y1-intercept)/slope*0.98)
        x2 = int((y2-intercept)/slope)
    return np.array([x1, y1, x2, y2])

#Function to define slope and intercept to find coordinates for left lines and right lines
def average_slope_intercept(image, lines):
    left_lines = []
    right_lines = []

    #following for loop is to get slope and intercept
    for line in lines:
        x1, y1, x2, y2 = line[0][:]
        parameters = np.polyfit((x1,x2), (y1,y2), 1)
        slope = parameters[0]
        intercept = parameters[1]
        if slope < 0:
            left_lines.append((slope, intercept))
        else:
            right_lines.append((slope, intercept))

    #Left Line COordinates
    left_line_coordinates = []
    for line in left_lines:
        if line[0] > -0.1:
            continue
        left_line_coordinates.append(get_coordinates(image, line))

    #Right line coordinates
    right_line_coordinates = []
    for line in right_lines:
        if line[0] < 0.2:
            continue
        right_line_coordinates.append(get_coordinates(image, line))

    # getting left lines and right lines using cosine distance remove the crackline that could be found on the road
    final_left_lines = []
    final_right_lines = []
    cosine_distance = []

    # Condition if both curves have the same slope
    if len(left_line_coordinates) == 0 or len(right_line_coordinates) == 0:
        if len(left_line_coordinates) == 0:
            lines = right_line_coordinates
        else:
            lines = left_line_coordinates

        if len(lines) <= 2:
            return np.array(lines)

        # Calculating the cosine distance between the left line and right line
        for l in lines:
            for m in lines:
                cosine_distance.append(spatial.distance.cosine(l, m))
        cosine_distance = [item for item in cosine_distance if not(math.isnan(item))]
        threshold = np.percentile(cosine_distance,85)
        
# Filter the lines based on threshold and cosine distance with 85 percentile
        for left in lines:
            for right in lines:
                dist = spatial.distance.cosine(left, right)

                if dist > threshold and len(final_left_lines) == 0:
                    final_left_lines.append(list(left))
                    final_right_lines.append(list(right))
                    continue

                if dist > threshold:
                    if list(left) not in final_left_lines and list(left) not in final_right_lines:
                        final_left_lines.append(list(left))
                    if list(right) not in final_right_lines and list(right) not in final_right_lines:
                        final_right_lines.append(list(right))

        # To find the average of the lines
        left_line = np.average(np.array(final_left_lines), axis=0)
        right_line = np.average(np.array(final_right_lines), axis=0)
        return np.array([left_line, right_line])
    
    else:
        # To keep the farthest lines and removing crack lines
        for left in left_line_coordinates:
            for right in right_line_coordinates:
                cosine_distance.append(spatial.distance.cosine(left, right))
        cosine_distance = [item for item in cosine_distance if not(math.isnan(item))]
        threshold = np.percentile(cosine_distance,85)

        # Threshold filtering similar to NVM
        for left in left_line_coordinates:
            for right in right_line_coordinates:
                dist = spatial.distance.cosine(left, right)

                if dist > threshold and len(final_left_lines) == 0:
                    final_left_lines.append(list(left))
                    final_right_lines.append(list(right))
                    continue
                    
                if dist > threshold:
                    if list(left) not in final_left_lines:
                        final_left_lines.append(list(left))
                    if list(right) not in final_right_lines:
                        final_right_lines.append(list(right))

        left_line = np.average(np.array(final_left_lines), axis=0)
        right_line = np.average(np.array(final_right_lines), axis=0)

        return np.array([left_line, right_line])


# Function to draw lines on the lanes for each side of the road
def draw_lane_lines(image, lines, color=[0, 0, 255], thickness=10):
    line_image = np.zeros_like(image)
    for line in lines:
        x1, y1, x2, y2 =line
        if line is not None:
            cv2.line(line_image, (int(x1),int(y1)), (int(x2),int(y2)), color, thickness)
    return cv2.addWeighted(image, 0.8, line_image, 1.0, 1.0)


# Recursive Function that performs lane using all the  above functions on the image and find lanes

def lanes(image):
    #gray image
    gray_images = gray_image(image)

    #Gaussian Filtering or smoothing
    gaussian_filtered_image = gaussian_filter(gray_images, 5, 5)

    #Canny edge detection
    canny_edge_image = canny_edge_detection(gaussian_filtered_image, 50, 150)

    #region of interest
    ROI_image = ROI_masking(canny_edge_image)

    #To get hough lines
    hough_lines = hough_transformation(ROI_image)

    #to get left and right lines
    lines = average_slope_intercept(ROI_image, hough_lines)
    threshold = spatial.distance.cosine(lines[0], lines[1])

    #to draw lanes using above lines
    draw_lanes = draw_lane_lines(image, lines,[0, 0, 255], 10)

    return threshold, draw_lanes


#Applying above functions on Input given Video to detect lanes 

# Reading the input video
video = cv2.VideoCapture('Lane_video.mp4')

# Check for the fps of video
fps = video.get(5)

# Checking for the total number of frames in the video
frame_count = video.get(7)

# Getting the frame size data
frame_width = int(video.get(3))
frame_height = int(video.get(4))
frame_size = (frame_width,frame_height)

# Impressing lane marked images into a video file
output = cv2.VideoWriter('Road Lane Tracking.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 20, frame_size)

# loading of each frame
while(video.isOpened()):
    ret, frame = video.read()
    if ret == True:
        threshold, final_image = lanes(frame)  
        if 0.2 <= threshold <= 0.303:
            output.write(final_image)
            cv2.imshow("Road Lane Tracking",final_image)
            k = cv2.waitKey(50)
            if k == 113:
                break
        else:
            continue
    else:
        break
import cv2
import numpy as np
# Hough Transform for static lane detection image


#function to convert read image 
def read_image(image_path):
    """This function reads any image from a given path"""
    image = cv2.imread(image_path)
    return image

def save_image(image_name_format, image):
    """This function saves any image to a given path"""
    cv2.imwrite(image_name_format, image)
    
#function to convert BGR image to Gray
def gray_scale(image):
    converted_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    return converted_image

#function to apply Gaussian filter on Gray Image
def guassin_filter(image, kernel_dimensions):
    filtered_image = cv2.GaussianBlur(image, kernel_dimensions, 0)
    return filtered_image

#function to detect edges using Canny Edge Detector
def canny_edge_detector(image, lower_threshold, upper_threshold):
    canny_detected_edge = cv2.Canny(image, lower_threshold, upper_threshold)
    return canny_detected_edge


def ROI_polygon(image):
    mask = np.zeros_like(image)
    
    if len(image.shape) > 2:
        channel_count = image.shape[2]
        ignore_mask_color = (255,)*channel_count
    
    else:
        ignore_mask_color = 255
    
    rows = image.shape[0]
    columns = image.shape[1]
    
    bottom_left = [0, rows]
    top_left = [columns*0.5, rows*0.5]
    bottom_right = [columns*0.9, rows*0.95]
    top_right = [columns*0.6, rows*0.6]
    
    vertices = np.array([[bottom_left,top_left,top_right,bottom_right]], dtype=np.int32)
    cv2.fillPoly(mask,vertices,ignore_mask_color)
    masked_image = cv2.bitwise_and(image,mask)
    
    return masked_image

#To find just region of interest in the image
def ROI_masking(image):
    height = image.shape[0]
    width = image.shape[1]
    
    image = np.array(image, dtype=np.float32)
    polygon_coordinates = np.array([(0,height),(round(width/2),round(height/2)),(1000,height)])
    mask = np.zeros((height,width))
    masked_image1 = cv2.fillPoly(mask,[polygon_coordinates],255)
    masked_image2 = np.array(masked_image1,dtype=np.float32)
    masked_image3 = cv2.bitwise_and(image,masked_image2)
    
    return masked_image3

#Function to define slope and intercept to find coordinates for left lines
def average_slope_intercept(image,lines):
    left_lines = []
    right_lines = []
    
    for line in lines:
        parameters = np.polyfit((x1,x2),(y1,y2),1)
        slope = parameters[0]
        y_intercept = parameters[1]
        
        if slope < 0:
            left_lines.append((slope,y_intercept))
            
        else:
            right_lines.append((slope,y_intercept))
            
    #Left Line COordinates
    left_average = np.average(left_lines, axis=0)
    right_average = np.average(right_lines, axis=0)
    
    left_line = get_coordinates(image,left_average)
    right_line = get_coordinates(image,right_average)
    
    return np.array([left_line, right_line])

#To get the get coordinates of lines on lanes
def get_coordinates(image, parameters):
    slope, intercept = parameters
    
    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))
        x1 = int((y1-intercept)/slope*0.82)
        x2 = int((y2-intercept)/slope)
    
    return np.array([x1,y1,x2,y2])


#function to draw lines on lanes either side of the road
def draw_lane_lines(image,lines,color,thickness):
    line_image = np.zeros_like(image)
    
    for line in lines:
        x1,y1,x2,y2 = line
        
        if line is not None:
            cv2.line(line_image,(x1,y1),(x2,y2),color,thickness)
            
    return cv2.addWeighted(image,0.8,line_image,1.0,1.0)


#To find hough lines using hough transformation
def hough_transformation(region_of_interest):
    image = cv2.convertScaleAbs(region_of_interest)
    return cv2.HoughLinesP(image, 1, np.pi/180, 50, None, 0, 1000)
    
    
    
    
dims = (5,5)
l_limit = 50
u_limit = 150
line_color = [0,0,255]
line_thickness = 12

image = read_image('road lane.jpg')
gray_images = gray_scale(image)
cv2.imshow('gray image',gray_images)
cv2.waitKey(0)
save_image('gray_image.jpg', gray_images)

filtered_image = guassin_filter(image=gray_images, kernel_dimensions=dims)
cv2.imshow('filtered image',np.hstack((gray_images,filtered_image)))
cv2.waitKey(0)
save_image('filtered_image.jpg', filtered_image)

canny_edge_image = canny_edge_detector(image, lower_threshold=l_limit, upper_threshold=u_limit)
cv2.imshow('edge image',np.hstack((filtered_image, canny_edge_image)))
cv2.imshow('edge image',canny_edge_image)
cv2.waitKey(0)
save_image('edge_image.jpg', canny_edge_image)

https://drive.google.com/drive/folders/1Fm-iDUVfY8SNuKJThLZV6aJptIwRPfEp?usp=sharing

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.