def centerline(self): """ determine the center line of the tail """ mask, offset = self.mask dist_map = cv2.distanceTransform(mask, cv2.DIST_L2, 5) # setup active contour algorithm ac = ActiveContour(blur_radius=self.centerline_blur_radius, closed_loop=False, alpha=0, #< line length is constraint by beta beta=self.centerline_bending_stiffness, gamma=self.centerline_adaptation_rate) ac.max_iterations = self.centerline_max_iterations ac.set_potential(dist_map) # find centerline starting from the ventral_side points = curves.translate_points(self.ventral_side, -offset[0], -offset[1]) spacing = self.centerline_spacing points = curves.make_curve_equidistant(points, spacing=spacing) # use the active contour algorithm points = ac.find_contour(points) points = curves.make_curve_equidistant(points, spacing=spacing) # translate points back into global coordinate system points = curves.translate_points(points, offset[0], offset[1]) # orient the centerline such that it starts at the posterior end dist1 = curves.point_distance(points[0], self.endpoints[0]) dist2 = curves.point_distance(points[-1], self.endpoints[0]) if dist1 > dist2: points = points[::-1] return points
def centerline(self): """ determine the center line of the tail """ mask, offset = self.mask dist_map = cv2.distanceTransform(mask, cv2.DIST_L2, 5) # setup active contour algorithm ac = ActiveContour( blur_radius=self.centerline_blur_radius, closed_loop=False, alpha=0, #< line length is constraint by beta beta=self.centerline_bending_stiffness, gamma=self.centerline_adaptation_rate) ac.max_iterations = self.centerline_max_iterations ac.set_potential(dist_map) # find centerline starting from the ventral_side points = curves.translate_points(self.ventral_side, -offset[0], -offset[1]) spacing = self.centerline_spacing points = curves.make_curve_equidistant(points, spacing=spacing) # use the active contour algorithm points = ac.find_contour(points) points = curves.make_curve_equidistant(points, spacing=spacing) # translate points back into global coordinate system points = curves.translate_points(points, offset[0], offset[1]) # orient the centerline such that it starts at the posterior end dist1 = curves.point_distance(points[0], self.endpoints[0]) dist2 = curves.point_distance(points[-1], self.endpoints[0]) if dist1 > dist2: points = points[::-1] return points
def measure_single_tail(self, frame, tail): """ do line scans along the measurement segments of the tails """ l = self.params['measurement/line_scan_width'] w = self.params['measurement/line_scan_step'] #< width of each individual line scan result = [] for line in self.get_measurement_lines(tail): ps = curves.make_curve_equidistant(line, spacing=2*w) profile = [] for pp, p, pn in itertools.izip(ps[:-2], ps[1:-1], ps[2:]): # slope dx, dy = pn - pp dlen = math.hypot(dx, dy) dx /= dlen; dy /= dlen # get end points of line scan p1 = (p[0] + l*dy, p[1] - l*dx) p2 = (p[0] - l*dy, p[1] + l*dx) lscan = image.line_scan(frame, p1, p2, half_width=w) profile.append(lscan.mean()) self.output.add_points([p1, p2], 1, 'w') result.append(profile) return result
def contour(self, points): """ sets the contour of the tail performing some sanity tests """ # do a first regularization points = regions.regularize_contour_points(points) spacing = self.contour_spacing # make the contour line equidistant points = curves.make_curve_equidistant(points, spacing=spacing) # regularize again, just to be sure points = regions.regularize_contour_points(points) # call parent setter shapes.Polygon.contour.fset(self, points)
def create_from_ground_profile_list(cls, ground_profiles): # determine the maximal number of points in a single ground num_points = max(len(ground) for ground in ground_profiles.grounds) # iterate through all profiles and convert them to have equal number of line # and store the data times = ground_profiles.times profiles = [curves.make_curve_equidistant(ground.points, count=num_points) for ground in ground_profiles.grounds] # store information in numpy arrays # profiles is a 3D array: len(times) x num_points x 2 return cls(times=times, profiles=profiles)
def _get_burrow_exits(self, contour): """ determines the exits of a burrow. Returns a list of exits, where each exit is described by a list of points lying on the burrow contour """ ground_line = self.ground.linestring dist_max = self.params['burrows/ground_point_distance'] #/2 # dist_max = dist + self.params['burrows/width'] contour = curves.make_curve_equidistant(contour, spacing=2) # determine burrow points close to the ground exit_points = [point for point in contour if ground_line.distance(geometry.Point(point)) < dist_max] if len(exit_points) < 2: return exit_points exit_points = np.array(exit_points) # cluster the points to detect multiple connections # this is important when a burrow has multiple exits to the ground dist_max = self.params['burrows/width'] data = cluster.hierarchy.fclusterdata(exit_points, dist_max, method='single', criterion='distance') exits = [exit_points[data == cluster_id] for cluster_id in np.unique(data)] # exits = [] # for cluster_id in np.unique(data): # points = exit_points[data == cluster_id] # point = points.mean(axis=0) # point_ground = curves.get_projection_point(ground_line, point) # exits.append(point_ground) return exits
def make_equidistant(self, **kwargs): """ makes the ground profile equidistant """ self.points = curves.make_curve_equidistant(self.points, **kwargs)