def _recursive_procrustes(self): r""" Recursively calculates a procrustes alignment. """ from menpo.shape import mean_pointcloud from menpo.transform import Similarity if self.n_iterations > self.max_iterations: return False new_tgt = mean_pointcloud( [t.aligned_source.points for t in self.transforms]) # rescale the new_target to be the same size as the original about # it's centre rescale = Similarity.identity(new_tgt.n_dims) s = UniformScale(self.initial_target_scale / new_tgt.norm(), self.n_dims, skip_checks=True) t = Translation(-new_tgt.centre, skip_checks=True) rescale.compose_before_inplace(t) rescale.compose_before_inplace(s) rescale.compose_before_inplace(t.pseudoinverse) rescale.apply_inplace(new_tgt) # check to see if we have converged yet delta_target = np.linalg.norm(self.target.points - new_tgt.points) if delta_target < 1e-6: return True else: self.n_iterations += 1 for t in self.transforms: t.set_target(new_tgt) self.target = new_tgt return self._recursive_procrustes()
def _recursive_procrustes(self): r""" Recursively calculates a procrustes alignment. """ # Avoid circular imports from menpo.shape import mean_pointcloud, PointCloud from ..compositions import scale_about_centre if self.n_iterations > self.max_iterations: return False new_tgt = mean_pointcloud([ PointCloud(t.aligned_source().points, copy=False) for t in self.transforms ]) # rescale the new_target to be the same size as the original about # it's centre rescale = scale_about_centre( new_tgt, self.initial_target_scale / new_tgt.norm()) rescale._apply_inplace(new_tgt) # check to see if we have converged yet delta_target = np.linalg.norm(self.target.points - new_tgt.points) if delta_target < 1e-6: return True else: self.n_iterations += 1 for t in self.transforms: t.set_target(new_tgt) self.target = new_tgt return self._recursive_procrustes()
def test_mean_pointcloud_type(): points = np.array([[1, 2, 3], [1, 1, 1]]) trilist = np.array([0, 1, 2]) pcs = [TriMesh(points, trilist), TriMesh(points + 2, trilist)] mean_pc = mean_pointcloud(pcs) assert isinstance(mean_pc, TriMesh) assert_allclose(mean_pc.points, points + 1)
def _recursive_procrustes(self): r""" Recursively calculates a procrustes alignment. """ from menpo.shape import mean_pointcloud from menpo.transform import Similarity if self.n_iterations > self.max_iterations: return False new_tgt = mean_pointcloud([t.aligned_source.points for t in self.transforms]) # rescale the new_target to be the same size as the original about # it's centre rescale = Similarity.identity(new_tgt.n_dims) s = UniformScale(self.initial_target_scale / new_tgt.norm(), self.n_dims, skip_checks=True) t = Translation(-new_tgt.centre, skip_checks=True) rescale.compose_before_inplace(t) rescale.compose_before_inplace(s) rescale.compose_before_inplace(t.pseudoinverse) rescale.apply_inplace(new_tgt) # check to see if we have converged yet delta_target = np.linalg.norm(self.target.points - new_tgt.points) if delta_target < 1e-6: return True else: self.n_iterations += 1 for t in self.transforms: t.set_target(new_tgt) self.target = new_tgt return self._recursive_procrustes()
def compute_reference_shape(shapes, diagonal, verbose=False): r""" Function that computes the reference shape as the mean shape of the provided shapes. Parameters ---------- shapes : `list` of `menpo.shape.PointCloud` The set of shapes from which to build the reference shape. diagonal : `int` or ``None`` If `int`, it ensures that the mean shape is scaled so that the diagonal of the bounding box containing it matches the provided value. If ``None``, then the mean shape is not rescaled. verbose : `bool`, optional If ``True``, then progress information is printed. Returns ------- reference_shape : `menpo.shape.PointCloud` The reference shape. """ # the reference_shape is the mean shape of the images' landmarks if verbose: print_dynamic('- Computing reference shape') reference_shape = mean_pointcloud(shapes) # fix the reference_shape's diagonal length if asked if diagonal: x, y = reference_shape.range() scale = diagonal / np.sqrt(x ** 2 + y ** 2) reference_shape = Scale(scale, reference_shape.n_dims).apply( reference_shape) return reference_shape
def _recursive_procrustes(self): r""" Recursively calculates a procrustes alignment. """ global mean_pointcloud, PointCloud, scale_about_centre, avoid_circular if avoid_circular is None: from menpo.shape import mean_pointcloud, PointCloud from ..compositions import scale_about_centre avoid_circular = True if self.n_iterations > self.max_iterations: return False new_tgt = mean_pointcloud([PointCloud(t.aligned_source().points, copy=False) for t in self.transforms]) # rescale the new_target to be the same size as the original about # it's centre rescale = scale_about_centre(new_tgt, self.initial_target_scale / new_tgt.norm()) rescale.apply_inplace(new_tgt) # check to see if we have converged yet delta_target = np.linalg.norm(self.target.points - new_tgt.points) if delta_target < 1e-6: return True else: self.n_iterations += 1 for t in self.transforms: t.set_target(new_tgt) self.target = new_tgt return self._recursive_procrustes()
def compute_reference_shape(shapes, diagonal, verbose=False): r""" Function that computes the reference shape as the mean shape of the provided shapes. Parameters ---------- shapes : `list` of `menpo.shape.PointCloud` The set of shapes from which to build the reference shape. diagonal : `int` or ``None`` If `int`, it ensures that the mean shape is scaled so that the diagonal of the bounding box containing it matches the provided value. If ``None``, then the mean shape is not rescaled. verbose : `bool`, optional If ``True``, then progress information is printed. Returns ------- reference_shape : `menpo.shape.PointCloud` The reference shape. """ # the reference_shape is the mean shape of the images' landmarks if verbose: print_dynamic('- Computing reference shape') reference_shape = mean_pointcloud(shapes) # fix the reference_shape's diagonal length if asked if diagonal: x, y = reference_shape.range() scale = diagonal / np.sqrt(x**2 + y**2) reference_shape = Scale(scale, reference_shape.n_dims).apply(reference_shape) return reference_shape
def test_mean_pointcloud(): points = np.array([[1, 2, 3], [1, 1, 1]]) pcs = [PointCloud(points), PointCloud(points + 2)] mean_pc = mean_pointcloud(pcs) assert isinstance(mean_pc, PointCloud) assert_allclose(mean_pc.points, points + 1)
def test_mean_pointcloud_type(): points = np.array([[1, 2, 3], [1, 1, 1]]) trilist = np.array([0, 1, 2]) pcs = [TriMesh(points, trilist), TriMesh(points + 2, trilist)] mean_pc = mean_pointcloud(pcs) assert isinstance(mean_pc, TriMesh) assert_allclose(mean_pc.points, points + 1)
def _build_shape_model(self, shapes, scale_index): mean_aligned_shape = mean_pointcloud(align_shapes(shapes)) self.n_landmarks = mean_aligned_shape.n_points self.reference_frame = build_reference_frame(mean_aligned_shape) dense_shapes = densify_shapes(shapes, self.reference_frame, self.transform) # Build dense shape model max_sc = self.max_shape_components[scale_index] return self._shape_model_cls[scale_index](dense_shapes, max_n_components=max_sc)
def _build_shape_model(self, shapes, scale_index): mean_aligned_shape = mean_pointcloud(align_shapes(shapes)) self.n_landmarks = mean_aligned_shape.n_points self.reference_frame = build_reference_frame(mean_aligned_shape) dense_shapes = densify_shapes(shapes, self.reference_frame, self.transform) # build dense shape model shape_model = build_shape_model(dense_shapes) return shape_model
def __init__(self, data, **kwargs): from menpofit.transform import DifferentiableAlignmentSimilarity aligned_shapes = align_shapes(data) self.mean = mean_pointcloud(aligned_shapes) # Default target is the mean self._target = self.mean self.transform = DifferentiableAlignmentSimilarity( self.target, self.target)
def __init__(self, data, **kwargs): from menpofit.transform import DifferentiableAlignmentSimilarity aligned_shapes = align_shapes(data) self.mean = mean_pointcloud(aligned_shapes) # Default target is the mean self._target = self.mean self.transform = DifferentiableAlignmentSimilarity(self.target, self.target)
def _build_shape_model(self, shapes, scale_index): mean_aligned_shape = mean_pointcloud(align_shapes(shapes)) self.n_landmarks = mean_aligned_shape.n_points self.reference_frame = build_patch_reference_frame( mean_aligned_shape, patch_shape=self.patch_shape[scale_index]) dense_shapes = densify_shapes(shapes, self.reference_frame, self.transform) # Build dense shape model max_sc = self.max_shape_components[scale_index] return self._shape_model_cls[scale_index](dense_shapes, max_n_components=max_sc)
def _compute_reference_shape(self, images, group, label, verbose): # the reference_shape is the mean shape of the images' landmarks if verbose: print_dynamic('- Computing reference shape') shapes = [i.landmarks[group][label] for i in images] ref_shape = mean_pointcloud(shapes) # fix the reference_shape's diagonal length if specified if self.diagonal: x, y = ref_shape.range() scale = self.diagonal / np.sqrt(x**2 + y**2) ref_shape = Scale(scale, ref_shape.n_dims).apply(ref_shape) return ref_shape
def _compute_reference_shape(self, images, group, label, verbose): # the reference_shape is the mean shape of the images' landmarks if verbose: print_dynamic('- Computing reference shape') shapes = [i.landmarks[group][label] for i in images] ref_shape = mean_pointcloud(shapes) # fix the reference_shape's diagonal length if specified if self.diagonal: x, y = ref_shape.range() scale = self.diagonal / np.sqrt(x**2 + y**2) Scale(scale, ref_shape.n_dims).apply_inplace(ref_shape) return ref_shape
def warp_images(training_shapes, images, out_image_fns=None): template_shape = mean_pointcloud(training_shapes) template_shape = template_shape.constrain_to_bounds( template_shape.bounds(5)) mask = menpo.image.BooleanImage.init_from_pointcloud(template_shape) transformer = menpo.transform.GeneralizedProcrustesAnalysis( training_shapes, template_shape) warped_images = [] for ii, image in enumerate(images): # cropped, tr_crop = image.crop_to_landmarks_proportion(.1, return_transform=True) # chained_tr = transformer.transforms[ii].compose_before(tr_crop) warped = image.warp_to_mask(mask, transformer.transforms[ii]) warped_images.append(warped.as_imageio()) # if out_image_fns is not None: return warped_images
def compute_reference_shape(shapes, normalization_diagonal, verbose=False): r""" Function that computes the reference shape as the mean shape of the provided shapes. Parameters ---------- shapes : list of :map:`PointCloud` The set of shapes from which to build the reference shape. normalization_diagonal : `int` If int, it ensures that the mean shape is scaled so that the diagonal of the bounding box containing it matches the normalization_diagonal value. If None, the mean shape is not rescaled. verbose : `bool`, Optional Flag that controls information and progress printing. Returns ------- reference_shape : :map:`PointCloud` The reference shape. """ # the reference_shape is the mean shape of the images' landmarks if verbose: print_dynamic('- Computing reference shape') reference_shape = mean_pointcloud(shapes) # fix the reference_shape's diagonal length if asked if normalization_diagonal: x, y = reference_shape.range() scale = normalization_diagonal / np.sqrt(x**2 + y**2) reference_shape = Scale(scale, reference_shape.n_dims).apply( reference_shape) return reference_shape
def compute_reference_shape(shapes, normalization_diagonal, verbose=False): r""" Function that computes the reference shape as the mean shape of the provided shapes. Parameters ---------- shapes : list of :map:`PointCloud` The set of shapes from which to build the reference shape. normalization_diagonal : `int` If int, it ensures that the mean shape is scaled so that the diagonal of the bounding box containing it matches the normalization_diagonal value. If None, the mean shape is not rescaled. verbose : `bool`, Optional Flag that controls information and progress printing. Returns ------- reference_shape : :map:`PointCloud` The reference shape. """ # the reference_shape is the mean shape of the images' landmarks if verbose: print_dynamic('- Computing reference shape') reference_shape = mean_pointcloud(shapes) # fix the reference_shape's diagonal length if asked if normalization_diagonal: x, y = reference_shape.range() scale = normalization_diagonal / np.sqrt(x**2 + y**2) reference_shape = Scale(scale, reference_shape.n_dims).apply(reference_shape) return reference_shape
def _compute_reference_shape(self, images, group, label): r""" Function that computes the reference shape, given a set of images. Parameters ---------- images : list of :map:`MaskedImage` The set of landmarked images. group : `string` The key of the landmark set that should be used. If ``None``, and if there is only one set of landmarks, this set will be used. label : `string` The label of the landmark manager that you wish to use. If no label is passed, the convex hull of all landmarks is used. Returns ------- reference_shape : :map:`PointCloud` The reference shape computed based on the given images. """ shapes = [i.landmarks[group][label] for i in images] return mean_pointcloud(shapes)
def _compute_reference_shape(self, images, group, label): r""" Function that computes the reference shape, given a set of images. Parameters ---------- images : list of :map:`MaskedImage` The set of landmarked images. group : `string` The key of the landmark set that should be used. If ``None``, and if there is only one set of landmarks, this set will be used. label : `string` The label of the landmark manager that you wish to use. If no label is passed, the convex hull of all landmarks is used. Returns ------- reference_shape : :map:`PointCloud` The reference shape computed based on the given images. """ shapes = [i.landmarks[group][label] for i in images] return mean_pointcloud(shapes)
def test_mean_pointcloud(): points = np.array([[1, 2, 3], [1, 1, 1]]) pcs = [PointCloud(points), PointCloud(points + 2)] mean_pc = mean_pointcloud(pcs) assert isinstance(mean_pc, PointCloud) assert_allclose(mean_pc.points, points + 1)