In this cell we detect lane lines by color and region.
In [19]:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
# Read in the image and print out some stats
# Note: in the previous example we were reading a .jpg
# Here we read a .png and convert to 0,255 bytescale
image = mpimg.imread('images/lane-lines-test.jpg')
# Grab the x and y size and make a copy of the image
ysize = image.shape[0]
xsize = image.shape[1]
color_select = np.copy(image)
line_image = np.copy(image)
# print(image.shape)
# Define color selection criteria
# MODIFY THESE VARIABLES TO MAKE YOUR COLOR SELECTION
thresh_num = 200
red_threshold, green_threshold, blue_threshold = thresh_num, thresh_num, thresh_num
rgb_threshold = [red_threshold, green_threshold, blue_threshold]
# Define the vertices of a triangular mask.
# Keep in mind the origin (x=0, y=0) is in the upper left
# MODIFY THESE VALUES TO ISOLATE THE REGION
# WHERE THE LANE LINES ARE IN THE IMAGE
left_bottom = [0, ysize]
right_bottom = [xsize, ysize]
apex = [xsize//2, ysize//2]
# Perform a linear fit (y=Ax+B) to each of the three sides of the triangle
# np.polyfit returns the coefficients [A, B] of the fit
fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)
# print(fit_left)
# print(fit_right)
# print(fit_bottom)
# Mask pixels below the threshold
color_thresholds = (image[:,:,0] < rgb_threshold[0]) | \
(image[:,:,1] < rgb_threshold[1]) | \
(image[:,:,2] < rgb_threshold[2])
# print(color_thresholds)
# Find the region inside the lines
# This gets a 2D array of the X-indices and Y-indices of the same size as our image
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & \
(YY > (XX*fit_right[0] + fit_right[1])) & \
(YY < (XX*fit_bottom[0] + fit_bottom[1]))
# print(region_thresholds)
# Mask color and region selection
# If the color_select image doesn't pass the color threshold or is NOT in the region threshold, black out
# This leaves only pixels in the region of white-ish color
color_select[color_thresholds | ~region_thresholds] = [0, 0, 0]
# Color pixels red where both color and region selections met
line_image[~color_thresholds & region_thresholds] = [255, 0, 0]
# Display the image and show region and color selections
x = [left_bottom[0], right_bottom[0], apex[0], left_bottom[0]]
y = [left_bottom[1], right_bottom[1], apex[1], left_bottom[1]]
plt.plot(x, y, 'b--', lw=4)
plt.imshow(image)
plt.imshow(color_select)
plt.imshow(line_image)
im_dir = "./images/test/"
mpimg.imsave("{0}image.jpg".format(im_dir), image)
mpimg.imsave("{0}color-select.jpg".format(im_dir), color_select)
mpimg.imsave("{0}line_image.jpg".format(im_dir), line_image)
In this cell we apply gaussian smoothing.
In [1]:
# Do all the relevant imports
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2
# Read in the image and convert to grayscale
# Note: in the previous example we were reading a .jpg
# Here we read a .png and convert to 0,255 bytescale
image = mpimg.imread('./images/exit-ramp.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
# Define a kernel size for Gaussian smoothing / blurring
kernel_size = 3 # Must be an odd number (3, 5, 7...)
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
# Define our parameters for Canny and run it
low_threshold = 256//4
high_threshold = 3*256//4
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
# Display the image
# plt.imshow(blur_gray, cmap='Greys_r')
im_dir = "./images/test/"
mpimg.imsave("{0}edges.jpg".format(im_dir), edges)
In the cell below we build on the result from our previous cell by using a Hough transform to detect lane lines out of Canny-edge-detected image of the exit-ramp.
In [75]:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2
# Read in and grayscale the image
image = mpimg.imread('./images/exit-ramp.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
# Define a kernel size and apply Gaussian smoothing
kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)
# Define our parameters for Canny and apply
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
# Next we'll create a masked edges image using cv2.fillPoly()
mask = np.zeros_like(edges)
ysize, xsize = image.shape[0], image.shape[1]
yheight = ysize//2 # bottom half of the image
xmid = xsize//2
# xtoplength = xsize//30
# xtopside = xtoplength//2
# This time we are defining a four sided polygon to mask
vertices = np.array([[(xmid, yheight), (0, ysize), (xsize, ysize)]], dtype=np.int32)
cv2.fillPoly(mask, vertices, 255)
masked_edges = cv2.bitwise_and(edges, mask) # This leaves us with edges only inside our polygon
# im_dir = './images/test/'
# mpimg.imsave('{0}edges.png'.format(im_dir), edges, cmap='gray')
# mpimg.imsave('{0}masked_edges.png'.format(im_dir), masked_edges, cmap='gray')
# Define the Hough transform parameters
# Make a blank the same size as our image to draw on
rho = 1 # distance resolution in pixels of the Hough grid
theta = np.pi/180 # angular resolution in radians of the Hough grid
min_line_length = xsize//8 #minimum number of pixels making up a line
max_line_gap = min_line_length//8 # maximum gap in pixels between connectable line segments
threshold = min_line_length//8 # minimum number of votes (intersections in Hough grid cell)
# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)
# Iterate over the output "lines" and draw lines on a blank image
line_image = np.copy(image)*0 # creating a blank to draw lines on
line_thickness = 5
line_color = (255, 0, 0)
for line in lines:
for x1,y1,x2,y2 in line:
cv2.line(line_image, (x1,y1), (x2,y2), line_color, line_thickness)
# Draw the lines on the edge image
color_edges = np.dstack((edges, edges, edges)) # Create a "color" binary image to combine with line image
lines_edges = cv2.addWeighted(color_edges, .8, line_image, 1, 0)
# plt.imshow(lines_edges)
im_dir = './images/test/'
mpimg.imsave('{0}lines_edges.png'.format(im_dir), lines_edges)
In [ ]: