In [ ]:
import numpy as np
from menpo.shape import PointCloud
from menpo.groupalign import GeneralizedProcrustesAnalysis

In [ ]:
src_1 = PointCloud(np.array([[0.0, 0.0],
                             [1.0, 0.0],
                             [1.0, 1.0],
                             [0.0, 1.0]]))
src_2 = PointCloud(np.array([[0.0, 0.0],
                             [2.0, 0.1],
                             [2.0, 2.0],
                             [0.1, 2.0]]))
src_3 = PointCloud(np.array([[-1.0, 0.0],
                             [0.0, 0.0],
                             [0.0, 1.0],
                             [-1.0, 1.0]]))

Building a GeneralizedProcrustesAnalysis causes it to run it's iterative alignment process.


In [ ]:
gpa = GeneralizedProcrustesAnalysis([src_1, src_2, src_3])

Printing the object gives you a summary of what happened


In [ ]:
print gpa

Being an instance of MultipleAlignment, we know it will provide a property transforms, giving one transform per source that aligns it to the target frame. The target frame is also accessable


In [ ]:
print gpa.transforms
print gpa.target

Each step of the procrustes step is visable - there is a procrustes attribute, which is a list of length n_sources. Each element of this list is a list of Procrustes objects, each one specifying one step in the iteration for the source in question. The following example shows how to interpret these objects.

all the Procrustes objects used to align src_1 are:


In [ ]:
src_1_proc_objects = gpa.procrustes[0]
print src_1_proc_objects

and for src_2 we used:


In [ ]:
src_2_proc_objects = gpa.procrustes[1]
print src_2_proc_objects

the first item of src_1_proc_objects has a source which is the same as src_1:


In [ ]:
print src_1_proc_objects[0].source
print np.all(src_1 == src_1_proc_objects[0].source)

the target of this object was set in the first iteration of the algorithm to the mean of all the sources:


In [ ]:
print src_1_proc_objects[0].target

the closest alignment that could be achieved in this first step is the aligned_source field. We can see that this was the source input to the next stage of the iteration, which is the next item in the list:


In [ ]:
print src_1_proc_objects[0].aligned_source
print np.all(src_1_proc_objects[0].aligned_source == src_1_proc_objects[1].source)

Its simple to manually check how the alignment did (this will be added to the object in a future as .view())


In [ ]:
for t, a_c in zip(gpa.transforms, gpa.sources):
    aligned_src = t.apply(a_c)
    scatter(aligned_src[:,0], aligned_src[:,1])