예제 #1
0
def show_hough_transform(image):
    h, theta, d = hough_line(canny(image))

    fig, ax = plt.subplots(1, 3, figsize=(15, 6))

    ax[0].imshow(image, cmap=cm.gray)
    ax[0].set_title('Input image')
    ax[0].set_axis_off()

    ax[1].imshow(
        np.log(1 + h),
        extent=[np.rad2deg(theta[-1]),
                np.rad2deg(theta[0]), d[-1], d[0]],
        cmap='gray',
        aspect=1 / 20)
    ax[1].set_title('Hough transform')
    ax[1].set_xlabel('Angles (degrees)')
    ax[1].set_ylabel('Distance (pixels)')

    ax[2].imshow(image, cmap=cm.gray)
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle)
        ax[2].plot((0, image.shape[1]), (y0, y1), '-r')
    ax[2].set_xlim((0, image.shape[1]))
    ax[2].set_ylim((image.shape[0], 0))
    ax[2].set_axis_off()
    ax[2].set_title('Detected lines')

    plt.tight_layout()
    return hough_line_peaks(h, theta, d)
예제 #2
0
def search_lines(blob,
                 angle_range,
                 npoints=1000,
                 min_distance=100,
                 min_angle=300,
                 threshold=None):

    thetas = np.linspace(np.deg2rad(angle_range[0]),
                         np.deg2rad(angle_range[1]), npoints)
    hspace, angles, distances = hough_line(blob, thetas)

    if threshold is not None:
        accum, angles, dists = hough_line_peaks(hspace,
                                                angles,
                                                distances,
                                                min_distance=min_distance,
                                                min_angle=min_angle,
                                                threshold=threshold *
                                                np.max(hspace))
    else:
        accum, angles, dists = hough_line_peaks(hspace,
                                                angles,
                                                distances,
                                                min_distance=min_distance,
                                                min_angle=min_angle)

    return accum, angles, dists
예제 #3
0
def test_hough_line_peaks_dist():
    img = np.zeros((100, 100), dtype=np.bool_)
    img[:, 30] = True
    img[:, 40] = True
    hspace, angles, dists = tf.hough_line(img)
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=5)[0]) == 2
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=15)[0]) == 1
def test_hough_line_peaks_dist():
    img = np.zeros((100, 100), dtype=np.bool_)
    img[:, 30] = True
    img[:, 40] = True
    hspace, angles, dists = tf.hough_line(img)
    with expected_warnings(['`background`']):
        assert len(tf.hough_line_peaks(hspace, angles, dists,
                                       min_distance=5)[0]) == 2
        assert len(tf.hough_line_peaks(hspace, angles, dists,
                                       min_distance=15)[0]) == 1
예제 #5
0
def test_hough_line_peaks_dist():
    img = np.zeros((100, 100), dtype=np.bool_)
    img[:, 30] = True
    img[:, 40] = True
    hspace, angles, dists = tf.hough_line(img)
    with expected_warnings(['`background`']):
        assert len(
            tf.hough_line_peaks(hspace, angles, dists, min_distance=5)[0]) == 2
        assert len(
            tf.hough_line_peaks(hspace, angles, dists,
                                min_distance=15)[0]) == 1
예제 #6
0
def skew_correction(img, edges, threshold=None, _save=False, _save_path="./"):
    # get HoughLinesMap
    h, theta, d = hough_line(edges)
    h_p, theta_p, d_p = None, None, None
    # get peaks of the HoughLinesMap

    if threshold is None:
        h_p, theta_p, d_p = hough_line_peaks(h, theta, d)
    else:
        h_p, theta_p, d_p = hough_line_peaks(h, theta, d, threshold=threshold)
    # get the histogram of the values ​​of the angles
    hist, bins = np.histogram(theta_p, 360)
    # the most probable angle is complementary to the skew
    c_skew = np.rad2deg(
        (bins[np.argmax(hist)] + bins[np.argmax(hist) + 1]) / 2)
    skew = 90 - c_skew if c_skew > 0 else -c_skew - 90

    # create a rotation matrix and rotate the image around its center
    matrix = cv2.getRotationMatrix2D((img.shape[1] / 2, img.shape[0] / 2),
                                     -skew, 1)
    dst = cv2.warpAffine(img, matrix, (img.shape[1], img.shape[0]),
                         cv2.INTER_NEAREST)

    if _save:
        _path_name = os.path.join(_save_path, "_skew_hough")
        if not os.path.isdir(_path_name):
            os.mkdir(_path_name)

        hough_lines_all = img.copy()
        hough_lines_true = img.copy()

        diag = np.sqrt(np.power(img.shape[0], 2) + np.power(img.shape[1], 2))

        for _, angle, dist in zip(*(h_p, theta_p, d_p)):
            a, b = np.cos(angle), np.sin(angle)
            x0, y0 = a * dist, b * dist
            x1 = int(x0 + diag * (-b))
            y1 = int(y0 + diag * (a))
            x2 = int(x0 - diag * (-b))
            y2 = int(y0 - diag * (a))
            cv2.line(hough_lines_all, (x1, y1), (x2, y2), (0, 255, 0), 4)
            if bins[np.argmax(hist)] <= angle <= bins[np.argmax(hist) + 1]:
                cv2.line(hough_lines_true, (x1, y1), (x2, y2), (0, 255, 0), 4)

        cv2.imwrite(os.path.join(_path_name, "pre_skew.jpg"), img)
        cv2.imwrite(os.path.join(_path_name, "post_skew.jpg"), dst)
        cv2.imwrite(os.path.join(_path_name, "hough_lines_all.jpg"),
                    hough_lines_all)
        cv2.imwrite(os.path.join(_path_name, "hough_lines_true.jpg"),
                    hough_lines_true)
    return dst, -np.deg2rad(skew)
예제 #7
0
def calculate_rotation(image):
    # sometimes we snag corners, by cropping the left and right 10% of the image we focus only on the
    # vertical bars formed by the structure
    height, width = image.shape
    crop = int(width * 0.1)
    cropped_image = image[:, crop: width - crop]
    # Find edges that have a strong vertical direction
    vertical_edges = sobel_v(cropped_image)
    # Separate out the areas where there is a large amount of vertically-oriented stuff
    segmentation = segment_edge_areas(vertical_edges)
    # Draw a line that follows the center of the segments at each point, which should be roughly vertical
    # We should expect this to give us four approximately-vertical lines, possibly with many gaps in
    # each line
    skeletons = skeletonize(segmentation)
    # Use the Hough transform to get the closest lines that approximate those four lines
    hough = transform.hough_line(skeletons, np.arange(-constants.FIFTEEN_DEGREES_IN_RADIANS,
                                                      constants.FIFTEEN_DEGREES_IN_RADIANS,
                                                      0.0001))
    # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0
    # being completely vertical
    # These angles correspond to the angles of the four sides of the channels, which we need to
    # correct for
    angles = [angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))]
    if not angles:
        raise ValueError("Image rotation could not be calculated. Check the images to see if they're weird.")
    else:
        # Get the average angle and convert it to degrees
        offset = sum(angles) / len(angles) * 180.0 / math.pi
        if offset > constants.ACCEPTABLE_SKEW_THRESHOLD:
            log.warn("Image is heavily skewed. Check that the images are valid.")
        return offset
예제 #8
0
def rotate_pic(pic):
    """
    rotate_pic finds the offset angle by measuring the grid with a Hough line transform. It then de-rotates by this amount
    """

    # for speed, only look at a 500x500 slice in the center of the image
    centercut = np.copy(
        pic[int(pic.shape[0] / 2.) - 500:int(pic.shape[0] / 2.) + 500,
            int(pic.shape[1] / 2.) - 500:int(pic.shape[1] / 2.) + 500, 0])

    # find the grid in the image by looking for brighter regions
    centermask = (centercut < 1) * (centercut > 0.8)

    h, theta, d = tf.hough_line(centermask,
                                theta=np.linspace(np.pi / 2 - 0.2,
                                                  np.pi / 2 + 0.2, 1000))
    _, angles, dist = tf.hough_line_peaks(h, theta, d)

    # plt.figure()
    # plt.imshow(centermask)
    # for ii in range(len(angles)):
    #     rho = dist[ii]
    #     theta = angles[ii]
    #
    #     y0 = (rho - 0 * np.cos(theta)) / np.sin(theta)
    #     y1 = (rho - centermask.shape[1] * np.cos(theta)) / np.sin(theta)
    #
    #     plt.plot([0,centermask.shape[0]],[y0,y1],'r-')

    angle = np.mean(angles * 180 / np.pi - 90)

    corrected_pic = tf.rotate(pic, angle, cval=1)

    return corrected_pic, angle
예제 #9
0
def test_hough_line_peaks_zero_input():
    # Test to make sure empty input doesn't cause a failure
    img = np.zeros((100, 100), dtype='uint8')
    theta = np.linspace(0, np.pi, 100)
    hspace, angles, dists = transform.hough_line(img, theta)
    h, a, d = transform.hough_line_peaks(hspace, angles, dists)
    assert_equal(a, np.array([]))
def compute_hough_transform(line_det_map1, line_det_map2, re_focus_angle=True):
    # focus theta for cuneiform horizontal lines
    theta_range = np.linspace(np.deg2rad(83), np.deg2rad(97), 50)
    # theta_range = np.linspace(np.deg2rad(-90) ,np.deg2rad(90), 180) # normal range

    # Classic straight-line Hough transform (usually angles from -90 to +90)
    h, theta, d = hough_line(line_det_map1, theta=theta_range)

    # debug
    # plt.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap='gray', aspect=1/1.5)
    # plt.show()

    # focus angle and re-run
    if re_focus_angle:
        # get peaks
        accum, angles, dists = hough_line_peaks(h,
                                                theta,
                                                d,
                                                min_distance=1,
                                                min_angle=16,
                                                num_peaks=50)

        # get median angle
        m_angle = np.median(np.rad2deg(angles))
        # modify theta
        theta_range = np.linspace(np.deg2rad(m_angle - 2),
                                  np.deg2rad(m_angle + 2), 50)
        theta_range2 = np.linspace(np.deg2rad(m_angle - 3),
                                   np.deg2rad(m_angle + 3), 50)
        # Classic straight-line Hough transform (usually angles from -90 to +90)
        h, theta, d = hough_line(line_det_map2, theta=theta_range)

    return h, theta, d, theta_range, theta_range2
예제 #11
0
def jet_detect(img, calibratemean, calibratestd, x):
    mean, std = image_stats(img)

    # compare mean & calibratemean
    if (mean < calibratemean * 0.8) or (mean > calibratemean * 1.2):
        print('no jet')

    for c in range(x):
        try:
            # binary = (img / (mean + 2 * std * 0.90 ** c)).astype(np.uint8)
            # binary = cv2.adaptiveThreshold(img, 1, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 50, 2)
            # binary = cv2.bitwise_not(imagem)
            # lines = cv2.HoughLines(binary, 1, np.radians(0.25), 30)
            # rho, theta = lines[0][0]

            binary = canny(img,
                           sigma=2,
                           use_quantiles=True,
                           low_threshold=0.9,
                           high_threshold=0.99)
            fig, (ax1, ax2) = plt.subplots(nrows=1,
                                           ncols=2,
                                           figsize=(8, 3),
                                           sharex=True,
                                           sharey=True)
            ax1.imshow(img, cmap=plt.cm.gray)
            ax2.imshow(binary, cmap=plt.cm.gray)
            plt.show()

            h, theta, d = hough_line(binary)
            accum, angles, ds = hough_line_peaks(h, theta, d, min_distance=2)
            print(accum)
            print(angles)
            print(ds)

            # if (theta > math.radians(45)) and (theta < math.radians(135)):
            # print('invalid jet')
            # if (get_jet_width(img, rho, theta) * pxsize > 0.1):
            #    print('invalid jet')
            # for rho, theta in lines[0]:
            # jetValid = true
            # if (theta > math.radians(70)):
            #     jetValid = False
