def save_found_lanes(): for fname in data.get_test_paths(): img = cv2.imread(fname) undist = cc.undistort(img, mtx, dist) threshold_binary = th.combine(undist) t = pt.Transformer( (threshold_binary.shape[1], threshold_binary.shape[0])) threshold_warp = t.warp(threshold_binary) finder = lf.LaneFinder() finder.set_new_frame(threshold_warp) finder.find_base(False) # result0 = finder.find_base() # cv2.imwrite(output_dir + '/result0_' + os.path.basename(fname), result0) result1 = finder.find_step1() cv2.imwrite(output_dir + '/result1_' + os.path.basename(fname), result1) result2 = finder.find_step2() cv2.imwrite(output_dir + '/result2_' + os.path.basename(fname), result2) lane_layer = np.zeros_like(result1) finder.draw_layer(lane_layer) result3 = cv2.addWeighted(result1, 1, lane_layer, 0.3, 0) cv2.imwrite(output_dir + '/result3_' + os.path.basename(fname), result3) result4 = map_lane(t, finder, undist) cv2.imwrite(output_dir + '/result4_' + os.path.basename(fname), result4)
def find_lines(img): img = undistort(img, mtx, dist) gray = compute_binary_image(img) warped, M = perspective_projection(gray) Minv = np.linalg.inv(M) result = lines.find_lines(img, warped, Minv) return result
def pipline(frame): global line_left, line_right, counter undistorted = undistort(frame, mtx, dist, verbose=False) binary_image = get_binary_image(undistorted, ksize=3, verbose=False) warped, M, Minv = perspective(binary_image, verbose=False) if counter > 0 and line_left.detected and line_right.detected: line_right, line_left, out_img = line_search_previous(warped, line_left, line_right, verbose=False) else: line_left, line_right, out_img = sliding_window_search(warped, line_left, line_right, verbose=False) draw = project_on_to_original_image(undistorted, warped, Minv, line_left, line_right, verbose=False) # add curvature R_left, R_right, R_mean = curvature(line_left, line_right, draw) cv2.putText(draw, 'Radius of Curvature: {:.02f}(m)'.format(R_mean), (100, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2) # add position offset position_offset = vehicle_position(line_left, line_right, draw) cv2.putText( draw, 'Vehicle position offset from center: {:.02f}(m)'.format( position_offset), (100, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 255, 255), 2) counter += 1 return draw
def save_undistorted(mtx, dist): paths = np.append(data.get_calibration_paths(), data.get_test_paths()) for fname in paths: img = cv2.imread(fname) dst = cc.undistort(img, mtx, dist) outname = output_dir + '/undistorted_' + os.path.basename(fname) cv2.imwrite(outname, dst) print("undistorted : {}".format(outname))
def process_image(img): undistorted = undistort(img) thresholded = binary_threshold(undistorted) transformed = perspective_transform(thresholded) left_fit, right_fit, leftx_base, rightx_base, out_img = hist_poly_fit(transformed) processed_image = draw_lanes(img, left_fit, right_fit, out_img) draw_text(processed_image, left_fit, right_fit, leftx_base, rightx_base) return processed_image
def save_threshold(): for fname in data.get_test_paths(): img = cv2.imread(fname) undist = cc.undistort(img, mtx, dist) gradx_binary = th.abs_sobel_thresh(undist, orient='x', thresh=th.GRADX_THRESH) cv2.imwrite(output_dir + '/threshold_gradx_' + os.path.basename(fname), th.bin2gray(gradx_binary)) grady_binary = th.abs_sobel_thresh(undist, orient='y', thresh=th.GRADY_THRESH) cv2.imwrite(output_dir + '/threshold_grady_' + os.path.basename(fname), th.bin2gray(grady_binary)) gradxy_binary = np.zeros_like(gradx_binary) gradxy_binary[(gradx_binary == 1) & (grady_binary == 1)] = 1 cv2.imwrite( output_dir + '/threshold_gradxy_' + os.path.basename(fname), th.bin2gray(gradxy_binary)) mag_binary = th.mag_thresh(undist, sobel_kernel=th.MAG_KERNEL, thresh=th.MAG_THRESH) cv2.imwrite(output_dir + '/threshold_mag_' + os.path.basename(fname), th.bin2gray(mag_binary)) dir_binary = th.dir_threshold(undist, sobel_kernel=th.DIR_KERNEL, thresh=th.DIR_THRESH) cv2.imwrite(output_dir + '/threshold_dir_' + os.path.basename(fname), th.bin2gray(dir_binary)) md_binary = np.zeros_like(mag_binary) md_binary[(mag_binary == 1) & (dir_binary == 1)] = 1 cv2.imwrite( output_dir + '/threshold_magdir_' + os.path.basename(fname), th.bin2gray(md_binary)) hls_binary1 = th.hls_select(undist, l_thresh=th.HLS_L_THRESH1, s_thresh=th.HLS_S_THRESH1) cv2.imwrite(output_dir + '/threshold_hls_s_' + os.path.basename(fname), th.bin2gray(hls_binary1)) hls_binary2 = th.hls_select(undist, h_thresh=th.HLS_H_THRESH2, s_thresh=th.HLS_S_THRESH2) cv2.imwrite( output_dir + '/threshold_hls_s2_' + os.path.basename(fname), th.bin2gray(hls_binary2)) combined_binary = th.combine(undist) cv2.imwrite( output_dir + '/threshold_combined_' + os.path.basename(fname), th.bin2gray(combined_binary))
def save_threshold(): for fname in test_paths: img = cv2.imread(fname) undist = cc.undistort(img, mtx, dist) cv2.imwrite(output_dir + '/undist_' + os.path.basename(fname), undist) for s in range(0, 150, 10): gradx_binary = th.abs_sobel_thresh(undist, orient='x', thresh=(s, s + 100)) cv2.imwrite( output_dir + "/threshold_gradx_{}_".format(s) + os.path.basename(fname), mask(undist, gradx_binary)) for s in range(0, 200, 10): grady_binary = th.abs_sobel_thresh(undist, orient='y', thresh=(s, s + 50)) cv2.imwrite( output_dir + "/threshold_grady_{}_".format(s) + os.path.basename(fname), mask(undist, grady_binary)) for s in range(0, 180, 10): mag_binary = th.mag_thresh(undist, sobel_kernel=13, thresh=(s, s + 70)) cv2.imwrite( output_dir + "/threshold_mag_{}_".format(s) + os.path.basename(fname), mask(undist, mag_binary)) for s in np.arange(0.0, 2.0, 0.1): dir_binary = th.dir_threshold(undist, sobel_kernel=17, thresh=(s, s + 0.6)) cv2.imwrite( output_dir + "/threshold_dir_{:.2f}_".format(s) + os.path.basename(fname), mask(undist, dir_binary)) for s in range(0, 200, 10): hls_binary = th.hls_select(undist, s_thresh=(s, s + 55)) cv2.imwrite( output_dir + "/threshold_hls_hs1_{}_".format(s) + os.path.basename(fname), mask(undist, hls_binary)) for s in range(0, 100, 10): hls_binary = th.hls_select(undist, s_thresh=(s, s + 60)) cv2.imwrite( output_dir + "/threshold_hls_hs2_{}_".format(s) + os.path.basename(fname), mask_r(undist, hls_binary)) combined_binary = th.combine(undist) cv2.imwrite( output_dir + '/threshold_combined_' + os.path.basename(fname), mask(undist, combined_binary))
def get_perspective_transform(): """ Calculate the perspective transorm matrix to convert camera images to 'birds-eye view' and save this matrix to the file 'perspective_transform.p' """ img = mpimg.imread("test_images/straight_lines1.jpg") img = undistort(img) img_size = (img.shape[1], img.shape[0]) # Specify source points to use in perspective transform src = np.float32([ [195, 720], # Bottom left [1120, 720], # Bottom right [687, 450], # Top right [594, 450] ] # Top left ) x_offset_l = 200 x_offset_r = 300 y_offset = 0 # Specify desitnation points to use in perspective transform dst = np.float32([ [x_offset_l, img_size[1] - y_offset], # Bottom Left [img_size[0] - x_offset_r, img_size[1] - y_offset], # Bottom Right [img_size[0] - x_offset_r, y_offset], # Top Right [x_offset_l, y_offset] # Top Left ]) # Save the perspective transform matrix for later use M = cv2.getPerspectiveTransform(src, dst) pickle.dump(M, open("perspective_transform.p", 'wb')) if __name__ == '__main__': # Plot the original and perspective-transformed images, along with points # used to define a rectangle warped = cv2.warpPerspective(img, M, img_size, flags=cv2.INTER_LINEAR) f, (ax1, ax2) = plt.subplots(1, 2, figsize=(24, 9)) f.tight_layout() ax1.imshow(img) x_cords = np.hstack((src[:, 0], src[0, 0])) y_cords = np.hstack((src[:, 1], src[0, 1])) ax1.plot(x_cords, y_cords, 'g-', linewidth=3) ax1.set_title('Original Image', fontsize=30) ax2.imshow(warped) x_cords = np.hstack((dst[:, 0], dst[0, 0])) y_cords = np.hstack((dst[:, 1], dst[0, 1])) ax2.plot(x_cords, y_cords, 'g-', linewidth=3) ax2.set_title('Perspective Transform', fontsize=30) plt.savefig("output_images/perspective_example.jpg", bbox_inches='tight') plt.show()
def process_pipeline(frame, keep_state=True): """ Apply whole lane detection pipeline to an input color frame. :param frame: input color frame :param keep_state: if True, lane-line state is conserved (this permits to average results) :return: output blend with detected lane overlaid """ global line_lt, line_rt, processed_frames ret, mtx, dist, rvecs, tvecs = cam_calibration(image_dir="../camera_cal/", nx=9, ny=6) # undistort the image using coefficients found in calibration img_undistorted = undistort(frame, mtx, dist, verbose=False) # binarize the frame s.t. lane lines are highlighted as much as possible img_binary = final_mask_combination(img_undistorted, verbose=False) # compute perspective transform to obtain bird's eye view M, Minv, img_birdeye = perspect_trans(img_binary, verbose=False) # fit 2-degree polynomial curve onto lane lines found if processed_frames > 0 and keep_state and line_lt.detected and line_rt.detected: line_lt, line_rt, img_fit = get_fits_by_previous_fits(img_birdeye, line_lt, line_rt, verbose=False) else: line_lt, line_rt, img_fit = get_fits_by_sliding_windows(img_birdeye, line_lt, line_rt, n_windows=9, verbose=False) # compute offset in meter from center of the lane offset_meter = compute_offset_from_center(line_lt, line_rt, frame_width=frame.shape[1]) # draw the surface enclosed by lane lines back onto the original frame blend_on_road = draw_back_onto_the_road(img_undistorted, Minv, line_lt, line_rt, keep_state) # stitch on the top of final output images from different steps of the pipeline blend_output = prepare_out_blend_frame(blend_on_road, img_binary, img_birdeye, img_fit, line_lt, line_rt, offset_meter) processed_frames += 1 return blend_output
def pipeline(img): undistored = my_cc.undistort(img, objpoints, imgpoints) sobelx = abs_sobel(undistored, 'x', (50, 255)) sobely = abs_sobel(undistored, 'y', (25, 255)) color_binary = color_select(undistored, sthresh=(100, 255), vtresh=(50, 255)) combined = np.zeros_like(sobelx) combined[((sobelx == 1) & (sobely == 1) | (color_binary == 1))] = 1 transformed, M, Minv = transform(combined) return transformed, M, Minv
def processFrame(img): objpoints, imgpoints = calibrate(9, 6) undist = undistort(objpoints, imgpoints, img) sxybinary = convertBinary(undist) masked_sxybinary = mask(sxybinary) binary_warped, Minv = warp(masked_sxybinary) left_fit, right_fit, left_fitx, right_fitx, ploty, leftx, lefty, rightx, righty = visualizeLanes( binary_warped) left_radius, right_radius = curvature(leftx, lefty, rightx, righty) distance = lanePosition(left_fitx, right_fitx, undist) img = addData(undist, left_radius, right_radius, distance) return drawLane(img, left_fit, right_fit, left_fitx, right_fitx, ploty, binary_warped, Minv)
def pipeline(frame): # Correcting for Distortion undist_img = undistort(frame, mtx, dist) # resize video undist_img = cv2.resize(undist_img, None, fx=1 / 2, fy=1 / 2, interpolation=cv2.INTER_AREA) rows, cols = undist_img.shape[:2] combined_gradient = get_combined_gradients(undist_img, th_sobelx, th_sobely, th_mag, th_dir) combined_hls = get_combined_hls(undist_img, th_h, th_l, th_s) combined_result = combine_grad_hls(combined_gradient, combined_hls) c_rows, c_cols = combined_result.shape[:2] s_LTop2, s_RTop2 = [c_cols / 2 - 24, 5], [c_cols / 2 + 24, 5] s_LBot2, s_RBot2 = [110, c_rows], [c_cols - 110, c_rows] src = np.float32([s_LBot2, s_LTop2, s_RTop2, s_RBot2]) dst = np.float32([(170, 720), (170, 0), (550, 0), (550, 720)]) warp_img, M, Minv = get_perspective_transform(combined_result, src, dst, (720, 720)) searching_img = get_lane_lines_img(warp_img, left_line, right_line) w_comb_result, w_color_result = illustrate_driving_lane(searching_img, left_line, right_line) # Drawing the lines back down onto the road color_result = cv2.warpPerspective(w_color_result, Minv, (c_cols, c_rows)) lane_color = np.zeros_like(undist_img) lane_color[220:rows - 12, 0:cols] = color_result # Combine the result with the original image result = cv2.addWeighted(undist_img, 1, lane_color, 0.3, 0) info_panel, birdeye_view_panel = np.zeros_like(result), np.zeros_like(result) info_panel[5:110, 5:325] = (255, 255, 255) birdeye_view_panel[5:110, cols-111:cols-6] = (255, 255, 255) info_panel = cv2.addWeighted(result, 1, info_panel, 0.2, 0) birdeye_view_panel = cv2.addWeighted(info_panel, 1, birdeye_view_panel, 0.2, 0) road_map = illustrate_driving_lane_with_topdownview(w_color_result, left_line, right_line) birdeye_view_panel[10:105, cols-106:cols-11] = road_map birdeye_view_panel = illustrate_info_panel(birdeye_view_panel, left_line, right_line) return birdeye_view_panel
def save_perspective_transform(): for fname in data.get_test_paths(): img = cv2.imread(fname) undist = cc.undistort(img, mtx, dist) t = pt.Transformer((undist.shape[1], undist.shape[0])) perspective_rect = draw_perspective_transform_rect(t, undist) cv2.imwrite( output_dir + '/perspective_transform_rect_' + os.path.basename(fname), perspective_rect) warp = t.warp(undist) cv2.imwrite( output_dir + '/perspective_transform_warp_' + os.path.basename(fname), warp) threshold_binary = th.combine(undist) threshold_warp = t.warp(threshold_binary) cv2.imwrite( output_dir + '/perspective_transform_threshold_warp_' + os.path.basename(fname), th.bin2gray(threshold_warp))
def validate_perspective_transform(inputdir, outputdir): fnames = load_images(inputdir) for fname in fnames: image = cv2.imread(fname) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = undistort(image) basename = os.path.basename(fname) savename = os.path.join(outputdir, basename) src = np.copy(image) src = draw_src_rectangle(src) save_image(src, savename, 'persp_src') dst = persp_trans_forward(image) dst = draw_dst_rectangle(dst) save_image(dst, savename, 'persp_dst') basename = os.path.basename(fname) head, ext = os.path.splitext(basename) savename = os.path.join('output_images', head + '_perspective' + ext) w = image.shape[1] h = image.shape[0] dpi = 96 fig = plt.figure(figsize=(w / dpi, h / dpi)) plt.suptitle(fname) plt.subplot(121) plt.imshow(src) plt.title('Undistort Image') plt.subplot(122) plt.imshow(dst) plt.title('Perspective Transform') #plt.xlabel(fname) fig.tight_layout() fig.savefig(savename, dpi=dpi) plt.close()
def draw_lanes(img, left_fit, right_fit, lanes_img): M = pickle.load(open("perspective_transform.p", 'rb')) Minv = np.linalg.inv(M) undistorted = undistort(img) thresholded = binary_threshold(undistorted) transformed = perspective_transform(thresholded) ploty = np.linspace(0, transformed.shape[0] - 1, transformed.shape[0]) left_fitx = left_fit[0] * ploty ** 2 + left_fit[1] * ploty + left_fit[2] right_fitx = right_fit[0] * ploty ** 2 + right_fit[1] * ploty + right_fit[2] # Create an image to draw the lines on warp_zero = np.zeros_like(transformed).astype(np.uint8) color_warp = np.dstack((warp_zero, warp_zero, warp_zero)) # Recast the x and y points into usable format for cv2.fillPoly() pts_left = np.array([np.transpose(np.vstack([left_fitx, ploty]))]) pts_right = np.array([np.flipud(np.transpose(np.vstack([right_fitx, ploty])))]) pts = np.hstack((pts_left, pts_right)) # Draw the lane onto the warped blank image cv2.fillPoly(color_warp, np.int_([pts]), (0, 255, 0)) # Warp the blank back to original image space using inverse perspective matrix (Minv) unwarped = cv2.warpPerspective(color_warp, Minv, (transformed.shape[1], transformed.shape[0])) # Combine the result with the original image result = cv2.addWeighted(undistorted, 1, unwarped, 0.3, 0) lanes_img_unwarped = cv2.warpPerspective(lanes_img, Minv, (transformed.shape[1], transformed.shape[0])) result = cv2.addWeighted(lanes_img_unwarped, 1, result, 0.8, 0) return result
def pipeline(img): img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) undist = cc.undistort(img, mtx, dist) threshold_binary = th.combine(undist) t = pt.Transformer((threshold_binary.shape[1], threshold_binary.shape[0])) threshold_warp = t.warp(threshold_binary) finder.set_new_frame(threshold_warp) finder.find_base(False) finder.find_step1(False) finder.find_step2(False) lane_layer_warp = np.zeros_like(undist) finder.draw_layer(lane_layer_warp) lane_layer = t.unwarp(lane_layer_warp) result = cv2.addWeighted(undist, 1, lane_layer, 0.3, 0) finder.draw_text(result) result = cv2.cvtColor(result, cv2.COLOR_BGR2RGB) return result
import camera_calibration as my_calib import cv2 objpoints, imgpoints = my_calib.camera_calibration() img_name = 'test_images/straight_lines1.jpg' img = cv2.imread(img_name) cv2.imshow('Distorted', img) cv2.waitKey(0) cv2.imshow('Undistorted', my_calib.undistort(img, objpoints, imgpoints)) cv2.waitKey(0)
if __name__ == '__main__': # For debugging Frame by Frame, using cv2.imshow() if input_type == 'frame_by_frame': cap = cv2.VideoCapture(input_name) frame_num = -1 while (cap.isOpened()): _, frame = cap.read() frame_num += 1 # increment frame_num, used for naming saved images # Correcting for Distortion undist_img = undistort(frame, mtx, dist) # resize video undist_img = cv2.resize(undist_img, None, fx=1 / 2, fy=1 / 2, interpolation=cv2.INTER_AREA) rows, cols = undist_img.shape[:2] combined_gradient = get_combined_gradients(undist_img, th_sobelx, th_sobely, th_mag, th_dir) combined_hls = get_combined_hls(undist_img, th_h, th_l, th_s) combined_result = combine_grad_hls(combined_gradient, combined_hls) c_rows, c_cols = combined_result.shape[:2] s_LTop2, s_RTop2 = [c_cols / 2 - 24, 5], [c_cols / 2 + 24, 5] s_LBot2, s_RBot2 = [110, c_rows], [c_cols - 110, c_rows] src = np.float32([s_LBot2, s_LTop2, s_RTop2, s_RBot2])
out_img, left_fit, right_fit, ploty, left_fitx, right_fitx = fit_polynomial(warped) plt.subplot(2,2,3) plt.plot(left_fitx, ploty, color='yellow') plt.plot(right_fitx, ploty, color='yellow') plt.imshow(out_img) left_curverad, right_curverad = measure_curvature_pixels(ploty, left_fit, right_fit) plt.subplot(2,2,4) result = map_lane_lines_to_original(img, warped, left_fitx, right_fitx, ploty, Minv) plt.imshow(result) """ plt.figure(figsize=(10,10)) img = rgb(cv2.imread(f)) img = undistort(img, mtx, dist) gray = compute_binary_image(img) warped, M = perspective_projection(gray) Minv = np.linalg.inv(M) result = line.find_lines(img, warped, Minv) #print(line.left_curverad, line.right_curverad) #print(line.distance_to_center(img)) plt.title(f"Distance to Center= {line.distance_to_center(img):.3f}, Left curverad = {line.left_curverad:.1f}, Right Curverad={line.right_curverad:.1f}") plt.imshow( result) plt.savefig("output_images/lane_finding_output.jpg") #plt.show()
gamma=0.) return blend_onto_road if __name__ == '__main__': line_lt, line_rt = Line(buffer_len=10), Line(buffer_len=10) ret, mtx, dist, rvecs, tvecs = cam_calibration(image_dir="../camera_cal/", nx=9, ny=6) # show result on test images for test_img in glob.glob('test_images/*.jpg'): img = cv2.imread(test_img) img_undistorted = undistort(img, mtx, dist, verbose=False) img_binary = final_mask_combination(img_undistorted, verbose=False) M, Minv, img_birdeye = perspect_trans(img_binary, verbose=False) line_lt, line_rt, img_out = get_fits_by_sliding_windows(img_birdeye, line_lt, line_rt, n_windows=7, verbose=True) print("done")
memory = 0.5 * np.ones(central_complex.N_CPU4) # initialize camera frame_num = 0 cap = cv2.VideoCapture(sys.argv[1]) #cap.set(cv2.CAP_PROP_FRAME_WIDTH,200) #cap.set(cv2.CAP_PROP_FRAME_HEIGHT,130) #fw = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) #fh = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) for i in range(200): ret, frame1 = cap.read() # Skip frames frame_num += 1 #frame1 = cv2.resize(frame1, (0,0), fx=0.25, fy=0.25) temp = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) prvs = camera_calibration.undistort(temp, 1.0) (fh, fw) = prvs.shape print("Frame size: {0}*{1}".format(fw, fh)) # visulize computed speed plt.ion() fig, (ax1, ax2) = plt.subplots(2, sharey=True) ax1.set(title='speed', ylabel='left') ax2.set(xlabel='time (s)', ylabel='right') x_axis = np.linspace(0, 100, num=100, endpoint=False) speed_left = np.zeros(100) speed_right = np.zeros(100) plt.show() # filter for speed retrieval row = np.linspace(0, fw, num=fw, endpoint=False)
# Recast the x and y points into usable format for cv2.fillPoly() pts_left = np.array([np.transpose(np.vstack([left_fitx, ploty]))]) pts_right = np.array([np.flipud(np.transpose(np.vstack([right_fitx, ploty])))]) pts = np.hstack((pts_left, pts_right)) # Draw the lane onto the warped blank image cv2.fillPoly(color_warp, np.int_([pts]), (0,255, 0)) # Warp the blank back to original image space using inverse perspective matrix (Minv) newwarp = cv2.warpPerspective(color_warp, Minv, (w, h)) # Combine the result with the original image result = cv2.addWeighted(undist, 1, newwarp, 0.3, 0) if verbose == True: plt.imshow(result) plt.title('Original (undistorted) image with lane area drawn') plt.show() return result if __name__ == '__main__': line_left = Line(buffer_len=10) line_right = Line(buffer_len=10) cali_path = '../CarND-Advanced-Lane-Lines/camera_cal' pickle_file = '../CarND-Advanced-Lane-Lines/pick' img = mpimg.imread('../CarND-Advanced-Lane-Lines/test_images/test2.jpg') ret, mtx, dist, rvecs, tvecs = calibration(img, pickle_file, cali_path, verbose=False) dst = undistort(img, mtx, dist, verbose=False) binary_image = get_binary_image(dst, ksize=3, verbose=False) warped, M, Minv = perspective(binary_image, verbose=False) line_left, line_right, img_out = sliding_window_search(warped, line_left, line_right, verbose=False) result = project_on_to_original_image(dst, warped, Minv, line_left, line_right, verbose=True)
out_img[nonzeroy[left_lane_inds], nonzerox[left_lane_inds]] = [255, 0, 0] # red out_img[nonzeroy[right_lane_inds], nonzerox[right_lane_inds]] = [0, 0, 225] # blue return left_fit, right_fit, leftx_base, rightx_base, out_img if __name__ == "__main__": # See what is happening to the test images (useful in debugging) image_urls = glob.glob('test_images/*.jpg') for url in image_urls: img = mpimg.imread(url) undistorted = undistort(img) thresholded = binary_threshold(undistorted) transformed = perspective_transform(thresholded) left_fit, right_fit, leftx_base, rightx_base, out_img = hist_poly_fit( transformed) ploty = np.linspace(0, img.shape[0] - 1, img.shape[0]) left_fitx = left_fit[0] * ploty**2 + left_fit[1] * ploty + left_fit[2] right_fitx = right_fit[0] * ploty**2 + right_fit[ 1] * ploty + right_fit[2] plt.imshow(out_img) plt.plot(left_fitx, ploty, color='yellow') plt.plot(right_fitx, ploty, color='yellow') plt.xlim(0, 1280) plt.ylim(720, 0)