lane/line.py
def line_search_reset(binary_img, left_lane, right_line):
    """
    #---------------------
    # After applying calibration, thresholding, and a perspective transform to a road image,
    # I have a binary image where the lane lines stand out clearly.
    # However, I still need to decide explicitly which pixels are part of the lines
    # and which belong to the left line and which belong to the right line.
    #
    # This lane line search is done using histogram and sliding window
    #
    # The sliding window implementation is based on lecture videos.
    #
    # This function searches lines from scratch, i.e. without using info from previous lines.
    # However, the search is not entirely a blind search, since I am using histogram information.
    #
    # Use Cases:
    #    - Use this function on the first frame
    #    - Use when lines are lost or not detected in previous frames
    #
    """

    # I first take a histogram along all the columns in the lower half of the image
    histogram = np.sum(binary_img[int(binary_img.shape[0] / 2) :, :], axis=0)

    # Create an output image to draw on and  visualize the result
    out_img = np.dstack((binary_img, binary_img, binary_img)) * 255

    # Find the peak of the left and right halves of the histogram
    # These will be the starting point for the left and right lines
    midpoint = np.int(histogram.shape[0] / 2)
    leftX_base = np.argmax(histogram[:midpoint])
    rightX_base = np.argmax(histogram[midpoint:]) + midpoint

    # Choose the number of sliding windows
    num_windows = 9

    # Set height of windows
    window_height = np.int(binary_img.shape[0] / num_windows)

    # Identify the x and y positions of all nonzero pixels in the image
    nonzero = binary_img.nonzero()
    nonzeroy = np.array(nonzero[0])
    nonzerox = np.array(nonzero[1])

    # Current positions to be updated for each window
    current_leftX = leftX_base
    current_rightX = rightX_base

    # Set minimum number of pixels found to recenter window
    min_num_pixel = 50

    # Create empty lists to receive left and right lane pixel indices
    win_left_lane = []
    win_right_lane = []

    window_margin = left_lane.window_margin

    # Step through the windows one by one
    for window in range(num_windows):
        # Identify window boundaries in x and y (and right and left)
        win_y_low = binary_img.shape[0] - (window + 1) * window_height
        win_y_high = binary_img.shape[0] - window * window_height
        win_leftx_min = current_leftX - window_margin
        win_leftx_max = current_leftX + window_margin
        win_rightx_min = current_rightX - window_margin
        win_rightx_max = current_rightX + window_margin

        # Draw the windows on the visualization image
        cv2.rectangle(
            out_img,
            (win_leftx_min, win_y_low),
            (win_leftx_max, win_y_high),
            (0, 255, 0),
            2,
        )
        cv2.rectangle(
            out_img,
            (win_rightx_min, win_y_low),
            (win_rightx_max, win_y_high),
            (0, 255, 0),
            2,
        )

        # Identify the nonzero pixels in x and y within the window
        left_window_inds = (
            (nonzeroy >= win_y_low)
            & (nonzeroy <= win_y_high)
            & (nonzerox >= win_leftx_min)
            & (nonzerox <= win_leftx_max)
        ).nonzero()[0]
        right_window_inds = (
            (nonzeroy >= win_y_low)
            & (nonzeroy <= win_y_high)
            & (nonzerox >= win_rightx_min)
            & (nonzerox <= win_rightx_max)
        ).nonzero()[0]
        # Append these indices to the lists
        win_left_lane.append(left_window_inds)
        win_right_lane.append(right_window_inds)

        # If you found > minpix pixels, recenter next window on their mean position
        if len(left_window_inds) > min_num_pixel:
            current_leftX = np.int(np.mean(nonzerox[left_window_inds]))
        if len(right_window_inds) > min_num_pixel:
            current_rightX = np.int(np.mean(nonzerox[right_window_inds]))

    # Concatenate the arrays of indices
    win_left_lane = np.concatenate(win_left_lane)
    win_right_lane = np.concatenate(win_right_lane)

    # Extract left and right line pixel positions
    leftx = nonzerox[win_left_lane]
    lefty = nonzeroy[win_left_lane]
    rightx = nonzerox[win_right_lane]
    righty = nonzeroy[win_right_lane]

    out_img[lefty, leftx] = [255, 0, 0]
    out_img[righty, rightx] = [0, 0, 255]

    # Fit a second order polynomial to each
    left_fit = np.polyfit(lefty, leftx, 2)
    right_fit = np.polyfit(righty, rightx, 2)

    left_lane.current_fit = left_fit
    right_line.current_fit = right_fit

    # Generate x and y values for plotting
    ploty = np.linspace(0, binary_img.shape[0] - 1, binary_img.shape[0])
    # ax^2 + bx + c
    left_plotx = left_fit[0] * ploty**2 + left_fit[1] * ploty + left_fit[2]
    right_plotx = right_fit[0] * ploty**2 + right_fit[1] * ploty + right_fit[2]

    left_lane.prevx.append(left_plotx)
    right_line.prevx.append(right_plotx)

    if len(left_lane.prevx) > 10:
        left_avg_line = smoothing(left_lane.prevx, 10)
        left_avg_fit = np.polyfit(ploty, left_avg_line, 2)
        left_fit_plotx = (
            left_avg_fit[0] * ploty**2 + left_avg_fit[1] * ploty + left_avg_fit[2]
        )
        left_lane.current_fit = left_avg_fit
        left_lane.allx, left_lane.ally = left_fit_plotx, ploty
    else:
        left_lane.current_fit = left_fit
        left_lane.allx, left_lane.ally = left_plotx, ploty

    if len(right_line.prevx) > 10:
        right_avg_line = smoothing(right_line.prevx, 10)
        right_avg_fit = np.polyfit(ploty, right_avg_line, 2)
        right_fit_plotx = (
            right_avg_fit[0] * ploty**2 + right_avg_fit[1] * ploty + right_avg_fit[2]
        )
        right_line.current_fit = right_avg_fit
        right_line.allx, right_line.ally = right_fit_plotx, ploty
    else:
        right_line.current_fit = right_fit
        right_line.allx, right_line.ally = right_plotx, ploty

    left_lane.startx, right_line.startx = (
        left_lane.allx[len(left_lane.allx) - 1],
        right_line.allx[len(right_line.allx) - 1],
    )
    left_lane.endx, right_line.endx = left_lane.allx[0], right_line.allx[0]

    # Set detected=True for both lines
    left_lane.detected, right_line.detected = True, True

    measure_curvature(left_lane, right_line)

    return out_img

    #---------------------
    # After applying calibration, thresholding, and a perspective transform to a road image,
    # I have a binary image where the lane lines stand out clearly.
    # However, I still need to decide explicitly which pixels are part of the lines
    # and which belong to the left line and which belong to the right line.
    #
    # This lane line search is done using histogram and sliding window
    #
    # The sliding window implementation is based on lecture videos.
    #
    # This function searches lines from scratch, i.e. without using info from previous lines.
    # However, the search is not entirely a blind search, since I am using histogram information.
    #
    # Use Cases:
    #    - Use this function on the first frame
    #    - Use when lines are lost or not detected in previous frames
    #
    