# width = get_jet_width(binary, rho, theta)
# if (width > [x]):
#     jetValid = False
# if (jetValid == False):
# reject jet
        except Exception:
            print(c)
            continue
        else:
            # show binary image
            # cv2.imshow('binary', binary)
            # cv2.waitKey(0)
            # cv2.destroyAllWindows()
            # return rho, theta
            # return 0, 0
            return angles[0], ds[0]
    raise ValueError('unable to detect jet')
예제 #12
0
def get_orientation(image, debug=False):
    bin_image = (image > threshold_li(image)) * 1
    dilated = scipy.ndimage.morphology.binary_dilation(bin_image,
                                                       iterations=30)
    labeled, num_regions = mh.label(dilated)
    sizes = mh.labeled.labeled_size(labeled)
    mh.labeled.labeled_size(labeled)

    if len(sizes) > 2:
        too_small = np.where(sizes < np.flip(np.sort(sizes))[1])
        labeled = mh.labeled.remove_regions(labeled, too_small)
        labeled = (labeled / np.max(np.unique(labeled))).astype(np.int)
    skeleton = skeletonize(labeled)
    h, theta, d = hough_line(skeleton)
    origin = np.array((0, skeleton.shape[1]))
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle)
    gradient = (y0 - y1) / origin[1]
    if debug == False:
        return math.degrees(np.arctan(gradient))
    elif debug == True:
        f, ax = plt.subplots(figsize=(40, 20))
        plt.imshow(bin_image)
        plt.show()
        f, ax = plt.subplots(figsize=(40, 20))
        plt.imshow(dilated)
        plt.show()
        f, ax = plt.subplots(figsize=(40, 20))
        plt.imshow(skeleton)
        plt.show()
        return math.degrees(np.arctan(gradient))
예제 #13
0
 def calculate(self, image: np.ndarray, disk_size: int=9,
               mean_threshold: int=100, min_object_size: int=750) -> float:
     # Find edges that have a strong vertical direction
     vertical_edges = sobel_v(image)
     # Separate out the areas where there is a large amount of vertically-oriented stuff
     segmentation = self._segment_edge_areas(vertical_edges, disk_size, mean_threshold, min_object_size)
     # Draw a line that follows the center of the segments at each point, which should be roughly vertical
     # We should expect this to give us four approximately-vertical lines, possibly with many gaps in
     # each line
     skeletons = skeletonize(segmentation)
     # Use the Hough transform to get the closest lines that approximate those four lines
     hough = transform.hough_line(skeletons, np.arange(-constants.FIFTEEN_DEGREES_IN_RADIANS,
                                                       constants.FIFTEEN_DEGREES_IN_RADIANS,
                                                       0.0001))
     # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0
     # being completely vertical
     # These angles correspond to the angles of the four sides of the channels, which we need to
     # correct for
     angles = [angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))]
     if not angles:
         raise ValueError("Image rotation could not be calculated. Check the images to see if they're weird.")
     else:
         # Get the average angle and convert it to degrees
         offset = sum(angles) / len(angles) * 180.0 / math.pi
         if offset > constants.ACCEPTABLE_SKEW_THRESHOLD:
             log.warn("Image is heavily skewed. Check that the images are valid.")
         return offset
예제 #14
0
def detect_vertical_lines(data,
                          max_deviation_from_vertical=1,
                          row_begin=100,
                          row_end=-100,
                          min_distance=50):
    if "cropped_original" in data:
        image = data["cropped_original"]
    else:
        image = data["original"]

    image = np.gradient(image)[1]  #Vertical component of gradient
    image = image[row_begin:row_end, :]

    h, theta, d = hough_line(image)  #hough transform
    h[:, :90 -
      max_deviation_from_vertical] = 0  #Mask out areas that relate to non vertical lines
    h[:, 90 + max_deviation_from_vertical:] = 0

    h = np.log(1 + h)  #log scale for better visibility

    fx = []
    for _, angle, dist in zip(
            *hough_line_peaks(h, theta, d, min_distance=min_distance)):
        y0 = (dist) / np.sin(angle)  #y for x = 0
        y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(
            angle)  #y for x = image.shape[1]
        intercept = y0
        slope = (y1 - y0) / float(image.shape[1])
        fx.append([slope, intercept])

    data["houghlines"] = fx
    #ax.plot(x, intercept+x*slope,  '-r')
    return data
예제 #15
0
    def hough_transform(self, err=np.pi * 1 / 12, threshold=0.49, ks=3):
        # -------------------- scikit-image hough line transform --------------------
        theta = np.linspace(-np.pi * 1 / 4, np.pi * 3 / 4, 180)
        h, theta, distance = hough_line(self.edges_img, theta)
        hits, phi, rho = hough_line_peaks(h,
                                          theta,
                                          distance,
                                          min_distance=10,
                                          min_angle=50,
                                          threshold=threshold * h.max(),
                                          num_peaks=np.inf)
        lines = list(zip(phi, rho))
        # -------------------- OpenCV hough line transform --------------------
        # lines = cv2.HoughLines(self.edges_img.astype(np.uint8), 1, np.pi / 180, threshold).reshape(-1, 2)
        # lines = list(map(lambda x: tuple(x), lines[:, ::-1].tolist()))

        # -------------------- discriminate between vertical and horizontal lines --------------------
        self.lines = dict(v=[], h=[], o=[])
        for ix, (phi, _) in enumerate(lines):
            if abs(phi) < err or abs(phi - np.pi) < err:
                # vertical
                self.lines['v'].append(lines[ix])
            elif abs(phi - np.pi / 2) < err:
                # horizontal
                self.lines['h'].append(lines[ix])
            else:
                # irrelevant lines
                self.lines['o'].append(lines[ix])
        return self.lines
예제 #16
0
def hough_transform(binary):
    try:
        h, angles, d = hough_line(binary)
        res = hough_line_peaks(h,
                               angles,
                               d,
                               min_distance=1,
                               threshold=int(binary.shape[0] / 3))
    except Exception:
        raise ValueError('ERROR hough: not a jet')
    fig, axes = plt.subplots(1, 2)
    axes[0].imshow(binary)
    axes[1].imshow(binary)
    valid = []
    for _, theta, dist in zip(*res):
        jetValid = True
        if (theta < np.radians(-45)) or (theta > np.radians(45)):
            print('ERROR angle: not a jet')
            jetValid = False
        yint = dist / np.sin(theta)
        xint = np.tan(theta) * yint
        if (dist < 0) or (xint > binary.shape[1]):
            print('ERROR xint: not a jet')
            jetValid = False
        if (jetValid):
            y0 = (dist - 0 * np.cos(theta)) / np.sin(theta)
            y1 = (dist - binary.shape[1] * np.cos(theta)) / np.sin(theta)
            axes[1].plot((0, binary.shape[1]), (y0, y1), 'r')
            valid.append([theta, dist])
    axes[1].set_xlim((0, binary.shape[1]))
    axes[1].set_ylim((binary.shape[0], 0))
    return valid
예제 #17
0
def y_coordinate_extractor(img_arr):
    middle_y_coor = 0.5 * img_arr.shape[0]
    image = rgb2gray(img_arr)
    image = np.asarray(image > 0.5, dtype=np.float32)
    edges = filters.sobel_h(image)

    h, theta, d = hough_line(edges)
    upper_y = img_arr.shape[0]
    lower_y = 0
    thres_upp = img_arr.shape[0]
    thres_low = img_arr.shape[0]

    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle)

        avg = (y0 + y1) / 2
        if avg - middle_y_coor < thres_low and avg - middle_y_coor > 0:
            lower_y = avg
            thres_low = avg - middle_y_coor
        if middle_y_coor - avg < thres_upp and middle_y_coor - avg > 0:
            upper_y = avg
            thres_upp = middle_y_coor - avg

    return upper_y, lower_y
예제 #18
0
def filter_errors(image_folder, image_list, threshold=0.5, plot=False):
    """
    This function filters errenous images out of an the image_list. It is based
    on the notion that erroneous images show slightly of horizontal bands over
    the image. Hough line detection is used to detect these lines. The erroneous
    images are separated from the correct images by thresholding the standard
    deviation over the line anlges. 

    Parameters
    ----------
    image_folder : string
        path to folder where images are located
    image_list : list
        list of image filenames (strings)
    threshold : float
        threshold on standard deviation of angles, under this threshold the 
        images are considered erroneous. The default is 0.5.
    plot : boolean, optional
        if true the detected lines are plotted. Only for 1 image.

    Returns
    -------
    errors : list
        list with the erroneous image filenames (strings)
    fig : matplotlib Figure, only if plot = True
        figure with the lines detected in the image
        
    Tested
    ------
    bad_images = ['40_a.npy', '163_a.npy', '163_b.npy', '269_a.npy', '313_b.npy', '122_b.npy', '277_a.npy', '328_b.npy', '311_a.npy', '184_b.npy', '398_b.npy', '158_a.npy', '356_b.npy']
    good_images = ['240_a.npy', '451_b.npy', '558_b.npy','617_a.npy', '61_b.npy','267_b.npy','490_b.npy','243_b.npy', '685_b.npy','696_a.npy']
    good_images = ['318_a.npy', '527_b.npy', '100_a.npy', '100_b.npy', '101_a.npy', '101_b.npy', '102_a.npy', '102_b.npy', '103_a.npy', '103_b.npy', '104_a.npy', '104_b.npy', '105_a.npy','105_b.npy', '107_a.npy']

    """

    errors = []
    for image in image_list:
        im = np.load((os.path.join(image_folder, image)))[:, :, 0]

        # edge filter using canny algorithm
        edges = canny(im, sigma=6)
        # detect lines using hough transform
        test_angles = np.linspace(np.pi / 4, 7 * np.pi / 4 / 2, 360 / 4)
        h, theta, d = hough_line(edges, theta=test_angles)
        accum, angle, dist = hough_line_peaks(h, theta, d)

        if plot:
            assert len(image_list) == 1, "plot can only be used for 1 image"
            fig = plot_detectedlines(im, h, theta, d)

        # filter based on standard deviation of angles
        std = np.std(angle)
        print(std)
        if std < threshold:
            errors.extend([image])

    if plot:
        return errors, fig
    else:
        return errors
예제 #19
0
def manipExtract(image, thetaInit, method='standard'):
    if np.issubdtype(image.dtype, 'bool'):
        edge = image
    else:
        edge = canny_cv(image)

    rows, cols = image.shape

    h, theta, d = hough_line(edge,
                             theta=np.arange(thetaInit - .3, thetaInit + .3,
                                             .01))

    try:
        _, angle, dist = hough_line_peaks(h,
                                          theta,
                                          d,
                                          min_distance=1,
                                          num_peaks=1)
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
    except IndexError:  # i think this error is being thrown if the manipulator is not found?
        y0 = np.NaN
        y1 = np.NaN
        angle = np.NaN
        dist = np.NaN

    return y0, y1, angle, dist
예제 #20
0
def test_hough_line_peaks_zero_input():
    # Test to make sure empty input doesn't cause a failure
    img = np.zeros((100, 100), dtype='uint8')
    theta = np.linspace(0, np.pi, 100)
    hspace, angles, dists = transform.hough_line(img, theta)
    h, a, d = transform.hough_line_peaks(hspace, angles, dists)
    assert_equal(a, np.array([]))
