def test_procrustes_no_target():
    # square
    src_1 = PointCloud(np.array([[1.0, 1.0], [1.0, -1.0],
                                 [-1.0, -1.0], [-1.0, 1.0]]))
    # rhombus
    src_2 = PointCloud(np.array([[2.0, 0.0], [4.0, 2.0],
                                 [6.0, 0.0], [4.0, -2.0]]))
    # trapezoid
    src_3 = PointCloud(np.array([[-0.5, -1.5], [2.5, -1.5],
                                 [2.8, -2.5], [-0.2, -2.5]]))
    gpa = GeneralizedProcrustesAnalysis([src_1, src_2, src_3],
                                        allow_mirror=True)
    aligned_1 = gpa.transforms[0].apply(gpa.sources[0])
    aligned_2 = gpa.transforms[1].apply(gpa.sources[1])
    aligned_3 = gpa.transforms[2].apply(gpa.sources[2])
    assert(gpa.converged is True)
    assert(gpa.n_iterations == 5)
    assert(gpa.n_sources == 3)
    assert(np.round(gpa.initial_target_scale * 100) == 195.)
    assert(np.round(gpa.mean_alignment_error() * 10) == 4.)
    assert_allclose(np.around(aligned_1.points, decimals=1),
                    np.around(aligned_2.points, decimals=1))
    res_3 = np.array([[0.7, -0.3], [2.6, -0.4], [2.7, -1.0], [0.9, -0.9]])
    assert_allclose(np.around(aligned_3.points, decimals=1), res_3)
    assert_allclose(gpa.target.points, gpa.mean_aligned_shape().points)
def test_procrustes_with_target():
    # square
    src_1 = PointCloud(np.array([[1.0, 1.0], [1.0, -1.0],
                                 [-1.0, -1.0], [-1.0, 1.0]]))
    # trapezoid
    src_2 = PointCloud(np.array([[-0.5, -1.5], [2.5, -1.5],
                                 [2.8, -2.5], [-0.2, -2.5]]))
    # rhombus as target
    src_trg = PointCloud(np.array([[2.0, 0.0], [4.0, 2.0],
                                   [6.0, 0.0], [4.0, -2.0]]))
    gpa = GeneralizedProcrustesAnalysis([src_1, src_2], target=src_trg,
                                        allow_mirror=True)
    aligned_1 = gpa.transforms[0].apply(gpa.sources[0])
    aligned_2 = gpa.transforms[1].apply(gpa.sources[1])
    assert(gpa.converged is True)
    assert(gpa.n_iterations == 2)
    assert(gpa.n_sources == 2)
    assert(gpa.initial_target_scale == 4.)
    assert(np.round(gpa.mean_alignment_error() * 100) == 93.)
    assert_allclose(np.around(aligned_1.points, decimals=1),
                    np.around(src_trg.points, decimals=1))
    res_2 = np.array([[2.0, -0.9], [4.9, 1.6], [6.0, 0.9], [3.1, -1.6]])
    assert_allclose(np.around(aligned_2.points, decimals=1), res_2)
    mean = np.array([[2.0, -0.5], [4.5, 1.8], [6.0, 0.5], [3.5, -1.8]])
    assert_allclose(np.around(gpa.mean_aligned_shape().points, decimals=1),
                    mean)
def build_shape_model(shapes, max_components=None):
    r"""
    Builds a shape model given a set of shapes.

    Parameters
    ----------
    shapes: list of :map:`PointCloud`
        The set of shapes from which to build the model.
    max_components: None or int or float
        Specifies the number of components of the trained shape model.
        If int, it specifies the exact number of components to be retained.
        If float, it specifies the percentage of variance to be retained.
        If None, all the available components are kept (100% of variance).

    Returns
    -------
    shape_model: :class:`menpo.model.pca`
        The PCA shape model.
    """
    # centralize shapes
    centered_shapes = [Translation(-s.centre()).apply(s) for s in shapes]
    # align centralized shape using Procrustes Analysis
    gpa = GeneralizedProcrustesAnalysis(centered_shapes)
    aligned_shapes = [s.aligned_source() for s in gpa.transforms]

    # build shape model
    shape_model = PCAModel(aligned_shapes)
    if max_components is not None:
        # trim shape model if required
        shape_model.trim_components(max_components)

    return shape_model
Beispiel #4
0
def align_shapes(shapes):
    r"""
    """
    # centralize shapes
    centered_shapes = [Translation(-s.centre()).apply(s) for s in shapes]
    # align centralized shape using Procrustes Analysis
    gpa = GeneralizedProcrustesAnalysis(centered_shapes)
    return [s.aligned_source() for s in gpa.transforms]
Beispiel #5
0
def align_shapes(shapes):
    r"""
    Function that aligns a set of shapes by applying Generalized Procrustes
    Analysis.

    Parameters
    ----------
    shapes : `list` of `menpo.shape.PointCloud`
        The input shapes.

    Returns
    -------
    aligned_shapes : `list` of `menpo.shape.PointCloud`
        The list of aligned shapes.
    """
    # centralize shapes
    centered_shapes = [Translation(-s.centre()).apply(s) for s in shapes]
    # align centralized shape using Procrustes Analysis
    gpa = GeneralizedProcrustesAnalysis(centered_shapes)
    return [s.aligned_source() for s in gpa.transforms]