示例#1
0
def hough_circle_detector(
    image: ImageImpl,
    threshold: int = 0.4,
    min_radius: int = 10,
    max_radius: int = 40,
    steps: int = 100,
    high_threshold: float = 75,
    low_threshold: float = 35,
) -> ImageImpl:

    img = Image.fromarray(image.to_rgb().get_array())
    img = img.resize((300, 200), Image.ANTIALIAS)
    image = ImageImpl(np.array(img))

    border_image = border_detection.canny_detection(image, 3, 10,
                                                    high_threshold,
                                                    low_threshold, 10)

    edge_pixels = np.where(
        border_image.get_array()[..., 0] == constants.MAX_PIXEL_VALUE)

    rmin = min_radius
    rmax = max_radius
    points = []
    for r in range(rmin, rmax + 1):
        for t in range(steps):
            points.append((r, int(r * cos(2 * pi * t / steps)),
                           int(r * sin(2 * pi * t / steps))))

    coordinates = list(zip(edge_pixels[0], edge_pixels[1]))
    acc = defaultdict(int)

    for y, x in coordinates:
        for r, dx, dy in points:
            a = x - dx
            b = y - dy
            acc[(a, b, r)] += 1

    circles = []
    iterator = sorted(acc.items(), key=lambda i: -i[1])
    for k, v in iterator:
        x, y, r = k
        if v / steps >= threshold and all(
            (x - xc)**2 + (y - yc)**2 > rc**2 for xc, yc, rc in circles):
            print(v / steps, x, y, r)
            circles.append((x, y, r))

    result = image.to_rgb()

    img = Image.fromarray(result.get_array())
    draw_result = ImageDraw.Draw(img)
    for x, y, r in circles:
        draw_result.ellipse((x - r, y - r, x + r, y + r),
                            outline=(255, 0, 0, 0))

    result = ImageImpl(np.array(img))
    return result
示例#2
0
def susan_detection(a_img: ImageImpl, threshold: int, low_filter: float,
                    high_filter: float, color: int) -> ImageImpl:
    """
    :param a_img:
    :param kernel_size:
    :param threshold:
    :return:
    """
    # circ_kernel = circular_kernel(7)
    circ_kernel = np.array([
        [0, 0, 1, 1, 1, 0, 0],
        [0, 1, 1, 1, 1, 1, 0],
        [1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1],
        [0, 1, 1, 1, 1, 1, 0],
        [0, 0, 1, 1, 1, 0, 0],
    ])

    original = ImageImpl(a_img.get_array())
    a_img.apply_filter(
        circ_kernel,
        lambda m: _calculate_c_for_susan(m, circ_kernel, threshold))
    # a_img.array = np.uint8(a_img.array > 0.75)

    border_img = np.uint8(a_img.array > low_filter)
    b_img = border_img - np.uint8(a_img.array > high_filter)
    border_img = np.zeros((border_img.shape[0], border_img.shape[1], 3))
    # because we only have 3 channels
    color = color % 3
    border_img[:, :, color] = b_img[:, :, 0]

    border_img = ImageImpl(border_img)

    result = border_img.mul_scalar(255)

    original = original.to_rgb()

    # result.add_image(original)
    return original.add(result)
示例#3
0
def hough_line_detector(
    image: ImageImpl,
    epsilon: float,
    threshold: int,
    theta_step: int = 7,
    rho_step: int = 5,
) -> ImageImpl:
    border_image = border_detection.canny_detection(image, 3, 10, 10)

    D = max(image.height, image.width)
    max_rho = np.sqrt(2) * D

    rho_range = np.arange(-max_rho, max_rho, rho_step)
    theta_range = np.deg2rad(np.arange(-90, 90, theta_step))
    theta_cos = np.cos(theta_range)
    theta_sin = np.sin(theta_range)

    edge_pixels = np.where(
        border_image.get_array()[..., 0] == constants.MAX_PIXEL_VALUE)
    coordinates = list(zip(edge_pixels[0], edge_pixels[1]))
    accumulator = np.zeros((len(theta_range), len(rho_range)))

    for p in range(len(coordinates)):
        for theta_idx in range(len(theta_range)):
            for rho_idx in range(len(rho_range)):
                # Veo si cumple la ecuacion de la recta
                if (abs(rho_range[rho_idx] -
                        coordinates[p][1] * theta_cos[theta_idx] -
                        coordinates[p][0] * theta_sin[theta_idx]) < epsilon):
                    accumulator[theta_idx, rho_idx] += 1

    result = image.to_rgb()
    for rho_idx in range(len(rho_range)):
        for theta_idx in range(len(theta_range)):
            if accumulator[theta_idx, rho_idx] >= threshold:
                result = draw_lines(result, rho_range[rho_idx],
                                    theta_range[theta_idx])
    return result