예제 #21
0
def show_hough_transform(image, filename):
    low_dark = (0, 0, 0)
    high_dark = (50, 50, 50)
    only_dark = cv2.inRange(img, low_dark, high_dark)
    h, theta, d = hough_line(canny(only_dark)) # вычисляем преобразование Хаффа от границ изображения

    fig, ax = plt.subplots(1, 3, figsize=(15, 6))

    ax[0].imshow(only_dark, cmap=cm.gray)
    ax[0].set_title('Input image')
    ax[0].set_axis_off()

    ax[1].imshow(np.log(1 + h),
                 extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]],
                 cmap='gray', aspect=1/20)
    ax[1].set_title('Hough transform')
    ax[1].set_xlabel('Angles (degrees)')
    ax[1].set_ylabel('Distance (pixels)')

    ax[2].imshow(image, cmap=cm.gray)
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle)
        ax[2].plot((0, image.shape[1]), (y0, y1), '-r')
    ax[2].set_xlim((0, image.shape[1]))
    ax[2].set_ylim((image.shape[0], 0))
    ax[2].set_axis_off()
    ax[2].set_title('Detected lines')

    plt.tight_layout()
    plt.savefig(filename, bbox_inches='tight')
    plt.close(fig)
예제 #22
0
def deskew(image, edge=True):
    """Rotate image so that lines will be horizontally aligned.

    :param image: ndarray, 2D binarized image
    :return: ndarray, 2D deskewed image
    """
    rows, cols = image.shape
    image2 = canny(image, 5) if edge else image
    plt.imshow(image2, cmap='gray')
    plt.show()

    plt.imshow(image, cmap='gray')
    skew = 0
    _, angles, dists = hough_line_peaks(*hough_line(image2))
    for angle, dist in zip(angles, dists):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        plt.plot((0, cols), (y0, y1), '-r')
        skew += 90 + np.rad2deg(angle) if angle < 0 else np.rad2deg(angle) - 90
    skew /= angles.shape[0] if angles.shape[0] != 0 else 1
    print(skew)
    plt.xlim([0, cols])
    plt.ylim([rows, 0])
    plt.show()
    return rotate(image,
                  skew,
                  resize=True,
                  mode='constant',
                  cval=255,
                  preserve_range=True).astype(np.uint8)
예제 #23
0
def estimate_corner_lines(corner_region, corner_type, image_size):
    '''
    Estimate the line parameters for the edges of the given marker corner

    Inputs:
        - corner_region: regionprops for the given corner of the marker
        - corner_type: either 'BL' for bottom-left or 'TR' for top-right
        - image_size: tuple of original camera image's size
    Return:
        A list of length 2 holding the line parameters of horizontal and vertical edges of the marker
    '''
    corner_miny, corner_minx, corner_maxy, corner_maxx = corner_region.bbox

    # Pad the corner image to match the size of the entire image
    corner_image = util.pad(corner_region.intensity_image,
                            ((corner_miny, image_size[0] - corner_maxy),
                             (corner_minx, image_size[1] - corner_maxx)),
                            mode='constant',
                            constant_values=0)

    # Perform edge detection and Hough line transform
    corner_edges = feature.canny(corner_image, sigma=0)
    corner_hough = transform.hough_line(corner_edges,
                                        theta=np.linspace(
                                            -np.pi / 2, np.pi / 2, 360))
    corner_hough_peaks = list(
        zip(*transform.hough_line_peaks(
            *corner_hough, min_angle=45, num_peaks=2)))

    corner_lines = []

    def is_horizontal(peak):
        return abs(np.rad2deg(peak[1])) > 75

    def is_vertical(peak):
        return abs(np.rad2deg(peak[1])) <= 15

    # Categorized the detected lines as vertical or horizontal
    horizontal_peaks = list(filter(is_horizontal, corner_hough_peaks))
    vertical_peaks = list(filter(is_vertical, corner_hough_peaks))

    # Add the first estimated horizontal line
    if horizontal_peaks:
        corner_lines.append(horizontal_peaks[0])
    else:
        # Create a horizontal line from the bottom edge (if BL type) or top edge (if TR type)
        angle = np.pi / 2
        dist = corner_maxy if corner_type == 'BL' else corner_miny
        corner_lines.append((0, angle, dist))

    # Add the first estimated vertical line
    if vertical_peaks:
        corner_lines.append(vertical_peaks[0])
    else:
        # Create a vertical line from the left edge (if BL type) or right edge (if TR type)
        angle = 0.001
        dist = corner_minx if corner_type == 'BL' else corner_maxx
        corner_lines.append((0, angle, dist))

    return corner_lines
예제 #24
0
def is_arrow_check(img_edges):
	# Find lines using hough transform
	hspace, theta, dists = transform.hough_line(img_edges)

	# Extract lines
	lines = transform.hough_line_peaks(hspace, theta, dists, num_peaks=4)

	# Convert lines to list of lines
	lines = np.array(list(zip(*lines)), dtype=[('hspace', np.uint64), ('angle', np.float), ('dist', np.float)])

	if len(lines) != 4: return False

	lines = list(lines)
	dists = []
	while lines:
		found = False
		for i in range(1, len(lines)):
			if angle_difference(lines[0], lines[i]) < 0.1:
				# Found a line parallel to lines[0]
				dists.append(abs(lines[0][2] - lines[i][2]))
				del lines[i]
				del lines[0]
				found = True
				break
		if not found: break


	if len(dists) == 2 and abs(12.0 - dists[0]) < 5.0 and abs(12.0 - dists[1]) < 5.0:
		return True
	return False
예제 #25
0
    def get_limits(self, max_width_proportion=0.45):
        """Busca dos lineas paralelas que correspondan al bajalenguas

        Args:
            max_width_proportion (float): Maxima proporcion del alto de la
                imagen (considerada apaisada) que puede abarcar el ancho del
                bajalenguas.
        Returns:
            status (str): Una descripcion del resultado de la busqueda.
            limits ([angles, dists]): Contiene dos numpy arrays. El primero
                contiene dos angulos y el segundo dos distancias. Cada par de
                angulo-distancia define la recta de arriba y de abajo del bajalenguas.
        """
        max_angle_diff = 5. / 180 * np.pi
        im_width = np.amin(self.curr_im_lowres_g.shape)
        min_dist = int(1. / 6 * im_width)
        sigma = 3
        edges = canny(self.curr_im_lowres_g, sigma)
        while np.mean(edges) < 0.01:
            sigma = (sigma - 0.1)
            if sigma < 0:
                break
            edges = canny(self.curr_im_lowres_g, sigma)
        self.edges = edges
        h, theta, d = hough_line(edges)
        params = hough_line_peaks(h,
                                  theta,
                                  d,
                                  num_peaks=6,
                                  min_distance=min_dist)
        self.params = params
        # Normalizo al ancho de la imagen
        dists = params[2] / im_width
        angles = params[1]
        dangles = pairwise_distances(angles[:, None])
        dangles = np.dstack((dangles, np.abs(dangles - np.pi)))
        dangles = np.amin(dangles, 2)
        np.fill_diagonal(dangles, np.inf)
        i, j = np.unravel_index(np.argmin(dangles), dangles.shape)
        angles = np.array([angles[i], angles[j]])
        dists = np.array([dists[i], dists[j]])
        # Ordeno los bordes para que el de arriba quede primero
        norm_dist = np.sign(angles) * dists
        sort_idx = np.argsort(norm_dist)
        if i == j:
            status = 'Sin bajalenguas'
            limits = None
        elif dangles[i, j] > max_angle_diff:
            status = 'Sin bajalenguas - mal paralelismo'
            limits = None
        elif abs(np.diff(norm_dist)) > max_width_proportion:
            status = 'Sin bajalenguas - mal ratio'
            limits = None
        elif abs(angles[0]) < 20. / 180 * np.pi:
            status = 'Sin bajalenguas - mala inclinacion'
            limits = None
        else:
            status = 'Con bajalenguas'
            limits = [angles[sort_idx], dists[sort_idx]]
        return status, limits
def _determine_rotation_offset(image):
    """
    Finds rotational skew so that the sides of the central trench are (nearly) perfectly vertical.
    :param image:   raw image data in a 2D (i.e. grayscale) numpy array
    :type image:    np.array()
    """
    segmentation = create_vertical_segments(image)
    # Draw a line that follows the center of the segments at each point, which should be roughly vertical
    # We should expect this to give us four approximately-vertical lines, possibly with many gaps in each line
    skeletons = skeletonize(segmentation)
    # Use the Hough transform to get the closest lines that approximate those four lines
    hough = transform.hough_line(
        skeletons,
        np.arange(-Constants.FIFTEEN_DEGREES_IN_RADIANS,
                  Constants.FIFTEEN_DEGREES_IN_RADIANS, 0.0001))
    # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0 being
    # completely vertical
    # These angles correspond to the angles of the four sides of the channels, which we need to correct for
    angles = [
        angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))
    ]
    if not angles:
        log.warn(
            "Image skew could not be calculated. The image is probably invalid."
        )
        return 0.0
    else:
        # Get the average angle and convert it to degrees
        offset = sum(angles) / len(angles) * 180.0 / math.pi
        if offset > Constants.ACCEPTABLE_SKEW_THRESHOLD:
            log.warn(
                "Image is heavily skewed. Check that the images are valid.")
        return offset
예제 #27
0
def removeChessboard(img):

    # Get the major lines in the image
    edges, dilatedEdges, (h, theta, d) = findLines(img)

    # Create image with ones to fill inn lines
    lines = np.ones(img.shape[:2])

    # Add lines to image as zeroes
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle)
        x, y = line(int(y1), 0, int(y0), img.shape[1] - 1)
        x = np.clip(x, 0, img.shape[0] - 1)
        y = np.clip(y, 0, img.shape[1] - 1)
        lines[x, y] = 0

    # Remove border edges from image with all edges
    w = 4
    edges = np.pad(edges[w:img.shape[0] - w, w:img.shape[1] - w],
                   w,
                   mode='constant')

    # Erode the lines bigger, such that they cover the original lines
    lines = erosion(lines, square(13))

    # Remove major lines and close shape paths
    removedChessboard = closing(edges * lines, square(8))

    return removedChessboard
예제 #28
0
def align_hough(input_Image):
    #Converte a imagem do padrão RGB para uma imagem binária
    monImage = color.rgb2gray(input_Image)
    monImage = feature.canny(monImage)

    houghTransform, angles, d = transform.hough_line(monImage,
                                                     theta=np.linspace(
                                                         -np.pi / 2, np.pi / 2,
                                                         180))
    hTP, angles, d = transform.hough_line_peaks(houghTransform, angles, d)

    angles = np.rad2deg(angles) + 90
    angles = np.round(angles, 0)
    angles = angles.astype(int)

    angle = np.bincount(angles).argmax()

    if (angle > 90 and angle < 180):
        angle = angle + 180

    transformedImage = transform.rotate(input_Image, angle, resize=True)

    #Pós processamento para remoção das bordas resultantes da rotação
    transformedImage = border_remove(transformedImage)

    return transformedImage, angles[0]
예제 #29
0
def classic_hough_line(img):
    edges = canny(img, sigma=10, low_threshold=0.05, high_threshold=0.10)
    # Classic straight-line Hough transform
    h, theta, d = hough_line(edges, )
    # Generating figure 1
    fig, axes = plt.subplots(1, 3, figsize=(15, 6))
    ax = axes.ravel()
    ax[0].imshow(img, cmap=cm.gray)
    ax[0].set_title('Input image')
    ax[0].set_axis_off()
    ax[1].imshow(
        np.log(1 + h),
        extent=[np.rad2deg(theta[-1]),
                np.rad2deg(theta[0]), d[-1], d[0]],
        cmap=cm.gray,
        aspect=1 / 1.5)
    ax[1].set_title('Hough transform')
    ax[1].set_xlabel('Angles (degrees)')
    ax[1].set_ylabel('Distance (pixels)')
    ax[1].axis('image')
    ax[2].imshow(img, cmap=cm.gray)
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle)
        ax[2].plot((0, img.shape[1]), (y0, y1), '-r')
    ax[2].set_xlim((0, img.shape[1]))
    ax[2].set_ylim((img.shape[0], 0))
    ax[2].set_axis_off()
    ax[2].set_title('Detected lines')
    plt.tight_layout()
    plt.show()
