Preet Desai wrote:
> I'm trying to do a course alignment of two similar (but not identical) point clouds using principal components analysis to get 3 direction vectors for each point cloud and finding a rotation based between the corresponding vectors (I'm deciding which vectors correspond with eigenvalue magnitudes).
>
> I'm using the eigs() function on the covariance matrix of each point cloud to get the respective eigenvectors and eigenvalues. I'm having two problems trying to align the data.
>
> 1) The eigenvectors for each data set represent the same axis (for example, a major axis of an ellipse), but sometimes point in different directions based on the initial position of the point clouds in space. So if the the eigenvectors were representing an axis 'x' for both data sets, the corresponding eigenvectors would be along 'x' but might be pointing in different directions. Since the objects I'm trying to align are not symmetrical this is a problem!
Yes, the signs of the eigenvectors can be sensitive to small changes in the data. However, for the purposes of PCA, those signs are entirely unimportant. For your purposes the sign may be important, so you probably want to enforce some appropriate sign convention.
> 2) I use a basic method to find the rotation between the sets of eigenvectors. Say A represents one set and B represents another. I find a matrix R that transforms A to B ((R*A) = B, R*A*A^1 = B*A^1, R = B*A^1).
> Unfortunately this method permits R to have reflections as well as rotations. This is unacceptable for my application and I wanted to know if there was another way to find 'R' without allowing for reflection.
If you have access to the Statistics Toolbox, you might look at using PROCRUSTES on your eigenvectors:
>> help procrustes
PROCRUSTES Procrustes Analysis
D = PROCRUSTES(X, Y) determines a linear transformation (translation,
reflection, orthogonal rotation, and scaling) of the points in the
matrix Y to best conform them to the points in the matrix X. The
"goodnessoffit" criterion is the sum of squared errors. PROCRUSTES
returns the minimized value of this dissimilarity measure in D. D is
standardized by a measure of the scale of X, given by
sum(sum((X  repmat(mean(X,1), size(X,1), 1)).^2, 1))
i.e., the sum of squared elements of a centered version of X. However,
if X comprises repetitions of the same point, the sum of squared errors
is not standardized.
X and Y are assumed to have the same number of points (rows), and
PROCRUSTES matches the i'th point in Y to the i'th point in X. Points
in Y can have smaller dimension (number of columns) than those in X.
In this case, PROCRUSTES adds columns of zeros to Y as necessary.
[D, Z] = PROCRUSTES(X, Y) also returns the transformed Y values.
[D, Z, TRANSFORM] = PROCRUSTES(X, Y) also returns the transformation
that maps Y to Z. TRANSFORM is a structure with fields:
c: the translation component
T: the orthogonal rotation and reflection component
b: the scale component
That is, Z = TRANSFORM.b * Y * TRANSFORM.T + TRANSFORM.c.
[...] = PROCRUSTES(..., 'Scaling',false) computes a procrustes solution
that does not include a scale component, that is, TRANSFORM.b == 1.
PROCRUSTES(..., 'Scaling',true) computes a procrustes solution that
does include a scale component, which is the default.
[...] = PROCRUSTES(..., 'Reflection',false) computes a procrustes solution
that does not include a reflection component, that is, DET(TRANSFORM.T) is
1. PROCRUSTES(..., 'Reflection','best') computes the best fit procrustes
solution, which may or may not include a reflection component, 'best' is
the default. PROCRUSTES(..., 'Reflection',true) forces the solution to
include a reflection component, that is, DET(TRANSFORM.T) is 1.
