def get_centerline_optimized(self, alpha=1e3, beta=1e6, gamma=0.01, spacing=20, max_iterations=1000, endpoints=None): """ determines the center line of the polygon using an active contour algorithm """ # use an active contour algorithm to find centerline ac = ActiveContour(blur_radius=1, alpha=alpha, beta=beta, gamma=gamma, closed_loop=False) ac.max_iterations = max_iterations # set the potential from the distance map mask, offset = self.get_mask(1, ret_offset=True) potential = cv2.distanceTransform(mask, cv2.DIST_L2, 5) ac.set_potential(potential) # initialize the centerline from the estimate points = self.get_centerline_estimate(endpoints) points = curves.make_curve_equidistant(points, spacing=spacing) points = curves.translate_points(points, -offset[0], -offset[1]) # anchor the end points anchor = np.zeros(len(points), np.bool) anchor[0] = anchor[-1] = True # find the best contour points = ac.find_contour(points, anchor, anchor) points = curves.make_curve_equidistant(points, spacing=spacing) return curves.translate_points(points, *offset)
def _find_point_connection(p1, p2=None, maximize_distance=False): """ estimate centerline between the one or two points """ mask, offset = self.get_mask(margin=2, dtype=np.int32, ret_offset=True) p1 = (p1[0] - offset[0], p1[1] - offset[1]) if maximize_distance or p2 is None: dist_prev = 0 if maximize_distance else np.inf # iterate until second point is found while True: # make distance map starting from point p1 distance_map = mask.copy() regions.make_distance_map(distance_map, start_points=(p1,)) # find point farthest point away from p1 idx_max = np.unravel_index(distance_map.argmax(), distance_map.shape) dist = distance_map[idx_max] p2 = idx_max[1], idx_max[0] if dist <= dist_prev: break dist_prev = dist # take farthest point as new start point p1 = p2 else: # locate the centerline between the two given points p2 = (p2[0] - offset[0], p2[1] - offset[1]) distance_map = mask regions.make_distance_map(distance_map, start_points=(p1,), end_points=(p2,)) # find path between p1 and p2 path = regions.shortest_path_in_distance_map(distance_map, p2) return curves.translate_points(path, *offset)