예제 #30
0
def houghTransform(s, sThreshold):
    """
    DESCRIPTION:
    This function computes the hough transform, for determining the shock front.
    see: https://scikit-image.org/docs/dev/auto_examples/edges/plot_line_hough_transform.html

    INPUT:
    s           - the 2D density field ln(\rho/\rho_0)
    sThreshold  - the threshold for the field. Densities above this threshold
                will be used to identify the shock front

    OUTPUT:
    x       - x coordinate of the Hough transform
    y       - y coordinate of the Hough transform
    xMin    - x coordinate of the window around the shock front
    yMin    - y coordinate of the window around the shock front
    sMask   - the mask, s.max() * sThreshold (for checking)

    """

    print("Calculating the Hough Transform.")
    # Create a mask on s for detecting the ionisation front
    sMask = s > s.max() * sThreshold

    # run a hough transform on the masked density data
    dtheta = 0.05  # the d\theta around a vertical line approximation for the ion. front.
    # create a sample of test angles close to a vertical line
    tested_angles = np.linspace(np.pi + dtheta, np.pi - dtheta, 90)

    # run the Hough transform
    origin = np.array((0, sMask.shape[1]))  # define the origin coordinate
    h, theta, d = hough_line(sMask,
                             theta=tested_angles)  # define the H. transform

    # pick the most dominant line from the H. transform
    hspace, angle, dist = hough_line_peaks(h, theta,
                                           d)  # extract param. values
    y0, y1 = (dist[0] - origin * np.cos(angle[0])) / np.sin(angle[0])

    # pick out the cooridinates in the density field from the line and create a window
    x, y = sampleHough(origin, [y0, y1])
    xMin = x - windowSize
    xMax = x + windowSize

    # Just taking a single value at the for the window
    xMin = xMin[0]
    xMax = xMax[0]

    # Make sure the window size isn't larger than the actual data domain
    if xMin < 0:
        xMin = 0
    elif xMin > sMask.shape[0] - 1:
        xMin = sMask.shape[0] - 1
    # and for xMax too
    if xMax < 0:
        xMax = 0
    elif xMax > sMask.shape[0] - 1:
        xMax = sMask.shape[0] - 1

    return x, y, xMin, xMax, sMask
예제 #31
0
파일: task5a.py 프로젝트: niklasmh/ntnu
def removeChessboard(img):

    # Get the major lines in the image
    edges, dilatedEdges, (h, theta, d) = findLines(img)

    # Create image with ones to fill inn lines
    lines = np.ones(img.shape[:2])

    # Add lines to image as zeroes
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle)
        x, y = line(int(y1), 0, int(y0), img.shape[1] - 1)
        x = np.clip(x, 0, img.shape[0] - 1)
        y = np.clip(y, 0, img.shape[1] - 1)
        lines[x, y] = 0

    # Remove border edges from image with all edges
    w = 4
    edges = np.pad(edges[w:img.shape[0] - w, w:img.shape[1] - w], w, mode='constant')

    # Erode the lines bigger, such that they cover the original lines
    lines = erosion(lines, square(13))

    # Remove major lines and close shape paths
    removedChessboard = closing(edges * lines, square(8))

    return removedChessboard
예제 #32
0
def alignRodCellvertically(
        Image,
        ifbinary=False,
        thres=0.4,  #thres value for binary image
        plotting=False,  # plotting the detected rod-direction
        inverse=False):
    """
    automatically align rod-shaped cells vertically
    """
    #image = util.ReadImg(Imagename).astype(np.uint8)
    #grey = cv2.cvtColor(rod,cv2.COLOR_RGB2GRAY)
    if ifbinary:
        binaryimage = Image
    else:
        if inverse:
            dummy, binaryimage = cv2.threshold(
                cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY), 255 * thres, 255,
                cv2.THRESH_BINARY_INV)
        else:
            dummy, binaryimage = cv2.threshold(
                cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY), 255 * thres, 255,
                cv2.THRESH_BINARY)

    # detect the direction of rod using the hough line detection
    # note, the angle unit is radian (1 radian = 57.2958 degree)
    Hspace, Angle, Dist = transform.hough_line(binaryimage)

    # find the peaks in the hough space
    peaks = transform.hough_line_peaks(Hspace, Angle, Dist)
    if len(peaks[0]) > 1:
        raise RuntimeError(
            'More than 1 directions exist, plz use a image that contains only 1 direction'
        )

    angle = peaks[1][0]
    dist = peaks[2][0]

    #  now rotate the image based one the angle
    radianTodegree = 57.29

    rotatedImage = imutils.rotate(Image, angle * radianTodegree)
    if plotting:
        origin = np.array((0, binaryimage.shape[1]))
        line = (dist - origin * np.cos(angle)) / np.sin(angle)
        plt.subplot(1, 2, 1)
        plt.imshow(Image)
        plt.plot(origin, line, 'r-')

        plt.ylim([0, binaryimage.shape[1]])
        plt.xticks([])
        plt.yticks([])
        plt.title('detected directions')

        plt.subplot(1, 2, 2)
        plt.imshow(rotatedImage)
        plt.xticks([])
        plt.yticks([])
        plt.title('align vertically')

    return rotatedImage
예제 #33
0
def identify_based_on_lines(img_edges):
    # Find lines using hough transform
    hspace, theta, dists = transform.hough_line(img_edges)

    # Extract lines
    lines = transform.hough_line_peaks(hspace, theta, dists, num_peaks=10)

    # Convert lines to list of lines
    lines = np.array(list(zip(*lines)),
                     dtype=[('hspace', np.uint64), ('angle', np.float),
                            ('dist', np.float)])

    shape_likeness = np.zeros(Shape.count)
    for i in range(1, Shape.count):
        shape = Shape.iterator[i]
        if shape == Shape.CAKE:
            hval = 0.0
            if len(lines) >= 3:
                hval = abs(((lines[0][0] + lines[1][0]) * 0.5) - lines[2][0])
            if hval >= 5.0:
                shape_likeness[i] = 0.0
            else:
                shape_likeness[i] = 10.0
        else:
            shape_likeness[i] = abs(shape.line_count - len(lines))
    return shape_likeness
예제 #34
0
def test_hough_line_peaks_single_angle():
    # Regression test for gh-4814
    # This code snippet used to raise an IndexError
    img = np.random.random((100, 100))
    tested_angles = np.array([np.pi / 2])
    h, theta, d = transform.hough_line(img, theta=tested_angles)
    accum, angles, dists = transform.hough_line_peaks(h, theta, d, threshold=2)
예제 #35
0
def Hough(image, filter='Canny', sigma=3, show=False):
    '''
    Read in an image and get the peak Hough line

    Parameters:
        image: The image to be read
        filter: Set whether to use Canny (default) or Sobel edge detection
        sigma: Sensitivity for Canny
        show: boolean to show the plot Hough plot

    Return:
        max_peak: The horizon line corresponding to the max peak
        edges: the edges
    '''
    img_gray = color.rgb2gray(image) # Grayscale

    if (filter == 'Canny'):
        # Edge detection
        edges = feature.canny(img_gray, sigma=3) # Canny
    if (filter == 'Sobel'):
        edges = filters.sobel(img_gray) # Use Sobel

    # Hough transformation
    h, theta, d = hough_line(edges)

    # Get the max_peak
    max_peak = hough_line_peaks(h, theta, d, num_peaks=1)

    if(show):
        fig = plt.figure()
        plt.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]],
                   cmap=plt.cm.gray, aspect=1 / 1.5)

    return max_peak, edges
예제 #36
0
def test_hough_line_peaks_num():
    img = np.zeros((100, 100), dtype=np.bool_)
    img[:, 30] = True
    img[:, 40] = True
    hspace, angles, dists = transform.hough_line(img)
    assert len(transform.hough_line_peaks(hspace, angles, dists,
                                          min_distance=0, min_angle=0,
                                          num_peaks=1)[0]) == 1
예제 #37
0
파일: util.py 프로젝트: MK8J/PV_analysis
def align_with_boarder(image, sigma=1):

    edges = ft.canny(image, sigma=sigma)
    # edges = abs(fil.sobel_v(image))

    h, theta, d = tf.hough_line(edges)

    a, rot_angle, c = tf.hough_line_peaks(h, theta, d, min_distance=0)
    image = rotate(image, np.rad2deg(rot_angle[0]))

    return image
예제 #38
0
def test_hough_line_peaks():
    img = np.zeros((100, 150), dtype=int)
    rr, cc = line(60, 130, 80, 10)
    img[rr, cc] = 1

    out, angles, d = tf.hough_line(img)

    out, theta, dist = tf.hough_line_peaks(out, angles, d)

    assert_equal(len(dist), 1)
    assert_almost_equal(dist[0], 80.723, 1)
    assert_almost_equal(theta[0], 1.41, 1)
예제 #39
0
 def test_ideal_tfr(self):
     """Test if the ideal TFR can be found using the instantaneous frequency
     laws."""
     _, iflaw1 = fmlin(128, 0.0, 0.2)
     _, iflaw2 = fmlin(128, 0.3, 0.5)
     iflaws = np.c_[iflaw1, iflaw2].T
     tfr, _, _ = pproc.ideal_tfr(iflaws)
     tfr[tfr == 1] = 255
     tfr = tfr.astype(np.uint8)
     hspace, angles, dists = hough_line(tfr)
     for x in hough_line_peaks(hspace, angles, dists):
         self.assertEqual(len(x), 2)
예제 #40
0
def houghSides(bottle, edges, threshold, left):
    h, theta, d = hough_line(edges)
    accum = zip(*hough_line_peaks(h, theta, d))
    sortedAccum = sorted(accum, key=getKey, reverse=True)
    sortedAccumR = [sa for sa in sortedAccum if sa[2] > 200]
    sortedAccumL = [sa for sa in sortedAccum if sa[2] <= 200]

    if left:
        hpeak, angle, dist = sortedAccumL[0]
    else:
        hpeak, angle, dist in sortedAccumR[0]

    return (1, dist, angle)
예제 #41
0
def test_hough_line_peaks_ordered():
    # Regression test per PR #1421
    testim = np.zeros((256, 64), dtype=np.bool)

    testim[50:100, 20] = True
    testim[85:200, 25] = True
    testim[15:35, 50] = True
    testim[1:-1, 58] = True

    hough_space, angles, dists = tf.hough_line(testim)

    hspace, _, _ = tf.hough_line_peaks(hough_space, angles, dists)
    assert hspace[0] > hspace[1]
