Beispiel #1
0
    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()
Beispiel #2
0
    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()
Beispiel #3
0
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)
Beispiel #4
0
    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()
Beispiel #5
0
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
Beispiel #6
0
    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()
Beispiel #7
0
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)
Beispiel #10
0
    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)
Beispiel #11
0
 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
Beispiel #12
0
    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)
Beispiel #13
0
    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)
Beispiel #14
0
 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)
Beispiel #15
0
 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
Beispiel #16
0
 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
Beispiel #17
0
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
Beispiel #18
0
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
Beispiel #19
0
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
Beispiel #20
0
    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)
Beispiel #21
0
    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)
Beispiel #22
0
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)