def corners_unwarp(image, chessboard_size): """ chessboard_size = (nx, ny) nx by ny size chessboard. """ undist = undistort(image) gray = cv2.cvtColor(undist, cv2.COLOR_BGR2GRAY) ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None) nx, _ = chessboard_size if ret: cv2.drawChessboardCorners(undist, chessboard_size, corners, ret) width, height = image.shape[1], image.shape[0] src_corners = np.float32( [corners[0], corners[nx - 1], corners[-nx], corners[-1]]) offset = 100 # offset for dst points dst_corners = np.float32([[offset, offset], [width - offset, offset], [offset, height - offset], [width - offset, height - offset]]) M = cv2.getPerspectiveTransform(src_corners, dst_corners) warped = cv2.warpPerspective(undist, M, (width, height), flags=cv2.INTER_LINEAR) return warped, M else: raise Exception("Cannot find corners", UserWarning)
def get_raw_line_pixels(self, image): self.image_undistorted = undistort(image, self.mtx, self.dist) self.ploty = np.linspace(0, self.image_undistorted.shape[0] - 1, self.image_undistorted.shape[0]) self.image_birdseye, self.M, self.Minv = self.get_birdseye( self.image_undistorted) self.image_hsv_bin = filter_white_yellow_hsv(self.image_birdseye) self.image_hls_bin = filter_hls(self.image_birdseye) analyse_histogram(self.image_hsv_bin) self.image_yellow_white_hls_bin = image_wip2 = filter_white_yellow_hls2( self.image_birdseye) # filter_white_yellow_hls2 # analyse_histogram(image_wip2) self.image_flt_hls_bin = filter_hls(self.image_birdseye) if (self.l_line.plausible == True) & (self.r_line.plausible == True): self.lanes_found, self.leftx_pixel_pos, self.lefty_pixel_pos, self.rightx_pixel_pos, self.righty_pixel_pos = self.find_lanes_near( self.image_hsv_bin) else: self.lanes_found, self.leftx_pixel_pos, self.lefty_pixel_pos, self.rightx_pixel_pos, self.righty_pixel_pos = self.find_lanes_blind( self.image_hsv_bin) print('self.left_fitx: {}, self.right_fitx: {}'.format( self.left_fitx, self.right_fitx)) # self.calculate_radius_real(self.left_fit, self.right_fit) return self.lanes_found, self.leftx_pixel_pos, self.lefty_pixel_pos, self.rightx_pixel_pos, self.righty_pixel_pos
def pipeline(img): # Undistort img_undistort = undistort(mtx, dist, img) # Perspective Transform img_unwarp, M, Minv = unwarp(img_undistort, src, dst) # Sobel Absolute (using default parameters) #img_sobelAbs = abs_sobel_thresh(img_unwarp) # Sobel Magnitude (using default parameters) #img_sobelMag = mag_thresh(img_unwarp) # Sobel Direction (using default parameters) #img_sobelDir = dir_thresh(img_unwarp) # HLS S-channel Threshold (using default parameters) #img_SThresh = hls_sthresh(img_unwarp) # HLS L-channel Threshold (using default parameters) img_LThresh = hls_lthresh(img_unwarp) # Lab B-channel Threshold (using default parameters) img_BThresh = lab_bthresh(img_unwarp) # Combine HLS and Lab B channel thresholds combined = np.zeros_like(img_BThresh) combined[(img_LThresh == 1) | (img_BThresh == 1)] = 1 return combined, Minv
def frameProcessPipeline(frame, keepState=True): global leftLine, rightLine, _processedFrameCount # undistort the image using coefficients found in calibration undistortedImage = undistort(frame, mtx, dist, verbose=False) # binarize the frame s.t. lane lines are highlighted as much as possible binaryImage = binarize(undistortedImage, verbose=False) # compute perspective transform to obtain bird's eye view warpedImage, M, Minv = warpPerspective(binaryImage, verbose=False) # fit 2-degree polynomial curve onto lane lines found if _processedFrameCount > 0 and keepState and leftLine.detected and rightLine.detected: leftLine, rightLine, img_fit = usePreviousFits(warpedImage, leftLine, rightLine, verbose=False) else: leftLine, rightLine, img_fit = slidingWindowFits(warpedImage, leftLine, rightLine, numWindows=9, verbose=False) # compute offset in meter from center of the lane offFromCenter = calculateOffFromCenter(leftLine, rightLine, frame_width=frame.shape[1]) # draw the surface enclosed by lane lines back onto the original frame image = drawOnRoad(undistortedImage, Minv, leftLine, rightLine, keepState) # stitch on the top of final output images from different steps of the pipeline blend_output = finalOutputDisplay(image, offFromCenter) _processedFrameCount += 1 return blend_output
def demo_mask(): # Read in a thresholded image #warped = mpimg.imread('warped_example.jpg') image = mpimg.imread('test_images/test1.jpg') undist = undistort(image) warped, M, M_inverse = warp(undist) binary_warped = threshold_image(warped) #plt.imshow(binary_warped) #plt.show() #warped = mpimg.imread('output_images/straight_lines1_warped.jpg') # window settings convolution = createConvolution() lane = convolution.find_lane(binary_warped) window_width = convolution.window_width window_height = convolution.window_height # If we found any window centers if lane is not None: # Points used to draw all the left and right windows l_points = np.zeros_like(binary_warped) r_points = np.zeros_like(binary_warped) # Go through each level and draw the windows for level in range(0, len(lane.leftx)): # Window_mask is a function to draw window areas l_mask = window_mask(window_width, window_height, binary_warped, lane.leftx[level], level) r_mask = window_mask(window_width, window_height, binary_warped, lane.rightx[level], level) # Add graphic points from window mask here to total pixels found l_points[(l_points == 255) | ((l_mask == 1))] = 255 r_points[(r_points == 255) | ((r_mask == 1))] = 255 # Draw the results template = np.array( r_points + l_points, np.uint8) # add both left and right window pixels together zero_channel = np.zeros_like(template) # create a zero color channel template = np.array(cv2.merge((zero_channel, template, zero_channel)), np.uint8) # make window pixels green warpage = np.array( cv2.merge((binary_warped, binary_warped, binary_warped)), np.uint8) # making the original road pixels 3 color channels output = cv2.addWeighted( warpage, 1, template, 0.5, 0.0) # overlay the orignal road image with window results # If no window centers found, just display orginal road image else: output = np.array( cv2.merge((binary_warped, binary_warped, binary_warped)), np.uint8) # Display the final results side_by_side_plot(binary_warped, output, im1_title="Binary Warped", im2_title="Conv Search", im1_cmap='gray', im2_cmap='gray')
def _action(self, context): img = context.get(self.input) if img is None: raise exceptions.PipeException( "missing context parameter: {}".format(self.input)) img_cal = calibration.undistort(img, self.mtx, self.dist) context[self.output] = img_cal return img_cal
def renders(self): # Correcting for Distortion undist_img = undistort(self.image, self.mtx, self.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 = combine_gradients( undist_img, (self.thesh_sobelx_X, self.thesh_sobelx_Y), (self.thesh_sobely_X, self.thesh_sobely_Y), (self.thesh_mag_X, self.thesh_mag_Y), (self.thesh_dir_X, self.thesh_dir_Y)) combined_hls = get_hls(undist_img, (self.thesh_h_X, self.thesh_h_Y), (self.thesh_l_X, self.thesh_l_Y), (self.thesh_s_X, self.thesh_s_Y)) combined_result = combine_hls_grandient(combined_gradient, combined_hls) c_rows, c_cols = combined_result.shape[:2] s_LTop2, s_RTop2 = [299, 40], [374, 40] s_LBot2, s_RBot2 = [218, 92], [472, 92] src = np.float32([s_LBot2, s_LTop2, s_RTop2, s_RBot2]) dst = np.float32([(60, 540), (60, 0), (360, 0), (360, 540)]) warp_img, M, Minv = get_perspective_transform(combined_result, src, dst, (420, 540)) cv2.imwrite('combine.png', combined_gradient) cv2.imwrite('wrap.png', warp_img) searching_img = get_lane_lines_img(warp_img, self.left_line, self.right_line) w_comb_result, w_color_result = draw_lane_line(searching_img, self.left_line, self.right_line) color_result = cv2.warpPerspective(w_color_result, Minv, (c_cols, c_rows)) lane_color = np.zeros_like(undist_img) lane_color[180:, :] = color_result result = cv2.addWeighted(undist_img, 1, lane_color, 0.3, 0) cv2.imwrite('results.png', result) cv2.imshow('LaneLines', result) cv2.imshow('bird_view', w_color_result) cv2.imshow('search_img', searching_img) cv2.imshow('gradient', warp_img) print(combined_hls.shape) # For debuging cv2.imshow('hls', combined_hls) cv2.imshow('combine', combined_result)
def demo(): image = mpimg.imread('test_images/straight_lines2.jpg') undist_image = undistort(image) warped, M, M_inverse = warp(undist_image) side_by_side_plot(image, warped, im1_title="Image", im2_title="Warped Image")
def pipeline(frame): # cv2.imwrite('./out_img/origin.png', frame) undist_img = undistort(frame, mtx, dist) undist_img = cv2.resize(undist_img, None, fx=1 / 2, fy=1 / 2, interpolation=cv2.INTER_AREA) # cv2.imwrite('./out_img/0_undist_img.png', undist_img) rows, cols = undist_img.shape[:2] combined_gradient = combine_gradients(undist_img, th_sobelx, th_sobely, th_mag, th_dir) # cv2.imwrite('./out_img/1_combine_gradient.png', combined_gradient) combined_hls = get_hls(undist_img, th_h, th_l, th_s) # cv2.imwrite('./out_img/2_combine_hls.png', combined_hls) combined_result = combine_hls_grandient(combined_gradient, combined_hls) # cv2.imwrite('./out_img/3_combine_result.png', combined_result) c_rows, c_cols = combined_gradient.shape[:2] s_LTop2, s_RTop2 = [299, 40], [374, 40] s_LBot2, s_RBot2 = [218, 92], [472, 92] src = np.float32([s_LBot2, s_LTop2, s_RTop2, s_RBot2]) dst = np.float32([(60, 540), (60, 0), (360, 0), (360, 540)]) warp_img, M, Minv = get_perspective_transform(combined_result, src, dst, (420, 540)) # cv2.imwrite('./out_img/bird_eye_view.png', warp_img) searching_img = get_image_lane_lines(warp_img, left_line, right_line) # cv2.imwrite('./out_img/searching.png', searching_img) w_comb_result, w_color_result = draw_lane_line(searching_img, left_line, right_line) # cv2.imwrite('./out_img/draw_lane.png', w_color_result) color_result = cv2.warpPerspective(w_color_result, Minv, (c_cols, c_rows)) # cv2.imwrite('./out_img/wrapped.png', color_result) lane_color = np.zeros_like(undist_img) lane_color[180:, :] = color_result result = cv2.addWeighted(undist_img, 1, lane_color, 0.3, 0) # cv2.imwrite('./out_img/result.png', result) return result
def demo_threshold_image(): image = mpimg.imread('test_images/straight_lines1.jpg') undist = undistort(image) warped, M, M_inverse = warp(undist) binary_warped = threshold_image(warped) side_by_side_plot(image, binary_warped, im1_title='Image', im2_title='Binary Warped', im2_cmap='gray') #plt.imshow(binary_image, cmap = 'gray') #plt.show() #demo_threshold_image()
def demo_convolution(): # Read in a thresholded image image = mpimg.imread('test_images/straight_lines2.jpg') undist = undistort(image) warped, M, M_inverse = warp(undist) binary_warped = threshold_image(warped) #plt.imshow(binary_warped) #plt.show() #warped = mpimg.imread('output_images/straight_lines1_warped.jpg') # window settings height = binary_warped.shape[0] convolution = createConvolution() lane = convolution.find_lane(binary_warped) left_fit, right_fit = lane.polyfit() y = np.linspace(0, height - 1, 72) leftx, rightx = lane.ploty(y) y_meter_per_pixel = 30 / 720 # meters per pixel in y dimension x_meter_per_pixel = 3.7 / 700 # meters per pixel in x dimension left_curverad, right_curverad = lane.measure_curvature( x_meter_per_pixel=x_meter_per_pixel, y_meter_per_pixel=y_meter_per_pixel) center_offset = convolution.center_offset(lane, x_meter_per_pixel) lane_drawn = convolution.draw_lane(lane, M_inverse) result = cv2.addWeighted(undist, 1, lane_drawn, 0.3, 0) plt.imshow(result) plt.plot(leftx, y, color='yellow') plt.plot(rightx, y, color='yellow') plt.text(5, 30, 'Left, Right Curvature: {:.2f}m, {:.2f}m'.format( left_curverad, right_curverad), fontsize=10, color='red') plt.text(5, 50, 'Center Lane Offset: {:.2f}m, Confidence: {:.2f}%'.format( center_offset, lane.confidence * 100), fontsize=10, color='red') plt.xlim(0, 1280) plt.ylim(720, 0) plt.show()
def process_pipeline(frame, keep_state): """ Description: Apply whole lane detection pipeline to an input color frame. Parameter - Frame: input color frame Parameter - keep_state: if True, lane-line state is conserved (this permits to average results) Rreturn - output blend with detected lane overlaid """ global left_line, right_line, processed_frames, show_processing # undistort the image using coefficients found in calibration undistorted_img = undistort(frame, mtx, dist, testing=False) # binarize the frame s.t. lane lines are highlighted as much as possible binary_img = binarize(undistorted_img, testing=False) # compute perspective transform to obtain bird's eye view birdeye_img, M, Minv = birdeye(binary_img, testing=False) # fit 2-degree polynomial curve onto lane lines found if processed_frames > 0 and keep_state and left_line.detected and right_line.detected: left_line, right_line, img_fit = get_fits_by_previous_fits( birdeye_img, left_line, right_line, verbose=False) else: left_line, right_line, img_fit = get_fits_by_sliding_windows( birdeye_img, left_line, right_line, n_windows=9, verbose=False) # compute offset in meter from center of the lane offset_meter = compute_offset_from_center(left_line, right_line, 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(undistorted_img, Minv, left_line, right_line, keep_state) processed_frames += 1 if show_processing: # stitch on the top of final output images from different steps of the pipeline blend_on_road = blend(blend_on_road, binary_img, birdeye_img, img_fit, left_line, right_line, offset_meter) #combined = blend(undistorted_img, binary_img, birdeye_img) return blend_on_road
def detect(self, rgb_image): undist_image = undistort(rgb_image) warped, M, M_inverse = warp(undist_image) binary_warped = threshold_image(warped) lane = None if self.best_lane is not None: lane = self.convolution.find_lane_with_hint(self.best_lane.midx(), binary_warped) if lane is None: lane = self.convolution.find_lane(binary_warped) self.add_lane(lane) lane_selected = None if self.best_lane is not None: lane_selected = self.best_lane self.n_best_lane_used += 1 elif (lane is not None) and lane.good_confidence(): lane_selected = lane self.n_lane_used += 1 else: lane_selected = self.last_good_lane self.n_last_good_lane_used += 1 if (lane is not None) and lane.good_confidence(): self.last_good_lane = lane if lane_selected is not None: left_curverad, right_curverad = self.measure_curvature(lane_selected) center_offset = self.center_offset(lane_selected) lane_drawn = self.convolution.draw_lane(lane_selected, M_inverse = M_inverse) out_image = cv2.addWeighted(undist_image, 1, lane_drawn, 0.3, 0) cv2.putText(out_image, 'Left, Right Curvature: {:.2f}m, {:.2f}m'.format(left_curverad, right_curverad), (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) cv2.putText(out_image, 'Center Lane Offset: {:.2f}m'.format(center_offset), (50, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) return out_image else: if lane is not None: print(lane.confidence) side_by_side_plot(undist_image, binary_warped) self.n_no_lane_used += 1 return undist_image
def process_pipeline(frame, keep_state=True): global line_lt, line_rt, processed_frames # undistorted the image using coefficients found in calibration img_undistorted = undistort(frame, mtx, dist, verbose=False) # binarize the frame to highlight lane lines as much as possible img_binary = binarize(img_undistorted, verbose=False) # compute perspective transform to obtain bird's eye view img_birdeye, M, Minv = birdeye(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 (thumbnail view of each pipeline steps) 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
src2=blend_onto_road, beta=0.5, 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 = calibrate_camera( calib_images_dir='camera_cal') # 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 = binarize(img_undistorted, verbose=False) img_birdeye, M, Minv = birdeye(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)
for point in src: axarray[0].plot(*point, '.') axarray[1].set_title('After perspective transform') axarray[1].imshow(warped, cmap='gray') for point in dst: axarray[1].plot(*point, '.') for axis in axarray: axis.set_axis_off() plt.show() return warped, M, Minv if __name__ == '__main__': ret, mtx, dist, rvecs, tvecs = calibrate_camera( calib_images_dir='camera_cal') # show result on test images for test_img in glob.glob('test_images/*.jpg'): img = cv2.imread(test_img) undistorted_img = undistort(img, mtx, dist, testing=False) binary_img = binarize(undistorted_img, testing=False) birdeye_img, M, Minv = birdeye(cv2.cvtColor(undistorted_img, cv2.COLOR_BGR2RGB), testing=True)
input_name = 'project_video.mp4' #'test_images/straight_lines1.jpg' # 'challenge_video.mp4' left_line = Line() right_line = Line() th_sobelx, th_sobely, th_mag, th_dir = (35, 100), (30, 255), (30, 255), (0.7, 1.3) th_h, th_l, th_s = (10, 100), (0, 60), (85, 255) # camera matrix & distortion coefficient mtx, dist = calib() if __name__ == '__main__': if input_type == 'image': img = cv2.imread(input_name) undist_img = undistort(img, mtx, dist) 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 = gradient_combine(undist_img, th_sobelx, th_sobely, th_mag, th_dir) combined_hls = hls_combine(undist_img, th_h, th_l, th_s) combined_result = comb_result(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 = warp_image(combined_result, src, dst, (720, 720))
def calibrate(self, frame): return undistort(frame, self.mtx, self.dist)
def to_binary_image(image): undist = undistort(image) binary_warped, M, M_inverse = warp(undist) return threshold_image(binary_warped)
return binary_output if __name__ == "__main__": from calibration import calibrate, undistort from unwraped import unwraped import matplotlib.image as mpimg img = mpimg.imread("test_images/test1.jpg") #img = cv2.imread("test_images/test1.jpg") img_size = (img.shape[0], img.shape[1]) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #cv2.imwrite('examples/gray_1.png', gray) ret, mtx, dist, rvecs, tvecs = calibrate(gray, 6, 9) undistort_img = undistort(img, mtx, dist) #cv2.imwrite('examples/undistort_img_1.png', undistort_img) #gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) unwraped_img = unwraped(undistort_img, img_size) hls = cv2.cvtColor(unwraped_img, cv2.COLOR_RGB2HLS).astype(np.float) l_channel = hls[:, :, 1] s_channel = hls[:, :, 2] x_binary_output = abs_sobel_thresh(unwraped_img, orient='x', thresh_min=20, thresh_max=100) cv2.imwrite('examples/sobel_x_1.png', x_binary_output) cv2.imwrite('examples/sobel_y_1.png', y_binary_output) l_chanel_output = abs_sobel_thresh(l_channel,