def check_door(image, Pw_corners, Pi_corners, door_edges,
               required_matching_ratio=0.7, verbose=0):
    """Check if door is closed."""
    results = {}

    image_sobel, image_edges = detect_edges(image)

    # Detect lines with Hough transform
    hough_accumulator, angles, dists = hough_line(image_edges)
    hspace, angles, dists = hough_line_peaks(
        hough_accumulator, angles, dists, threshold=150.0)

    # Estimate camera transformation by minimizing the distance between
    # calibration points
    params = optimize_transform(camera_params, Pw_corners, Pi_corners)
    if verbose >= 1:
        print("Parameters: %s" % np.round(params, 3))
    cam2world = transform_from(matrix_from_euler_xyz(params[:3]), params[3:6])
    kappa = params[-1]

    W2I = partial(world2image, cam2world=cam2world, kappa=kappa,
                  **camera_params)

    # Get edge pixels in vicinity of lines
    Pi_line_points = check_edge_is_on_line(image_edges, angles, dists)

    if len(Pi_line_points) == 0:
        if verbose >= 1:
            print("No lines detected, assume that door is closed")
        door_closed = True
    else:
        # Check how good the edges of the door projected to the image match
        # detected edge pixels that correspond to lines
        matchings = [check_line_is_edge(edge, Pi_line_points, cam2world, kappa,
                                        camera_params) for edge in door_edges]
        results["door_edges_in_image"] = [m[0] for m in matchings]
        ratios = np.array([m[1] for m in matchings])

        if verbose >= 1:
            print(("Matching ratios: " + ", ".join(["%.2f"] * len(ratios)))
                % tuple(100 * ratios))

        door_closed = np.any(ratios > required_matching_ratio)

    results["cam2world"] = cam2world
    results["Pi_line_points"] = Pi_line_points
    results["image_sobel"] = image_sobel
    results["image_edges"] = image_edges
    results["lines"] = (angles, dists)

    return door_closed, W2I, results
def test_hough_line_peaks_angle():
    img = np.zeros((100, 100), dtype=np.bool_)
    img[:, 0] = True
    img[0, :] = True

    hspace, angles, dists = tf.hough_line(img)
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1

    theta = np.linspace(0, np.pi, 100)
    hspace, angles, dists = tf.hough_line(img, theta)
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1

    theta = np.linspace(np.pi / 3, 4. / 3 * np.pi, 100)
    hspace, angles, dists = tf.hough_line(img, theta)
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2
    assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1
예제 #44
0
def test_example():
        
    # Construct toydata
    image = np.zeros((100, 100))
    idx = np.arange(25, 75)
    image[idx[::-1], idx] = 255
    image[idx, idx] = 255
    
    # Classic straight-line Hough transform  
    h, theta, d = hough_line(image)

    # plot
    plt.figure(figsize=(8, 4))

    plt.subplot(131)
    plt.imshow(image, cmap=plt.cm.gray)
    plt.title('Input image')

    plt.subplot(132)
    plt.imshow(np.log(1 + h),
               extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
                       d[-1], d[0]],
               cmap=plt.cm.gray, aspect=1/1.5)
    plt.title('Hough transform')
    plt.xlabel('Angles (degrees)')
    plt.ylabel('Distance (pixels)')

    plt.subplot(133)
    plt.imshow(image, cmap=plt.cm.gray)
    rows, cols = image.shape
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        plt.plot((0, cols), (y0, y1), '-r')
    plt.axis((0, cols, rows, 0))
    plt.title('Detected lines')
예제 #45
0
   def satellites(self,maskflag=8,det_nthresh=3.0,ngrowth=1,min_length=200,conv_sigma=2.0,angle_accuracy=1.0,min_distance=40,min_angle=5,threshold=None,num_peaks=np.inf,touch_edge=False,thresh_absolute=True,nmax=100):
      """
      maskflag: flag for satellite trails
      det_nthresh: relative threshold for detecting satellites
      ngrowth: dilation iterations for detections
      min_length: minimun lenght for satellites
      conv_sigma: convolution kernel to convolve the raw image
      angle_accuracy: the accurancy of caculating the theta angle of straight lines
      min_distance,min_angle,threshold,num_peaks: keywords in hough_line_peaks (skimage) 
      touch_edge: need satellites touch the image edge
      thresh_abolute: threshold is absolute not relative
      nmax: maximum lines to be detected
      """
      start=time.time()
      maskflag=maskflag | self.bad_flag
      if self.sky is None or self.sky_rms is None:
         raise AttributeError("get sky and skyrms first!")
      # convolve data with gaussian profile
      data_conv=self.data.copy()
      if self.mask is not None:
         data_conv[self.mask]=self.sky
      if conv_sigma is not None:
         data_conv=snd.filters.gaussian_filter(data_conv,sigma=conv_sigma)
      # detect signals
      gmask=data_conv - self.sky > self.sky_rms*det_nthresh
      # growth satellite trails by dilation operation
      if ngrowth >0: 
         struct=np.ones((3,3)).astype('int')
         gmask=snd.morphology.binary_dilation(gmask,struct,iterations=ngrowth)
      if self.mask is not None: 
         mask=gmask | (self.mask)
      else:
         mask=gmask.copy()
      #fits.writeto('gmask.fits',gmask.astype('uint8'),clobber=True)
      #fits.writeto('mask.fits',mask.astype('uint8'),clobber=True)
            
      # remove objects that are obviously not satellites
      labels,_=snd.label(mask)
      slices=snd.find_objects(labels)
      flags=np.zeros_like(self.data).astype('int')
      nr,nc=self.data.shape
      slcs=[]
      labs=[]
      for i,slc in enumerate(slices):
         ilabel=labels[slc]
         imask=mask[slc]
         igmask=gmask[slc]
         tmpmask=ilabel == i+1
         slc0,slc1=slc
         
         # remove objects not touch edge using raw data
         if touch_edge and (not (slc0.start==0 or slc0.stop==nr or slc1.start==0 or slc1.stop==nc)): 
            imask[tmpmask]=0
            igmask[tmpmask]=0
            ilabel[tmpmask]=0
            continue

         # remove objects that are small 
         size=ilabel.shape
         if np.max(size) < min_length: 
            imask[tmpmask]=0
            igmask[tmpmask]=0
            ilabel[tmpmask]=0
            continue

         # remove objects not touch edge using masked data
         if touch_edge:
            tmpdata=igmask.copy()
            tmpdata[~tmpmask]=0
            if not tmpdata.any(): continue
            tmpslc0,tmpslc1=snd.find_objects(tmpdata)[0]
            r0=slc0.start+tmpslc0.start; c0=slc1.start+tmpslc1.start
            r1=r0+tmpslc0.stop-tmpslc0.start; 
            c1=c0+tmpslc1.stop-tmpslc1.start; 
            if not (r0==0 or r1==nr or c0==0 or c1==nc):
               imask[tmpmask]=0
               igmask[tmpmask]=0
               ilabel[tmpmask]=0
               continue

         slcs.append(slc)
         labs.append(i+1)

      # no labels 
      if len(slcs) == 0: 
         print('No Satellite Found!')
         return [],[],[]

      # find satellites by using hough transform 
      t=np.linspace(-np.pi/2.0,np.pi/2.0,np.fix(180/angle_accuracy))
      h,theta,d=hough_line(mask,theta=t)
      print('hough max:',h.max())
      thres=None
      if threshold is not None: 
         if thresh_absolute: 
            thres=threshold
         else: 
            thres=threshold*h.max()
      else: 
         if thresh_absolute: 
            thres=3*min_length

      _,angles,dists = hough_line_peaks(h,theta,d, min_distance=min_distance, min_angle=min_angle, threshold=thres, num_peaks=num_peaks)
      print(angles,dists)
      # no labels 
      if len(angles) > nmax: 
         print('Too much lines, not to detect satellite!')
         return [],[],[]
      # refine the lines 
      smask=np.zeros_like(self.data).astype('bool')
      newdists=[] #np.zeros_like(dists)
      newangles=[] #np.zeros_like(dists)
      widths=[] #np.ones_like(angles)
      # angle is y+ -> left is plus   while y+ -> right is minus
      for i,(angle,dist) in enumerate(zip(angles,dists)):
         if np.abs(angle) >= np.pi/4.0:
            imask=mask.copy()
            data=data_conv.copy()
            angle1=angle
         else: 
            imask=mask.transpose()
            data=data_conv.transpose()
            if angle >=0:
               angle1=np.pi/2.0-angle
            else: 
               angle1=-np.pi/2.0-angle
               dist=-dist
         shape=data.shape
         lmask=np.zeros(shape).astype('bool')
         xx=np.arange(shape[1])
         yy=(dist-xx*np.cos(angle1))/np.sin(angle1)
         intyy=np.round(yy).astype('int')
         for j in np.arange(2*min_distance+1):
            jsub=j-min_distance
            tmpyy=intyy+jsub
            index=np.where((tmpyy >=0) & (tmpyy < shape[0]))[0]
            if len(index) == 0: continue
            tmpxx=xx[index]; tmpyy=tmpyy[index]
            lmask[tmpyy,tmpxx]=imask[tmpyy,tmpxx]
         if touch_edge:
            tmpmask1=lmask[0,:] | lmask[-1,:]
            tmpmask2=lmask[:,0] | lmask[:,-1]
            if (not tmpmask1.any()) and (not tmpmask2.any()): continue

         #fits.writeto('lmask.fits',lmask.astype('int16'),clobber=True)
         width=lmask.sum(axis=0)
         tmpmask=width>0
         if not tmpmask.any(): continue
         mwidth=np.ceil(np.median(width[tmpmask])).astype('int')
         if mwidth % 2 ==0: mwidth+=1
         if mwidth >= min_distance: continue
         #print('satellite widths:',mwidth)
         mdata=data.copy()
         mdata[~lmask]=-np.inf
         indmax=np.argmax(mdata,axis=0)
         tmpmask=(width > 0)
         if tmpmask.sum() == 0: continue
         yy1=indmax[tmpmask];xx1=xx[tmpmask]
         
         model_line=linear_model.RANSACRegressor(linear_model.LinearRegression())
         model_line.residual_threshold=min_distance
         model_line.fit(xx1.reshape((len(xx1),1)),yy1)
         """
         y=kx+b
         d=x*cos(t)+y*sin(t)
         y=-1/tan(t)*x+d/sin(t)
         k=-1/tan(t)
         b=d/sin(t)
         """
         k=model_line.estimator_.coef_[0]
         b=model_line.estimator_.intercept_
         if k==0: 
            angle1=np.pi/2.0
         else:
            angle1=np.arctan(-1/k)
         mdist1=b*np.sin(angle1)
         
         tmpangle=angle1
         tmpdist=mdist1
         if np.abs(angle) < np.pi/4.0:
            if angle1 >=0:
               tmpangle=np.pi/2.0-angle1
            else:
               tmpangle=-np.pi/2.0-angle1
               tmpdist=-mdist1
         newdists.append(tmpdist)
         newangles.append(tmpangle)
         widths.append(mwidth)

         lmask=np.zeros(shape).astype('bool')
         xx=np.arange(shape[1])
         yy=(mdist1-xx*np.cos(angle1))/np.sin(angle1)
         intyy=np.round(yy).astype('int')
         tflag=0
         for j in np.arange(mwidth):
            jsub=j-mwidth//2
            tmpyy=intyy+jsub
            index=np.where((tmpyy >0) & (tmpyy < shape[0]))[0]
            if len(index) == 0: continue
            tmpxx=xx[index]; tmpyy=tmpyy[index]
            lmask[tmpyy,tmpxx]=imask[tmpyy,tmpxx]
         if touch_edge:
            tmpmask1=lmask[0,:] | lmask[-1,:]
            tmpmask2=lmask[:,0] | lmask[:,-1]
            if (not tmpmask1.any()) and (not tmpmask2.any()): continue
         if np.abs(angle) >= np.pi/4.0:
            smask=smask | lmask
            #mask=mask & (~lmask)
         else:
            smask=smask | lmask.transpose()
            #mask=mask & (~lmask.transpose())
         
      flags=smask*maskflag
      if self.flags is not None:
         self.flags = np.bitwise_or(self.flags,flags)
      else:
         self.flags=flags
      if self.mask is not None:
         self.mask = self.mask | (flags > 0)
      else: 
         self.mask = flags > 0
      if self.weight is not None:
         tmpmask=flags>0
         self.weight[tmpmask]=0
      if len(newdists)==0: 
         print('no satellite found!')
      print(newdists,newangles,widths)
      print('satellite time: ',time.time()-start)
      return newdists,newangles,widths