After applying calibration, thresholding, and a perspective transform to a road image,
I have a binary image where the lane lines stand out clearly.
However, I still need to decide explicitly which pixels are part of the lines
and which belong to the left line and which belong to the right line.

This lane line search is done using histogram and sliding window

The sliding window implementation is based on lecture videos.

This function searches lines from scratch, i.e. without using info from previous lines.
However, the search is not entirely a blind search, since I am using histogram information.

Use Cases:
- Use this function on the first frame
- Use when lines are lost or not detected in previous frames
After applying calibration thresholding and a perspective transform to a road image I have a binary image where the lane lines stand out clearly . However I still need to decide explicitly which pixels are part of the lines and which belong to the left line and which belong to the right line . This lane line search is done using histogram and sliding window The sliding window implementation is based on lecture videos . This function searches lines from scratch i . e . without using info from previous lines . However the search is not entirely a blind search since I am using histogram information . Use Cases : - Use this function on the first frame - Use when lines are lost or not detected in previous frames
def line_search_reset(binary_img, left_lane, right_line):
    histogram = np.sum(binary_img[int(binary_img.shape[0] / 2) :, :], axis=0)
    out_img = np.dstack((binary_img, binary_img, binary_img)) * 255
    midpoint = np.int(histogram.shape[0] / 2)
    leftX_base = np.argmax(histogram[:midpoint])
    rightX_base = np.argmax(histogram[midpoint:]) + midpoint
    num_windows = 9
    window_height = np.int(binary_img.shape[0] / num_windows)
    nonzero = binary_img.nonzero()
    nonzeroy = np.array(nonzero[0])
    nonzerox = np.array(nonzero[1])
    current_leftX = leftX_base
    current_rightX = rightX_base
    min_num_pixel = 50
    win_left_lane = []
    win_right_lane = []
    window_margin = left_lane.window_margin
    for window in range(num_windows):
        win_y_low = binary_img.shape[0] - (window + 1) * window_height
        win_y_high = binary_img.shape[0] - window * window_height
        win_leftx_min = current_leftX - window_margin
        win_leftx_max = current_leftX + window_margin
        win_rightx_min = current_rightX - window_margin
        win_rightx_max = current_rightX + window_margin
        cv2.rectangle(
            out_img,
            (win_leftx_min, win_y_low),
            (win_leftx_max, win_y_high),
            (0, 255, 0),
            2,
        )
        cv2.rectangle(
            out_img,
            (win_rightx_min, win_y_low),
            (win_rightx_max, win_y_high),
            (0, 255, 0),
            2,
        )
        left_window_inds = (
            (nonzeroy >= win_y_low)
            & (nonzeroy <= win_y_high)
            & (nonzerox >= win_leftx_min)
            & (nonzerox <= win_leftx_max)
        ).nonzero()[0]
        right_window_inds = (
            (nonzeroy >= win_y_low)
            & (nonzeroy <= win_y_high)
            & (nonzerox >= win_rightx_min)
            & (nonzerox <= win_rightx_max)
        ).nonzero()[0]
        win_left_lane.append(left_window_inds)
        win_right_lane.append(right_window_inds)
        if len(left_window_inds) > min_num_pixel:
            current_leftX = np.int(np.mean(nonzerox[left_window_inds]))
        if len(right_window_inds) > min_num_pixel:
            current_rightX = np.int(np.mean(nonzerox[right_window_inds]))
    win_left_lane = np.concatenate(win_left_lane)
    win_right_lane = np.concatenate(win_right_lane)
    leftx = nonzerox[win_left_lane]
    lefty = nonzeroy[win_left_lane]
    rightx = nonzerox[win_right_lane]
    righty = nonzeroy[win_right_lane]
    out_img[lefty, leftx] = [255, 0, 0]
    out_img[righty, rightx] = [0, 0, 255]
    left_fit = np.polyfit(lefty, leftx, 2)
    right_fit = np.polyfit(righty, rightx, 2)
    left_lane.current_fit = left_fit
    right_line.current_fit = right_fit
    ploty = np.linspace(0, binary_img.shape[0] - 1, binary_img.shape[0])
    left_plotx = left_fit[0] * ploty**2 + left_fit[1] * ploty + left_fit[2]
    right_plotx = right_fit[0] * ploty**2 + right_fit[1] * ploty + right_fit[2]
    left_lane.prevx.append(left_plotx)
    right_line.prevx.append(right_plotx)
    if len(left_lane.prevx) > 10:
        left_avg_line = smoothing(left_lane.prevx, 10)
        left_avg_fit = np.polyfit(ploty, left_avg_line, 2)
        left_fit_plotx = (
            left_avg_fit[0] * ploty**2 + left_avg_fit[1] * ploty + left_avg_fit[2]
        )
        left_lane.current_fit = left_avg_fit
        left_lane.allx, left_lane.ally = left_fit_plotx, ploty
    else:
        left_lane.current_fit = left_fit
        left_lane.allx, left_lane.ally = left_plotx, ploty
    if len(right_line.prevx) > 10:
        right_avg_line = smoothing(right_line.prevx, 10)
        right_avg_fit = np.polyfit(ploty, right_avg_line, 2)
        right_fit_plotx = (
            right_avg_fit[0] * ploty**2 + right_avg_fit[1] * ploty + right_avg_fit[2]
        )
        right_line.current_fit = right_avg_fit
        right_line.allx, right_line.ally = right_fit_plotx, ploty
    else:
        right_line.current_fit = right_fit
        right_line.allx, right_line.ally = right_plotx, ploty
    left_lane.startx, right_line.startx = (
        left_lane.allx[len(left_lane.allx) - 1],
        right_line.allx[len(right_line.allx) - 1],
    )
    left_lane.endx, right_line.endx = left_lane.allx[0], right_line.allx[0]
    left_lane.detected, right_line.detected = True, True
    measure_curvature(left_lane, right_line)
    return out_img
