def check_lane_separation(self, left_fit, right_fit, max_diff=150): """ Sanity check left lane and right lane are separted in appropriate distance. """ if left_fit is None or right_fit is None: return None, None left_bottom_x = eval_poly(left_fit, self.h) right_bottom_x = eval_poly(right_fit, self.h) bottom_dist = abs(left_bottom_x - right_bottom_x) # Proper distance is defined by W and OFFSET in perspective transform. if abs(bottom_dist - (self.w - 2 * self.offset)) > max_diff: return None, None return left_fit, right_fit
def calc_center_dist(self, left_fit, right_fit): """ Calculates car distance from lane center :param left_fit: left lane line poly fit parameters. :param right_fit: right lane line poly fit parameters. :return: center distance in meters. """ if left_fit is None or right_fit is None: return 0.0 car_pos = self.w // 2 left_bottom_x = eval_poly(left_fit, self.h) right_bottom_x = eval_poly(right_fit, self.h) lane_center = (left_bottom_x + right_bottom_x) / 2 return (car_pos - lane_center) * self.mx
def distance_from_center(self): """ positve: right negative: left """ mid_x, max_y = self.image_size[0] / 2.0, self.image_size[1] bottom_x = eval_poly(self.coeffs, max_y) self.base_pos = (bottom_x - mid_x) * self.xm_per_pix
def draw_lanes(img, left_fit, right_fit, warper): """ Draws lanes on image. :param img: input image. :param left_fit: left line polyfit. :param right_fit: right line polyfit :param warper: a callable warps bird-view to vehicle-view. :return: created image. """ draw_img = np.copy(img) if left_fit is None or right_fit is None: return draw_img color_warp = np.zeros_like(draw_img) # to cover same y-range as image w, h = draw_img.shape[1], draw_img.shape[0] ploty = np.linspace(0, h - 1, h) left_fitx = eval_poly(left_fit, ploty) right_fitx = eval_poly(right_fit, ploty) # 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]), GREEN) cv2.polylines(color_warp, np.int32([pts_left]), isClosed=False, color=RED, thickness=15) cv2.polylines(color_warp, np.int32([pts_right]), isClosed=False, color=BLUE, thickness=15) # Warp the blank back to original image space using |warper| newwarp = warper(color_warp) # Combine the result with the original image return cv2.addWeighted(draw_img, 1, newwarp, 0.5, 0)
def search_lanes_with_prev(self, binary_img, prev_left_fit, prev_right_fit): """ Searches left and right lane lines from a binary image, by using previous fitting lanes and polynomial fitting. :param binary_img: binary image. :param prev_left_fit: previous left polyfit parameters. :param prev_right_fit: previous right polyfit parameters. :return: left_fit: left lane line poly fit parameters. right_fit: right lane line poly fit parameters. left_lane_inds: left lane line indices. right_lane_inds: right lane line indices. margin: margin +/- from the previous lanes. """ nonzero = binary_img.nonzero() nonzeroy = np.array(nonzero[0]) nonzerox = np.array(nonzero[1]) prev_left_fit_x = eval_poly(prev_left_fit, nonzeroy) prev_right_fit_x = eval_poly(prev_right_fit, nonzeroy) left_lane_inds = ((nonzerox > prev_left_fit_x - self.margin) & (nonzerox < prev_left_fit_x + self.margin)) right_lane_inds = ((nonzerox > prev_right_fit_x - self.margin) & (nonzerox < prev_right_fit_x + self.margin)) # Extract left and right line pixel positions leftx = nonzerox[left_lane_inds] lefty = nonzeroy[left_lane_inds] rightx = nonzerox[right_lane_inds] righty = nonzeroy[right_lane_inds] left_fit, right_fit = None, None if len(leftx) > 0: # Fit a second order polynomial to each left_fit = np.polyfit(lefty, leftx, 2) if len(rightx) > 0: right_fit = np.polyfit(righty, rightx, 2) return left_fit, right_fit, left_lane_inds, right_lane_inds, self.margin
def compute_flowfield(design_vec,var): # ypred = np.array(Parallel(n_jobs=ncores,verbose=1,)(delayed(eval_poly)(design_vec,lowers[pt,var],uppers[pt,var],coeffs[pt,var,:],W[pt,var,:,:]) for pt in pts)) for pt in pts: ypred[pt] = eval_poly(design_vec,lowers[pt,var],uppers[pt,var],coeffs[pt,var,:],W[pt,var,:,:]) return ypred
def draw_lane_fits(img, left_fit, right_fit, left_lane_inds, right_lane_inds, rectangles, margin): """ Generates lane line fits. :param img: binary image :param left_fit: left line polyfit. :param right_fit: right line polyfit. :param left_lane_inds: left line indices. :param right_lane_inds: right line indices. :param rectangles: rectangles used in sliding window search. :param margin: margin used in marginal search. :return: created (RGB colorspace). """ w, h = img.shape[1], img.shape[0] ploty = np.linspace(0, h - 1, h) left_fitx, right_fitx = eval_poly([1, 1, 0], ploty), eval_poly([1, 1, 0], ploty) if left_fit is not None: left_fitx = eval_poly(left_fit, ploty) if right_fit is not None: right_fitx = eval_poly(right_fit, ploty) out_img = np.dstack((img, img, img)) # Draw the rectangles on the visualization image, if any. if rectangles: for rect in rectangles: cv2.rectangle(out_img, (rect[0], rect[1]), (rect[2], rect[3]), GREEN, 2) # Identify the x and y positions of all nonzero pixels in the image. nonzero = img.nonzero() nonzeroy = np.array(nonzero[0]) nonzerox = np.array(nonzero[1]) out_img[nonzeroy[left_lane_inds], nonzerox[left_lane_inds]] = RED out_img[nonzeroy[right_lane_inds], nonzerox[right_lane_inds]] = BLUE # Draw the lane onto the warped blank image pts_left = np.array([np.transpose(np.vstack([left_fitx, ploty]))]) pts_right = np.array( [np.flipud(np.transpose(np.vstack([right_fitx, ploty])))]) cv2.polylines(out_img, np.int32([pts_left]), isClosed=False, color=YELLOW, thickness=2) cv2.polylines(out_img, np.int32([pts_right]), isClosed=False, color=YELLOW, thickness=2) # Draw margin on image, if any. if margin: left_line_window1 = np.array( [np.transpose(np.vstack([left_fitx - margin, ploty]))]) left_line_window2 = np.array( [np.flipud(np.transpose(np.vstack([left_fitx + margin, ploty])))]) left_line_pts = np.hstack((left_line_window1, left_line_window2)) right_line_window1 = np.array( [np.transpose(np.vstack([right_fitx - margin, ploty]))]) right_line_window2 = np.array( [np.flipud(np.transpose(np.vstack([right_fitx + margin, ploty])))]) right_line_pts = np.hstack((right_line_window1, right_line_window2)) # Generate a polygon to illustrate the search window area # And recast the x and y points into usable format for cv2.fillPoly() window_img = np.zeros_like(out_img) # Draw the lane onto the warped blank image cv2.fillPoly(window_img, np.int_([left_line_pts]), GREEN) cv2.fillPoly(window_img, np.int_([right_line_pts]), GREEN) out_img = cv2.addWeighted(out_img, 1, window_img, 0.3, 0) return out_img
def deviate_of_center(cls, left, right): x, y = left.image_size[0], left.image_size[1] x_left = eval_poly(left.coeffs, y) x_right = eval_poly(right.coeffs, y) return (x / 2.0 - (x_left + x_right) / 2.0) * left.xm_per_pix