예제 #46
0
def interest_region(image, plot_image = 0):
	# constant 
	th_x = 0.5
	th_y = 0.5
	lid_thickness = 680
	bot_thickness = 230
	side_thickness = 80

	rotation_limit = 2
	angle_u_lim = (90.0 + rotation_limit) / 180.0 * np.pi	
	angle_d_lim = (90.0 - rotation_limit) / 180.0 * np.pi
	
	#Grayscale Conversion and Edge Detection
	if(len(image.shape)>2):
		image = rgb2gray(image)
	img_edge =  canny(image, sigma = 3)
	
	#Image Rotation
	h, theta, d = hough_line(img_edge)
	h_peak, theta_peak, d_peak = hough_line_peaks(h, theta, d)	
	
	theta_rotation = theta[np.where(np.absolute(theta_peak)<=angle_u_lim)]
	theta_rotation = theta_rotation[np.where(np.absolute(theta_rotation)>=angle_d_lim)]

	if(theta_rotation.size):
		rotate_angle = np.pi/2-np.absolute(np.mean(theta_rotation))
		img_rotate = rotate(img_edge,rotate_angle*180)

	#rectangular region selection
	index = np.where(img_rotate>0)

	[hy,b] = np.histogram(index[0],100)
	by = (b[0:(len(b)-1)]+b[1:len(b)])/2
	[hx,b] = np.histogram(index[1],100)
	bx = (b[0:(len(b)-1)]+b[1:len(b)])/2
	
	temp = by[np.where(hy>=th_y*np.mean(hy))]
	if(len(temp)>0):
		bottom = np.amin(temp)
		top = np.amax(temp)	
	else:
		bottom = 450
		top = 1500

	temp = bx[np.where(hx>=th_x*np.mean(hx))]
    
	if(len(temp)>0):		
		left = np.amin(temp)+lid_thickness
		right = np.amax(temp)-bot_thickness
		if (right <= left):
			left = np.amin(temp)+int(lid_thickness/2)
			right = np.amax(temp)+int(lid_thickness/2)
	else:
		left = 1700
		right = 3600-bot_thickness

        bottom = bottom + side_thickness
        top = top - side_thickness
        
        #print [bottom,top,left,right];
	image_rotation = rotate(image,rotate_angle*180)	
	
	interest_image = image_rotation[bottom:top,left:right];
	
	if(plot_image == 1):
		fig, ax = plt.subplots(2,3)
		ax[0,0].imshow(image,cmap=plt.cm.gray)
		ax[0,0].set_title('Original Image')
		ax[0,1].imshow(img_edge,cmap=plt.cm.gray)
		ax[0,1].set_title('Canny Endge Detection')
		ax[0,2].imshow(image, cmap=plt.cm.gray)
		rows, cols = image.shape
		for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
    			y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
    			y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
    			ax[0,2].plot((0, cols), (y0, y1),'-r')
		ax[0,2].axis((0, cols, rows, 0))
		ax[0,2].set_title('Detected lines')
		ax[0,2].set_axis_off()
		ax[1,0].imshow(img_rotate,cmap=plt.cm.gray)
		ax[1,0].set_title('Image Edge after Rotation')
		ax[1,1].scatter(index[1],index[0])
		ax[1,1].set_aspect('equal')
		ax[1,1].set_title('Pixel Axises Histogram')
		divider = make_axes_locatable(ax[1,1])
		axHistx = divider.append_axes("top", 1.2, pad=0.1, sharex=ax[1,1])
		axHisty = divider.append_axes("right", 1.2, pad=0.1, sharey=ax[1,1])
		# make some labels invisible
		plt.setp(axHistx.get_xticklabels() + axHisty.get_yticklabels(),visible=False)
		# now determine nice limits by hand:
		axHistx.hist(index[1], bins=bx)
		axHistx.axhline(y=th_y*np.mean(hy),c="red",linewidth=2,zorder=0)
		axHisty.hist(index[0], bins=by, orientation='horizontal')
		axHisty.axvline(x=th_x*np.mean(hx),c="red",linewidth=2,zorder=0)
		#axHistx.axis["bottom"].major_ticklabels.set_visible(False)
		for tl in axHistx.get_xticklabels():
    			tl.set_visible(False)
		axHistx.set_yticks([0, 400, 800, 1200])
		#axHisty.axis["left"].major_ticklabels.set_visible(False)
		for tl in axHisty.get_yticklabels():
    			tl.set_visible(False)
		axHisty.set_xticks([0, 400, 800, 1200])
		ax[1,2].imshow(interest_image,cmap=plt.cm.gray)
		ax[1,2].set_title('Edge Detection')	
		plt.show()
		#"""
	return [interest_image,[bottom,top,left,right],rotate_angle*180]
예제 #47
0
    h, theta, d = hough_line(image)

    fig, ax = plt.subplots(1, 3, figsize=(6, 3.5))

    # Original image
    ax[0].imshow(image, cmap=plt.cm.gray)
    ax[0].axis('off')

    # Display Hough transform
    ax[1].imshow(np.log(1 + h),
                 extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
                         d[-1], d[0]],
                 cmap=plt.cm.gray, aspect=1 / 1.5)
    ax[1].axis('off')

    # Original image with lines detected
    ax[2].imshow(image, cmap=plt.cm.gray)
    rows, cols = image.shape
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d, min_angle=5,
                                                min_distance=5)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        ax[2].plot((0, cols), (y0, y1), '-r')
    ax[2].axis((0, cols, rows, 0))
    ax[2].axis('off')

    # Save a nice figure
    fig.tight_layout()
    fig.subplots_adjust(wspace=0, left=0, right=1, top=1, bottom=0)
    fig.savefig('./hough_lines.png', dpi=300)
def main():
    if len(sys.argv) != 2:
        print "ERROR! Correct usage is:"
        print "\tpython test_hough_transform.py [gps_point_collection.dat]"
        return
    
    GRID_SIZE = 500
    results = np.zeros((GRID_SIZE, GRID_SIZE), np.float)
    
    # Load GPS points
    with open(sys.argv[1], "rb") as fin:
        point_collection = cPickle.load(fin)
    
    for pt in point_collection:
        y_ind = math.floor((pt[0] - const.RANGE_SW[0]) / (const.RANGE_NE[0] -const.RANGE_SW[0]) * GRID_SIZE)
        x_ind = math.floor((pt[1] - const.RANGE_NE[1]) / (const.RANGE_SW[1] -const.RANGE_NE[1]) * GRID_SIZE)
        results[x_ind, y_ind] += 1.0
        if results[x_ind, y_ind] >= 64:
            results[x_ind, y_ind] = 63
    results /= np.amax(results)
    
    thresholded_results = np.zeros((GRID_SIZE, GRID_SIZE), np.bool)
    
    THRESHOLD = 0.02
    for i in range(0, GRID_SIZE):
        for j in range(0, GRID_SIZE):
            if results[i,j] >= THRESHOLD:
                thresholded_results[i,j] = 1
            else:
                thresholded_results[i,j] = 0
    box_size = 50
    
    x_ind = random.randint(box_size, GRID_SIZE-box_size)                
    y_ind = random.randint(box_size, GRID_SIZE-box_size)
    
#    x_ind = 217
#    y_ind = 175

    
    test_img = thresholded_results[(x_ind-box_size):(x_ind+box_size),\
                                     (y_ind-box_size):(y_ind+box_size)]
                
    h, theta, d = hough_line(test_img)
#    fig = plt.figure(figsize=(30,16))
#    ax = fig.add_subplot(121, aspect='equal')
#    ax.imshow(test_img, cmap=plt.cm.gray)
#    
#    ax = fig.add_subplot(122)
#    img = skeletonize(test_img)
#    ax.imshow(img, cmap=plt.cm.gray)
#    plt.show()
#    fig = plt.figure(figsize=(30,16))
#    ax = fig.add_subplot(131, aspect='equal')
#    ax.imshow(test_img, cmap=plt.cm.gray)
#    
#    ax = fig.add_subplot(132)
#    ax.imshow(np.log(1+h),
#               extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]],
#               cmap=plt.cm.gray, aspect=1/1.5)
#    ax = fig.add_subplot(133)
#    ax.imshow(test_img, cmap=plt.cm.gray)
#    rows, cols = test_img.shape
#    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
#        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
#        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
#        ax.plot((0, cols), (y0, y1), '-r')
#    ax.set_xlim([0, cols])
#    ax.set_ylim([rows, 0])
#    plt.show()
    
    print "point at: ", x_ind, y_ind
    coords = [(y_ind-box_size, x_ind-box_size), (y_ind+box_size, x_ind-box_size),\
              (y_ind+box_size, x_ind+box_size), (y_ind-box_size, x_ind+box_size), \
              (y_ind-box_size, x_ind-box_size)]
    
    bound_box = Polygon(coords)
    patch = PolygonPatch(bound_box, fc='none', ec='red')
    fig = plt.figure(figsize=(30,16))
    rows, cols = thresholded_results.shape
    ax = fig.add_subplot(121, aspect='equal')
    ax.imshow(thresholded_results, cmap=plt.cm.gray)
    ax.add_patch(patch)
    ax.set_xlim([0, cols])
    ax.set_ylim([rows, 0])
    
    ax = fig.add_subplot(122)
    ax.imshow(test_img, cmap=plt.cm.gray)
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d, min_distance=8)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        ax.plot((0, cols), (y0, y1), '-r')
    rows, cols = test_img.shape
    ax.set_xlim([0, cols])
    ax.set_ylim([rows, 0])
    plt.show()
예제 #49
0
    def _find_edges(self, image):
        """
        Takes as input an RGB chessboard image and computes the Hough lines
        and intersections between them corresponding to the edges of the 64
        squares. The function returns a tuple whose first element is a
        numpy array with shape (N,2) where N is the number of
        intersections between the Hough lines. The second element is a list
        of tuples (intensity, abs(theta), abs(r)) describing the significant
        Hough lines (in polar coordinates).
        """

        image_canny = self.compute_canny_image(image)
        h, theta, d = hough_line(image_canny)

        '''
        Small trick: we expect to get something like 11 horizontal lines and
        another 11 vertical lines: indeed the chessboard is made of 8 rows and
        8 columns, i.e. 9 lines, plus 2 lines for the edges of the chessboard.
        So, to help hough_line_peaks() let's set the min. distance expected
        between two lines to the size of the image divided by 11.
        TODO: better way? Might cause problems if the board does not fit the
        whole frame...
        '''
        min_distance = int(floor(image.shape[1] / 11))

        hough_peaks = hough_line_peaks(h, theta, d, min_distance=min_distance,
                                       threshold=40)  # TODO adjust threshold

        # separate horizontal from vertical lines
        vertical_lines = []
        horizontal_lines = []

        '''
        In Hough space, straight lines are parametrized by coefficients (r,θ):
        r = x.cos(θ) + y.sin(θ) ; (r,θ) are the polar coordinates of
        the point on the line which lies closest to the origin, with r being
        either positive or negative, and -π/2 ≤ θ ≤ π/2   (with π/2 ≈ 1.57)

        A horizontal line is therefore one with θ=±π/2, and a vertical line is
        one with θ=0.
        Also, two lines are parallel iif they have the same θ (mod π/2).

        Finally, in scikit-image, keep in mind that the orientation is :

                                O----->
                                |     (x axis)
                                |
                                V (y axis)

        (where the origin is the top-left corner of our image)
        And as a consequence, positive angles are counted from the X axis toward
        the Y axis (i.e. "clockwise").
        '''

        for intensity, theta, r in zip(*hough_peaks):
            if np.fabs(theta) < self.LINE_ANGLE_TOLERANCE:
                vertical_lines.append((intensity, theta, r))
            elif np.fabs(np.fabs(theta) - math.pi / 2) < self.LINE_ANGLE_TOLERANCE:
                horizontal_lines.append((intensity, theta, r))

        '''
        Only keep the 9 most significant lines of each direction and sort
        them by absolute radius, to return edges from top to bottom,
        and left to right. We sort by *absolute* radius because horizontal
        lines can be parametrized either as 'θ=π/2, r>0' or 'θ=-π/2, r<0'
        '''
        for i,lines in enumerate((horizontal_lines, vertical_lines)):
            lines.sort(reverse=True)   # reverse-sort by intensity
            del lines[9:]              # only keep the 9 first
            lines.sort(key=lambda entry: np.fabs(entry[2]))  # sort by absolute radius

        '''
        Now let's find the intersections of these 18 lines.
        We are solving the following system:
        r1 = x.cos(θ1) + y.sin(θ1)  and  r2 = x.cos(θ2) + y.sin(θ2)   for (x,y)
        The non-degenerate solution is:
        x = (r1.sin(θ2) - r2.sin(θ1))/D  and  y = (r2.cos(θ1) - r1.cos(θ2))/D
        with D = cos(θ1).sin(θ2) - sin(θ1).cos(θ2) = sin(θ2-θ1)
        We can see that this holds only if θ1 ≠ θ2, i.e. only if the lines are
        not parallel (which makes sense!).
        '''
        intersections = []
        for _, theta1, r1 in horizontal_lines:
            for _, theta2, r2 in vertical_lines:
                # don't attempt to compute the intersection if the lines are parallel
                denum = np.sin(theta2 - theta1)
                if denum < self.ANGLE_EPSILON:
                    continue
                x_inter = (r1 * np.sin(theta2) - r2 * np.sin(theta1)) / denum
                y_inter = (r2 * np.cos(theta1) - r1 * np.cos(theta2)) / denum
                # register this intersection iff. it is *inside* the image
                if 0 < x_inter < image.shape[1] and 0 < y_inter < image.shape[0]:
                    intersections.append((x_inter, y_inter))

        hough_lines = horizontal_lines + vertical_lines
        # TODO we don't check that we get 9x9 intersections...

        '''
        Since the horizontal and vertical lines have been sorted by increasing
        value of |r|, the intersections are now sorted from top-left to bottom-right
        corner of the image.
        '''
        return np.array(intersections), hough_lines