def line_search_reset ( binary_img , left_lane , right_line ) : histogram = np . sum ( binary_img [ int ( binary_img . shape [ 0 ] / 2 ) : , : ] , axis = 0 ) out_img = np . dstack ( ( binary_img , binary_img , binary_img ) ) * 255 midpoint = np . int ( histogram . shape [ 0 ] / 2 ) leftX_base = np . argmax ( histogram [ : midpoint ] ) rightX_base = np . argmax ( histogram [ midpoint : ] ) + midpoint num_windows = 9 window_height = np . int ( binary_img . shape [ 0 ] / num_windows ) nonzero = binary_img . nonzero ( ) nonzeroy = np . array ( nonzero [ 0 ] ) nonzerox = np . array ( nonzero [ 1 ] ) current_leftX = leftX_base current_rightX = rightX_base min_num_pixel = 50 win_left_lane = [ ] win_right_lane = [ ] window_margin = left_lane . window_margin for window in range ( num_windows ) : win_y_low = binary_img . shape [ 0 ] - ( window + 1 ) * window_height win_y_high = binary_img . shape [ 0 ] - window * window_height win_leftx_min = current_leftX - window_margin win_leftx_max = current_leftX + window_margin win_rightx_min = current_rightX - window_margin win_rightx_max = current_rightX + window_margin cv2 . rectangle ( out_img , ( win_leftx_min , win_y_low ) , ( win_leftx_max , win_y_high ) , ( 0 , 255 , 0 ) , 2 , ) cv2 . rectangle ( out_img , ( win_rightx_min , win_y_low ) , ( win_rightx_max , win_y_high ) , ( 0 , 255 , 0 ) , 2 , ) left_window_inds = ( ( nonzeroy >= win_y_low ) & ( nonzeroy <= win_y_high ) & ( nonzerox >= win_leftx_min ) & ( nonzerox <= win_leftx_max ) ) . nonzero ( ) [ 0 ] right_window_inds = ( ( nonzeroy >= win_y_low ) & ( nonzeroy <= win_y_high ) & ( nonzerox >= win_rightx_min ) & ( nonzerox <= win_rightx_max ) ) . nonzero ( ) [ 0 ] win_left_lane . append ( left_window_inds ) win_right_lane . append ( right_window_inds ) if len ( left_window_inds ) > min_num_pixel : current_leftX = np . int ( np . mean ( nonzerox [ left_window_inds ] ) ) if len ( right_window_inds ) > min_num_pixel : current_rightX = np . int ( np . mean ( nonzerox [ right_window_inds ] ) ) win_left_lane = np . concatenate ( win_left_lane ) win_right_lane = np . concatenate ( win_right_lane ) leftx = nonzerox [ win_left_lane ] lefty = nonzeroy [ win_left_lane ] rightx = nonzerox [ win_right_lane ] righty = nonzeroy [ win_right_lane ] out_img [ lefty , leftx ] = [ 255 , 0 , 0 ] out_img [ righty , rightx ] = [ 0 , 0 , 255 ] left_fit = np . polyfit ( lefty , leftx , 2 ) right_fit = np . polyfit ( righty , rightx , 2 ) left_lane . current_fit = left_fit right_line . current_fit = right_fit ploty = np . linspace ( 0 , binary_img . shape [ 0 ] - 1 , binary_img . shape [ 0 ] ) left_plotx = left_fit [ 0 ] * ploty ** 2 + left_fit [ 1 ] * ploty + left_fit [ 2 ] right_plotx = right_fit [ 0 ] * ploty ** 2 + right_fit [ 1 ] * ploty + right_fit [ 2 ] left_lane . prevx . append ( left_plotx ) right_line . prevx . append ( right_plotx ) if len ( left_lane . prevx ) > 10 : left_avg_line = smoothing ( left_lane . prevx , 10 ) left_avg_fit = np . polyfit ( ploty , left_avg_line , 2 ) left_fit_plotx = ( left_avg_fit [ 0 ] * ploty ** 2 + left_avg_fit [ 1 ] * ploty + left_avg_fit [ 2 ] ) left_lane . current_fit = left_avg_fit left_lane . allx , left_lane . ally = left_fit_plotx , ploty else : left_lane . current_fit = left_fit left_lane . allx , left_lane . ally = left_plotx , ploty if len ( right_line . prevx ) > 10 : right_avg_line = smoothing ( right_line . prevx , 10 ) right_avg_fit = np . polyfit ( ploty , right_avg_line , 2 ) right_fit_plotx = ( right_avg_fit [ 0 ] * ploty ** 2 + right_avg_fit [ 1 ] * ploty + right_avg_fit [ 2 ] ) right_line . current_fit = right_avg_fit right_line . allx , right_line . ally = right_fit_plotx , ploty else : right_line . current_fit = right_fit right_line . allx , right_line . ally = right_plotx , ploty left_lane . startx , right_line . startx = ( left_lane . allx [ len ( left_lane . allx ) - 1 ] , right_line . allx [ len ( right_line . allx ) - 1 ] , ) left_lane . endx , right_line . endx = left_lane . allx [ 0 ] , right_line . allx [ 0 ] left_lane . detected , right_line . detected = True , True measure_curvature ( left_lane , right_line ) return out_img
After applying calibration, thresholding, and a perspective transform to a road image,
 I have a binary image where the lane lines stand out clearly.
