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
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)
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