예제 #50
0
파일: extract.py 프로젝트: mitbal/pemilu
def extract_corner_hough(patch):
    """ Extract four corner points using Hough transform

    """
    # Find the lines that makes the boundary box using Hough Transform
    h, theta, d = hough_line(patch)

    # Divide the hough space for searching different horizontal and vertical lines
    hcroph = h[:, 0:30]
    rows, cols = patch.shape

    # Search all vertical lines in the hough parameter space
    # It is located in the middle, when theta is near zero
    vlf = []
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d, min_angle=9)):
        x0 = (dist - 0 * np.sin(angle)) / np.cos(angle)
        x1 = (dist - rows * np.sin(angle)) / np.cos(angle)
        vlf += [((x0, 0), (x1, rows))]

    # Likewise previous operation, but with horizontal lines
    # Located at the left, when theta is near minus 90 degree
    hlf = []
    for _, angle, dist in zip(*hough_line_peaks(hcroph, theta, d, min_angle=9)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        hlf += [((0, y0), (cols, y1))]

    if DEBUG:
        plt.subplot(142)
        plt.title('hough line')
        plt.imshow(patch, cmap='gray')
        for i in xrange(len(vlf)):
            plt.plot((vlf[i][0][0], vlf[i][1][0]), (vlf[i][0][1], vlf[i][1][1]), 'r-')
        for i in xrange(len(hlf)):
            plt.plot((hlf[i][0][0], hlf[i][1][0]), (hlf[i][0][1], hlf[i][1][1]), 'r-')
        plt.axis([0, cols, rows, 0])

    # Search the rightmost and leftmost vertical lines
    vl = []
    vl += [search_closest_line(vlf, [(0, 0), (0, rows)])]
    vl += [search_closest_line(vlf, [(cols, 0), (cols, rows)])]

    # Search the topmost and bottommost horizontal lines
    hl = []
    hl += [search_closest_line(hlf, [(0, 0), (cols, 0)])]
    hl += [search_closest_line(hlf, [(0, rows), (cols, rows)])]

    if len(hl) < 2 or len(vl) < 2:
        print 'Not enough lines found'
        return []

    points = [vl[0], vl[-1], hl[0], hl[-1]]
    # Check for error
    for i in xrange(4):
        for j in xrange(i + 1, 4):
            if points[i] == points[j]:
                print 'Error Line'
                return []

    # Calculate the intersection between pair of vertical and horizontal lines
    # The line is defined by using two points.
    p1 = calc_intersection(vl[0][0][0], vl[0][0][1], vl[0][1][0], vl[0][1][1], hl[0][0][0], hl[0][0][1], hl[0][1][0],
                           hl[0][1][1])
    p2 = calc_intersection(vl[0][0][0], vl[0][0][1], vl[0][1][0], vl[0][1][1], hl[1][0][0], hl[1][0][1], hl[1][1][0],
                           hl[1][1][1])
    p3 = calc_intersection(vl[1][0][0], vl[1][0][1], vl[1][1][0], vl[1][1][1], hl[0][0][0], hl[0][0][1], hl[0][1][0],
                           hl[0][1][1])
    p4 = calc_intersection(vl[1][0][0], vl[1][0][1], vl[1][1][0], vl[1][1][1], hl[1][0][0], hl[1][0][1], hl[1][1][0],
                           hl[1][1][1])

    # Find the nearest point for each corner
    dim = patch.shape
    corners = [(0, 0), (0, dim[0]), (dim[1], dim[0]), (dim[1], 0)]
    points = [p1, p2, p3, p4]
    dest_points = [[] for x in range(4)]
    for i in xrange(4):
        dest_points[i] = search_closest_points(corners[i], points)

    epsilon = 1e-10
    for i in xrange(4):
        for j in xrange(i + 1, 4):
            if calc_distance(dest_points[i], dest_points[j]) < epsilon:
                print 'Error point'
                return []

    return dest_points
예제 #51
0
파일: hough.py 프로젝트: th13/libyoga
def lines(base, test):
    image1 = imread(base, flatten=True)
    image2 = imread(test, flatten=True)

    # Angles
    a1 = []
    a2 = []

    group1_a1 = []
    group2_a1 = []
    group3_a1 = []

    # # Plot 1 -> Base Case (original)
    # print "Plot 1"
    h, theta, d = hough_line(image1)
    rows, cols = image1.shape

    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        degree = degrees(angle)
        a1.append(degree)
        if degree < -45 or degree > 45:
            if degree < -85 or degree > 85:
                pos_horizontal = []
                neg_horizontal = []
                if degree > 0:
                    pos_horizontal.append(90 - degree)
                elif degree <= 0:
                    neg_horizontal.append(-(degree + 90))
        elif degree > -45 and degree < 0:
            if degree > -40 and degree < -25:
                group2_a1.append(degree)
        elif degree > 0 and degree < 45:
            if degree > 15 and degree < 40:
                group3_a1.append(degree)

    if len(pos_horizontal) == 0:
        avg_horizontal = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal))
    elif len(neg_horizontal) == 0:
        avg_horizontal = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal))
    else:
        avg_neg = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal))
        avg_pos = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal))
        avg_horizontal = (avg_pos + avg_neg)/2

    print "BASE HORIZONTAL: " + str(avg_horizontal)

    h1, theta1, d1 = hough_line(image2)
    rows, cols = image2.shape

    group1_a2 = []
    group2_a2 = []
    group3_a2 = []
    for _, angle, dist in zip(*hough_line_peaks(h1, theta1, d1)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        degree = degrees(angle)
        a2.append(degree)
        if degree < -45 or degree > 45:
            if degree < -85 or degree > 85:
                pos_horizontal_user = []
                neg_horizontal_user = []
                if degree > 0:
                    pos_horizontal_user.append(90 - degree)
                elif degree <= 0:
                    neg_horizontal_user.append(-(degree + 90))
        elif degree > -45 and degree < 0:
            if degree > -40 and degree < -25:
                group2_a2.append(degree)
        elif degree > 0 and degree < 45:
            if degree > 15 and degree < 40:
                group3_a2.append(degree)
        a2.append(degrees(angle))

    if len(pos_horizontal_user) == 0:
        avg_horizontal_user = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user))
    elif len(neg_horizontal_user) == 0:
        avg_horizontal_user = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user))
    else:
        avg_neg = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user))
        avg_pos = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user))
        avg_horizontal_user = (avg_pos + avg_neg)/2

    avg_down = -1
    avg_up =-1

    base_down = reduce(lambda x, y: x + y, group2_a1) / float(len(group2_a1))
    if len(group2_a2) > 0:
        avg_down = reduce(lambda x, y: x + y, group2_a2) / float(len(group2_a2))
    base_up = reduce(lambda x, y: x + y, group3_a1) / float(len(group3_a1))
    if len(group3_a2) > 0:
        avg_up = reduce(lambda x, y: x + y, group3_a2) / float(len(group3_a2))

    print "USER HORIZONTAL: " + str(avg_horizontal_user)

    print "BASE DOWN: " + str(base_down)
    print "USER DOWN: " + str(avg_down)

    print "BASE UP: " + str(base_up)
    print "USER UP: " + str(avg_up)

    base_down = float(base_down)
    base_up = float(base_up)
    user_down = float(avg_down)
    user_up = float(avg_up)

    # Calculate score
    score = 10

    lost_down = abs(base_down - avg_down)
    lost_up = abs(base_up - avg_up)
    lost_horizontal = abs(avg_horizontal - avg_horizontal_user)

    SCORE_FACTOR = 3             # equals max angle of error / 10
    score1 = lost_down / SCORE_FACTOR
    score2 = lost_up / SCORE_FACTOR
    score3 = lost_horizontal / SCORE_FACTOR

    neg_points = (score1 + score2 + score3) / 3.0
    score -= neg_points
    print "SCORE: " + str(score)
    return score