After applying calibration thresholding and a perspective transform to a road image I have a binary image where the lane lines stand out clearly .
"""
    #---------------------
    # After applying calibration, thresholding, and a perspective transform to a road image,
    # I have a binary image where the lane lines stand out clearly.
    # However, I still need to decide explicitly which pixels are part of the lines
    # and which belong to the left line and which belong to the right line.
    #
    # This lane line search is done using histogram and sliding window
    #
    # The sliding window implementation is based on lecture videos.
    #
    # This function searches lines from scratch, i.e. without using info from previous lines.
    # However, the search is not entirely a blind search, since I am using histogram information.
    #
    # Use Cases:
    #    - Use this function on the first frame
    #    - Use when lines are lost or not detected in previous frames
    #
    """ # I first take a histogram along all the columns in the lower half of the image # Create an output image to draw on and  visualize the result # Find the peak of the left and right halves of the histogram # These will be the starting point for the left and right lines # Choose the number of sliding windows # Set height of windows # Identify the x and y positions of all nonzero pixels in the image # Current positions to be updated for each window # Set minimum number of pixels found to recenter window # Create empty lists to receive left and right lane pixel indices # Step through the windows one by one # Identify window boundaries in x and y (and right and left) # Draw the windows on the visualization image # Identify the nonzero pixels in x and y within the window # Append these indices to the lists # If you found > minpix pixels, recenter next window on their mean position # Concatenate the arrays of indices # Extract left and right line pixel positions # Fit a second order polynomial to each # Generate x and y values for plotting # ax^2 + bx + c # Set detected=True for both lines
binary_img
left_lane
right_line