from PIL import ImageGrab import time import matplotlib.pyplot as plt from scipy.misc import imresize from calibration_utils import calibrate_camera, undistort from binarization_utils import binarize from perspective_utils import birdeye from line_utils import get_fits_by_sliding_windows, draw_back_onto_the_road, Line, get_fits_by_previous_fits import imageio imageio.plugins.ffmpeg.download() from moviepy.editor import VideoFileClip import numpy as np from globals import xm_per_pix, time_window processed_frames = 0 # counter of frames processed (when processing video) line_lt = Line(buffer_len=time_window) # line on the left of the lane line_rt = Line(buffer_len=time_window) # line on the right of the lane def prepare_out_blend_frame(blend_on_road, img_binary, img_birdeye, img_fit, line_lt, line_rt, offset_meter): """ Prepare the final pretty pretty output blend, given all intermediate pipeline images :param blend_on_road: color image of lane blend onto the road :param img_binary: thresholded binary image :param img_birdeye: bird's eye view of the thresholded binary image :param img_fit: bird's eye view with detected lane-lines highlighted :param line_lt: detected left lane-line :param line_rt: detected right lane-line :param offset_meter: offset from the center of the lane
def main(): logging.basicConfig(level=logging.DEBUG) cap = cv2.VideoCapture('footage/7_edit.avi') ''' cap = cv2.VideoCapture(1) cap.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0.25) cap.set(cv2.CAP_PROP_EXPOSURE, 0.01) cap.set(cv2.CAP_PROP_FRAME_WIDTH,1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT,720) ''' DIM = (640, 480) K = np.array([[359.0717640266508, 0.0, 315.08914578097387], [0.0, 358.06497428501837, 240.75242680088732], [0.0, 0.0, 1.0]]) D = np.array([[-0.041705903204711826], [0.3677107787593379], [-1.4047363783373128], [1.578157237454529]]) profile = (DIM, K, D) CC = CameraCalibration(profile) yellow_HSV_th_min = np.array([0, 70, 70]) yellow_HSV_th_max = np.array([50, 255, 255]) line_lt = Line(buffer_len=time_window) # line on the left of the lane line_rt = Line(buffer_len=time_window) # line on the right of the lane processed_frames = 0 ### traffic light detector setup ### ''' red_bound = ([0,0,0], [255,255,360]) green_bound = ([0,0,0], [255,255,360]) color_bounds = {'red':red_bound, 'green':green_bound} reference_images = [] reference_paths = glob('./reference/*.jpg') for path in reference_paths: reference_images.append(cv2.imread(path)) TLD = TrafficLightDetector(reference_images, color_bounds) ''' while cap.isOpened(): ret, frame = cap.read() ### traffic light detection # TODO: replace placeholder values ''' while True: state = TLD.get_state(frame) logging.debug('traffic light state:', str(state)) if state == 'green': comm.write_serial_message('s30') break ''' frame = CC.undistort(frame) ### calibration ### ### crop to ROI ### ### perspective transform ### img, warped = debug_roi(frame, None, None) ### binarize frame ### ### get steering angle v1 ### ''' _, lines = pathfinder.get_line_segments(warped) grey = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY) turn_angle = pathfinder.compute_turn_angle(grey) print('turn angle:', turn_angle) cv2.imshow('lines', lines) ''' ### get steering angle v2 ### #mask, res = filter_hsv_colour(img, yellow_HSV_th_max, yellow_HSV_th_min) img_binary = binarization_utils.binarize(warped, verbose=False) cv2.imshow('img binary', img_binary) ### contours ### _, contours, hierarchy = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) img_binary_colour = cv2.cvtColor(img_binary, cv2.COLOR_GRAY2BGR) if len(contours) > 0: for cnt in contours: if cnt.size >= 5: epsilon = 0.1 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) ellipse = cv2.fitEllipse(cnt) cv2.ellipse(img_binary_colour, ellipse, (255, 0, 0), 5) rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) cv2.drawContours(img_binary_colour, [box], 0, (0, 0, 255), 5) ### basic pathfinder ### #img_binary_colour = img_binary_colour[:][100:] _, lines = pathfinder.get_line_segments(img_binary_colour) turn_angle = pathfinder.compute_turn_angle(img_binary_colour) print('turn angle:', turn_angle) turn_angle += 90 turn_angle_message = str('a%d' % int(turn_angle)) comm.write_serial_message(turn_angle_message) #comm.write_serial_message('s50') cv2.putText(lines, str(int(turn_angle)), (200, 450), cv2.FONT_HERSHEY_SIMPLEX, 4, (0, 255, 0), 4, cv2.LINE_AA) cv2.imshow('lines', lines) ''' keep_state = False if processed_frames > 0 and keep_state and line_lt.detected and line_rt.detected: line_lt, line_rt, img_fit = line_utils.get_fits_by_previous_fits(img_binary, line_lt, line_rt, verbose=False) else: line_lt, line_rt, img_fit = line_utils.get_fits_by_sliding_windows(img_binary, line_lt, line_rt, n_windows=9, verbose=False) offset_meter = compute_offset_from_center(line_lt, line_rt, frame_width=frame.shape[1]) ''' #print(offset_meter) #Minv = np.zeros(shape=(3, 3)) # draw the surface enclosed by lane lines back onto the original frame #blend_on_road = line_utils.draw_back_onto_the_road(img, Minv, line_lt, line_rt, keep_state) #cv2.imshow('asfdfd', blend_on_road) # 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, warped, img_fit, line_lt, line_rt, offset_meter) #processed_frames += 1 #cv2.imshow('mask', mask) #cv2.imshow('res', res) cv2.imshow('frame', frame) cv2.imshow('warped', warped) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
import os import matplotlib.pyplot as plt from calibration_utils import calibrate_camera, undistort from threshold import binarize, binarize_with_threshold from perspective_transform import perspective_transform import pickle import glob from line_utils import Line, get_fits_by_sliding_windows, get_fits_by_previous_fits, compute_offset_from_center from globals import * from visualization import final_viz, prepare_out_blend_frame import argparse from moviepy.editor import VideoFileClip #global variables processed_frames = 0 line_lt = Line(buffer_len=window_size) # line on the left of the lane line_rt = Line(buffer_len=window_size) # line on the right of the lane 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 # step 2 # TODO 4: call undistort funcction and pass it to img_undistorted
(60, 60), font, 1, (255, 255, 255), 2) cv2.putText(blend_on_road, 'Offset from center: {:.02f}m'.format(offset_meter), (60, 90), font, 1, (255, 255, 255), 2) processed_frames += 1 return blend_on_road if __name__ == '__main__': # step 1: calibrate the camera mtx, dist = calibrate('camera_cal') mode = "video" processed_frames = 0 line_lt, line_rt = Line(buffer_len=10), Line(buffer_len=10) if mode == "image": for test_img in glob.glob('test_images/*.jpg'): img = mpimg.imread(test_img) img_out = process_pipeline(img, True) plt.imshow(img_out) plt.show() elif mode == "video": selector = 'project' clip = VideoFileClip( '{}_video.mp4'.format(selector)).fl_image(process_pipeline) clip.write_videofile('out_{}.mp4'.format(selector), audio=False)