예제 #52
0
def skimage_transform():
    #Source: http://scikit-image.org/docs/dev/auto_examples/plot_line_hough_transform.html
    image = data.imread('../images/window.jpg', True)

    # Classic straight-line Hough transform
    h, theta, d = hough_line(image)

    fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 4))

    ax1.imshow(image, cmap=plt.cm.gray)
    ax1.set_title('Input image')
    ax1.set_axis_off()

    ax2.imshow(np.log(1 + h),
               extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]),
               d[-1], d[0]],
               cmap=plt.cm.gray,
               aspect=1/1.5)
    ax2.set_title('Hough transform')
    ax2.set_xlabel('Angles (degrees)')
    ax2.set_ylabel('Distance (pixels)')
    ax2.axis('image')

    ax3.imshow(image, cmap=plt.cm.gray)
    rows, cols = image.shape
    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        ax3.plot((0, cols), (y0, y1), '-r')
    ax3.axis((0, cols, rows, 0))
    ax3.set_title('Detected lines')
    ax3.set_axis_off()




    # Line finding, using the Probabilistic Hough Transform

    image = data.camera()
    edges = canny(image,2, 1, 25)
    lines = probabilistic_hough_line(edges, threshold=10, line_length=100, line_gap=3)

    fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True)

    ax1.imshow(image, cmap=plt.cm.gray)
    ax1.set_title('Input image')
    ax1.set_axis_off()
    ax1.set_adjustable('box-forced')

    ax2.imshow(edges, cmap=plt.cm.gray)
    ax2.set_title('Canny edges')
    ax2.set_axis_off()
    ax2.set_adjustable('box-forced')

    ax3.imshow(edges * 0)

    for line in lines:
        p0, p1 = line
        ax3.plot((p0[0], p1[0]), (p0[1], p1[1]))

    ax3.set_title('Probabilistic Hough')
    ax3.set_axis_off()
    ax3.set_adjustable('box-forced')


    image = data.imread('../images/AMFGP02lg.jpg', True)
    edges = canny(image, 2, 1, 25)
    lines = probabilistic_hough_line(edges, threshold=10, line_length=100, line_gap=3)

    fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True)

    ax1.imshow(image, cmap=plt.cm.gray)
    ax1.set_title('Input image')
    ax1.set_axis_off()
    ax1.set_adjustable('box-forced')

    ax2.imshow(edges, cmap=plt.cm.gray)
    ax2.set_title('Canny edges')
    ax2.set_axis_off()
    ax2.set_adjustable('box-forced')

    ax3.imshow(edges * 0)

    for line in lines:
        p0, p1 = line
        ax3.plot((p0[0], p1[0]), (p0[1], p1[1]))

    ax3.set_title('Probabilistic Hough')
    ax3.set_axis_off()
    ax3.set_adjustable('box-forced')


    image = data.imread('../images/window.jpg', True)
    edges = canny(image, 2, 1, 25)
    lines = probabilistic_hough_line(edges, threshold=10, line_length=100, line_gap=1)

    fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True)

    ax1.imshow(image, cmap=plt.cm.gray)
    ax1.set_title('Input image')
    ax1.set_axis_off()
    ax1.set_adjustable('box-forced')

    ax2.imshow(edges, cmap=plt.cm.gray)
    ax2.set_title('Canny edges')
    ax2.set_axis_off()
    ax2.set_adjustable('box-forced')

    ax3.imshow(edges * 0)

    for line in lines:
        p0, p1 = line
        ax3.plot((p0[0], p1[0]), (p0[1], p1[1]))

    ax3.set_title('Probabilistic Hough')
    ax3.set_axis_off()
    ax3.set_adjustable('box-forced')


    plt.show()
예제 #53
0
between_fields = logical_and(field_area, logical_not(field_mask))

# Find the roads and separate the fields
# Separate out into smaller blocks
print('Separating Fields in image')
for stride in [100, 200, 400]:  # pixels
    num_row_strides = int_(between_fields.shape[0]/stride)
    num_col_strides = int_(between_fields.shape[1]/stride)
    r_stride = int_(between_fields.shape[0]/num_row_strides)
    c_stride = int_(between_fields.shape[1]/num_col_strides)

    for r in range(num_row_strides+1):
        for c in range(num_col_strides+1):
            h, theta, d = hough_line(between_fields[r*r_stride:(r+1)*r_stride, c*c_stride:(c+1)*c_stride])
            threshold = 0  #0.0005*max(h)
            h, theta, d = hough_line_peaks(h, theta, d, min_distance=20, threshold=threshold)
            for n in range(len(theta)):
                if abs(theta[n]) < 0.1 or abs(theta[n]) > ((pi/2) - 0.1):
                    draw_hough_line(field_mask[r*r_stride:(r+1)*r_stride, c*c_stride:(c+1)*c_stride], d[n], theta[n])


# do a few small openings
field_mask = binary_opening(field_mask, rectangle(1, 5))
field_mask = binary_opening(field_mask, rectangle(5, 1))
imsave(fname_template.format('segmented_fields', 'png'), field_mask)

# Label fields
field_mask = label(field_mask, 4, 0) + 1
remove_small_objects(field_mask, 100, 1, True)
field_props = regionprops(field_mask)
예제 #54
0
파일: hough.py 프로젝트: th13/libyoga
def lines(base, test):
    """
    Reads two images of yoga poses and compares them.
    """
    image1 = imread(base, flatten=True)
    image2 = imread(test, flatten=True)

    # Angles
    a1 = []
    a2 = []

    group1_a1 = []
    group2_a1 = []
    group3_a1 = []
    # Generate figure and 2 axes from matplotlib
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))

    # # Plot 1 -> Base Case (original)
    # print "Plot 1"
    h, theta, d = hough_line(image1)
    ax1.imshow(image1, cmap=plt.cm.get_cmap('gray'))
    rows, cols = image1.shape

    for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        degree = degrees(angle)
        a1.append(degree)
        if degree < -45 or degree > 45:
            if degree < -85 or degree > 85:
                pos_horizontal = []
                neg_horizontal = []
                if degree > 0:
                    pos_horizontal.append(90 - degree)
                elif degree <= 0:
                    neg_horizontal.append(-(degree + 90))
                ax1.plot((0, cols), (y0, y1), '-r')
        elif degree > -45 and degree < 0:
            if degree > -40 and degree < -25:
                group2_a1.append(degree)
                ax1.plot((0, cols), (y0, y1), '-r')
        elif degree > 0 and degree < 45:
            if degree > 15 and degree < 40:
                group3_a1.append(degree)
                ax1.plot((0, cols), (y0, y1), '-r')

    ax1.axis((0, cols, rows, 0))
    ax1.set_title('Detected lines')
    ax1.set_axis_off()
    if len(pos_horizontal) == 0:
        avg_horizontal = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal))
    elif len(neg_horizontal) == 0:
        avg_horizontal = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal))
    else:
        avg_neg = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal))
        avg_pos = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal))
        avg_horizontal = (avg_pos + avg_neg)/2

    print "BASE HORIZONTAL: " + str(avg_horizontal)
    # print group2_a1
    # print group3_a1

    # Plot 2 -> Test Case (submission)
    # print "\nPlot 2"
    h1, theta1, d1 = hough_line(image2)
    ax2.imshow(image2, cmap=plt.cm.gray)
    rows, cols = image2.shape

    group1_a2 = []
    group2_a2 = []
    group3_a2 = []
    for _, angle, dist in zip(*hough_line_peaks(h1, theta1, d1)):
        y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
        y1 = (dist - cols * np.cos(angle)) / np.sin(angle)
        degree = degrees(angle)
        a2.append(degree)
        if degree < -45 or degree > 45:
            if degree < -85 or degree > 85:
                pos_horizontal_user = []
                neg_horizontal_user = []
                if degree > 0:
                    pos_horizontal_user.append(90 - degree)
                elif degree <= 0:
                    neg_horizontal_user.append(-(degree + 90))
                ax2.plot((0, cols), (y0, y1), '-r')
        elif degree > -45 and degree < 0:
            if degree > -40 and degree < -25:
                group2_a2.append(degree)
                ax2.plot((0, cols), (y0, y1), '-r')
        elif degree > 0 and degree < 45:
            if degree > 15 and degree < 40:
                group3_a2.append(degree)
                ax2.plot((0, cols), (y0, y1), '-r')
        a2.append(degrees(angle))
        # ax2.plot((0, cols), (y0, y1), '-r')

    if len(pos_horizontal_user) == 0:
        avg_horizontal_user = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user))
    elif len(neg_horizontal_user) == 0:
        avg_horizontal_user = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user))
    else:
        avg_neg = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user))
        avg_pos = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user))
        avg_horizontal_user = (avg_pos + avg_neg)/2

    print "USER HORIZONTAL: " + str(avg_horizontal_user)
    # print sorted(a2, key=float)
    # print group2_a2
    # print group3_a2
    avg_down = -1
    avg_up =-1
    
    base_down = reduce(lambda x, y: x + y, group2_a1) / float(len(group2_a1))
    if len(group2_a2) > 0:
        avg_down = reduce(lambda x, y: x + y, group2_a2) / float(len(group2_a2))
    base_up = reduce(lambda x, y: x + y, group3_a1) / float(len(group3_a1))
    if len(group3_a2) > 0:
        avg_up = reduce(lambda x, y: x + y, group3_a2) / float(len(group3_a2))

    print "BASE DOWN: " + str(base_down)
    print "USER DOWN: " + str(avg_down)

    print "BASE UP: " + str(base_up)
    print "USER UP: " + str(avg_up)

    ax2.axis((0, cols, rows, 0))
    ax2.set_title('Detected lines')
    ax2.set_axis_off()

    plt.show()
    return a1, a2
ax = axes.ravel()

ax[0].imshow(image, cmap=cm.gray)
ax[0].set_title('Input image')
ax[0].set_axis_off()

ax[1].imshow(np.log(1 + h),
             extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]],
             cmap=cm.gray, aspect=1/1.5)
ax[1].set_title('Hough transform')
ax[1].set_xlabel('Angles (degrees)')
ax[1].set_ylabel('Distance (pixels)')
ax[1].axis('image')

ax[2].imshow(image, cmap=cm.gray)
for _, angle, dist in zip(*hough_line_peaks(h, theta, d)):
    y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
    y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle)
    ax[2].plot((0, image.shape[1]), (y0, y1), '-r')
ax[2].set_xlim((0, image.shape[1]))
ax[2].set_ylim((image.shape[0], 0))
ax[2].set_axis_off()
ax[2].set_title('Detected lines')

plt.tight_layout()
plt.show()

# Line finding using the Probabilistic Hough Transform
image = data.camera()
edges = canny(image, 2, 1, 25)
lines = probabilistic_hough_line(edges, threshold=10, line_length=5,
예제 #56
0
import sys

from scipy.ndimage import io, uniform_filter
from skimage import transform
from skimage import color

from src.image_preprocess.PeakDetector import generate_green_map

__author__ = "Kern"

if len(sys.argv) < 2:
    raise ValueError("Usage:", sys.argv[0], " Missing some argument to indicate input files")
path = sys.argv[1]

image_input = io.imread(path)
image = uniform_filter(image_input)
image = generate_green_map(image)

image_grey = color.rgb2gray(image)

hspace, angles, dists = transform.hough_line(image_grey)
hspace, angles, dists = transform.hough_line_peaks(hspace, angles, dists)
print(hspace, angles, dists)
예제 #57
0
파일: skew_detect.py 프로젝트: kakul/Alyn
    def determine_skew(self, img_file):

        img = io.imread(img_file, as_grey=True)
        edges = canny(img, sigma=self.sigma)
        h, a, d = hough_line(edges)
        _, ap, _ = hough_line_peaks(h, a, d, num_peaks=self.num_peaks)

        if len(ap) == 0:
            return {"Image File": img_file, "Message": "Bad Quality"}

        absolute_deviations = [self.calculate_deviation(k) for k in ap]
        average_deviation = np.mean(np.rad2deg(absolute_deviations))
        ap_deg = [np.rad2deg(x) for x in ap]

        bin_0_45 = []
        bin_45_90 = []
        bin_0_45n = []
        bin_45_90n = []

        for ang in ap_deg:

            deviation_sum = int(90 - ang + average_deviation)
            if self.compare_sum(deviation_sum):
                bin_45_90.append(ang)
                continue

            deviation_sum = int(ang + average_deviation)
            if self.compare_sum(deviation_sum):
                bin_0_45.append(ang)
                continue

            deviation_sum = int(-ang + average_deviation)
            if self.compare_sum(deviation_sum):
                bin_0_45n.append(ang)
                continue

            deviation_sum = int(90 + ang + average_deviation)
            if self.compare_sum(deviation_sum):
                bin_45_90n.append(ang)

        angles = [bin_0_45, bin_45_90, bin_0_45n, bin_45_90n]
        lmax = 0

        for j in range(len(angles)):
            l = len(angles[j])
            if l > lmax:
                lmax = l
                maxi = j

        if lmax:
            ans_arr = self.get_max_freq_elem(angles[maxi])
            ans_res = np.mean(ans_arr)

        else:
            ans_arr = self.get_max_freq_elem(ap_deg)
            ans_res = np.mean(ans_arr)

        data = {
            "Image File": img_file,
            "Average Deviation from pi/4": average_deviation,
            "Estimated Angle": ans_res,
            "Angle bins": angles}

        if self.display_output:
            self.display(data)

        if self.plot_hough:
            self.display_hough(h, a, d)
        return data