Example #1
0
def get_all_hough_lines(image, min_angle, max_angle, min_separation_distance,
                        min_separation_angle):

    angles = np.deg2rad(np.arange(min_angle, max_angle, 0.5))
    hough, angles, distances = hough_line(image, angles)

    Debug.save_image("hough", "accumulator", normalize(hough))

    _, peak_angles, peak_distances = \
      hough_line_peaks(hough, angles, distances,
                       num_peaks=150,
                       threshold=0.2*np.amax(hough),
                       min_distance=min_separation_distance,
                       min_angle=min_separation_angle)

    lines = [
        get_line_endpoints_in_image(image, angle, radius)
        for angle, radius in zip(peak_angles, peak_distances)
    ]

    if Debug.active:
        peak_angle_idxs = [
            np.where(angles == angle)[0][0] for angle in peak_angles
        ]
        peak_rho_idxs = [
            np.where(distances == distance)[0][0]
            for distance in peak_distances
        ]
        peak_coords = zip(peak_rho_idxs, peak_angle_idxs)
        peaks = np.zeros(hough.shape)
        for coord in peak_coords:
            peaks[coord] = 1
        Debug.save_image("hough", "accumulator_peaks", peaks)

    if Record.active:
        # Thought get_max_theta_idx might be a useful way to filter
        # real meanlines from spurious meanlines, but it's not
        # reliable when the image is saturated with incorrect
        # meanlines. Filtering lines based on the ROI angle
        # was more effective.

        # max_theta_idx = get_max_theta_idx(hough)
        # Record.record("theta_mode", angles[max_theta_idx])

        # in radians
        average_meanline_angle = np.mean(peak_angles)
        std_deviation_meanline_angle = np.std(peak_angles)

        Record.record("average_meanline_angle",
                      float("%.4f" % average_meanline_angle))
        Record.record("std_deviation_meanline_angle",
                      float("%.4f" % std_deviation_meanline_angle))

    return lines
Example #2
0
def get_max_theta_idx(hough):
    '''
  Returns the column (theta) of the hough transform with the
  most above-threshold bins.

  '''
    thresh_hough = threshold_hough(hough, 0.2 * np.amax(hough))
    Debug.save_image("hough", "thresholded_accumulator",
                     normalize(thresh_hough))
    # find the column with the most above-threshold bins
    sum_thresh_hough = np.sum(thresh_hough, axis=0)
    max_theta_idx = np.argmax(sum_thresh_hough)
    return max_theta_idx
def detect_meanlines(masked_image, corners, scale=1):
    padding = PARAMS["trace-spacing"](scale) / 2

    timeStart("bound image")
    # effectively shrink the roi by a distance **padding**
    top_bound = padding + np.amax(
        [corners["top_left"][1], corners["top_right"][1]])
    bottom_bound = -padding + np.amin(
        [corners["bottom_left"][1], corners["bottom_right"][1]])
    left_bound = padding + np.amax(
        [corners["bottom_left"][0], corners["top_left"][0]])
    right_bound = -padding + np.amin(
        [corners["top_right"][0], corners["bottom_right"][0]])

    # mask all image values outside of this shrunken roi
    bounded_image = masked_image.copy()
    bounded_image[:top_bound, :] = ma.masked
    bounded_image[bottom_bound:, :] = ma.masked
    bounded_image[:, :left_bound] = ma.masked
    bounded_image[:, right_bound:] = ma.masked
    timeEnd("bound image")

    Debug.save_image("meanlines", "bounded_image", bounded_image.filled(0))

    timeStart("threshold image")
    black_and_white_image = otsu_threshold_image(bounded_image)
    timeEnd("threshold image")

    Debug.save_image("meanlines", "thresholded_image", black_and_white_image)

    timeStart("remove small objects")
    filtered_image = remove_small_objects(black_and_white_image,
                                          PARAMS["small-object-size"](scale))
    timeEnd("remove small objects")

    Debug.save_image("meanlines", "filtered_image", filtered_image)

    timeStart("get hough lines")
    roi_top_angle = np.rad2deg(
        points_to_rho_theta(corners["top_left"], corners["top_right"])[1])
    angle_padding = 2  # degrees
    min_angle = roi_top_angle - angle_padding
    max_angle = roi_top_angle + angle_padding
    min_separation_distance = int((2.0 / 3) * PARAMS["trace-spacing"](scale))
    lines = get_all_hough_lines(
        filtered_image,
        min_angle=min_angle,
        max_angle=max_angle,
        min_separation_distance=min_separation_distance,
        min_separation_angle=5)
    timeEnd("get hough lines")

    print "found %s meanlines" % len(lines)
    Record.record("num_meanlines", len(lines))

    if Debug.active:
        debug_image = gray2rgb(np.copy(masked_image))
        line_coords = [
            skidraw.line(line[0][1], line[0][0], line[1][1], line[1][0])
            for line in lines
        ]
        for line in line_coords:
            rr, cc = line
            mask = (rr >= 0) & (rr < debug_image.shape[0]) & (cc >= 0) & (
                cc < debug_image.shape[1])
            debug_image[rr[mask], cc[mask]] = [1.0, 0, 0]
        Debug.save_image("meanlines", "meanlines", debug_image)

    return lines