def abs_sobel_thresh(img, orient='x', sobel_kernel=3, thresh=(0, 255)):
    thresh_min, thresh_max = thresh

    # Convert to grayscale
    gray = rgb_to_gray(img)

    # Take the derivative in x or y given orient = 'x' or 'y'
    if orient == 'x':
        sobel = cv2.Sobel(gray, cv2.CV_64F, 1, 0)
    elif orient == 'y':
        sobel = cv2.Sobel(gray, cv2.CV_64F, 0, 1)

    # Take the absolute value of the derivative or gradient
    sobel = np.absolute(sobel)

    # Scale to 8-bit (0 - 255) then convert to type = np.uint8
    sobel = np.uint8(255 * sobel / np.max(sobel))

    # Create a mask of 1's where the scaled gradient magnitude
    # is > thresh_min and < thresh_max
    binary_output = np.zeros_like(sobel)
    binary_output[(sobel >= thresh_min) & (sobel <= thresh_max)] = 1

    # Return this mask as your binary_output image
    return binary_output
def calibrate_camera():

    for i, filepath in enumerate(images_glob):
        # Load image
        img = rgb_image(filepath)

        # Convert image to grayscale
        gray = rgb_to_gray(img)

        # Find chessboard corners for image
        ret, corners = cv2.findChessboardCorners(gray, chessboard_shape, None)

        # Create an object points array
        cols, rows = chessboard_shape
        objp = np.zeros((cols * rows, 3), np.float32)
        objp[:,:2] = np.mgrid[0:cols, 0:rows].T.reshape(-1, 2)

        if ret == True:
            objpoints.append(objp)
            imgpoints.append(corners)

        corners_img = cv2.drawChessboardCorners(img, (9,6), corners, ret)
        plt.imsave("./camera_cal/corners{:02d}.jpg" .format(i+1), corners_img)
        #plt.pause(0.5)

    # Use the object points and image points to calibrate a camera
    _, mtx, dist, _, _ = cv2.calibrateCamera(objpoints, imgpoints, image_shape, None, None)

    # Save the calibration data for use later
    save_camera_calibration(output_file, mtx, dist)
def calibrate():
    # List of images to be used for calibration
    images_glob = glob.glob("images/calibration/calibration*.jpg")

    # Shape of the calibration images
    image_shape = rgb_image(images_glob[0]).shape[1::-1]

    # Number of columns and rows for the chessboard
    chessboard_shape = (9, 6)

    # Where to save the calibration data
    output_file = "./calibration.pkl"

    objpoints = []
    imgpoints = []

    for filepath in images_glob:
        # Load image
        img = rgb_image(filepath)

        # Convert image to grayscale
        gray = rgb_to_gray(img)

        # Find chessboard corners for image
        pattern_was_found, corners = cv2.findChessboardCorners(
            gray, chessboard_shape, None)

        # Create an object points array
        cols, rows = chessboard_shape
        objp = np.zeros((cols * rows, 3), np.float32)
        objp[:, :2] = np.mgrid[0:cols, 0:rows].T.reshape(-1, 2)

        if pattern_was_found:
            objpoints.append(objp)
            imgpoints.append(corners)

    # Use the object points and image points to calibrate a camera
    _, mtx, dist, _, _ = cv2.calibrateCamera(objpoints, imgpoints, image_shape,
                                             None, None)

    # Save the calibration data for use later
    save_calibration_data(output_file, mtx, dist)
def dir_thresh(img, sobel_kernel=3, thresh=(0, np.pi / 2)):
    # Convert to grayscale
    gray = rgb_to_gray(img)

    # Take the gradient in x and y separately
    sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=sobel_kernel)
    sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=sobel_kernel)

    # Take the absolute value of the x and y gradients
    sobel_x = np.absolute(sobel_x)
    sobel_y = np.absolute(sobel_y)

    # Use np.arctan2(abs_sobely, abs_sobelx) to calculate the direction of the gradient
    direction = np.arctan2(sobel_y, sobel_x)

    # Create a binary mask where direction thresholds are met
    binary_output = np.zeros_like(direction)
    binary_output[(direction >= thresh[0]) & (direction <= thresh[1])] = 1

    # Return this mask as your binary_output image
    return binary_output
def mag_thresh(img, sobel_kernel=3, mag_thresh=(0, 255)):
    # Convert to grayscale
    gray = rgb_to_gray(img)

    # Take the gradient in x and y separately
    sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=sobel_kernel)
    sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=sobel_kernel)

    # Calculate the magnitude
    sobel_xy = np.sqrt(sobel_x**2 + sobel_y**2)

    # Scale to 8-bit (0 - 255) and convert to type = np.uint8
    sobel_xy = np.uint8(255 * sobel_xy / np.max(sobel_xy))

    # Create a binary mask where mag thresholds are met
    binary_output = np.zeros_like(sobel_xy)
    binary_output[(sobel_xy >= mag_thresh[0])
                  & (sobel_xy <= mag_thresh[1])] = 1

    # Return this mask as your binary_output image
    return binary_output