0

I am trying to perform a Principal Component Analysis of some 3D scans however I am stuck when calculating and working with the eigenvalues and eigenvectors.

The scans are in a .obj file format.

     x          y         z
v 0.001888 -0.058120 -0.069146
v 0.007348 -0.066757 -0.062134
...                        ...
f 6436 6439 6445
f 6446 6445 6430

There are 6449 vectors, 12894 faces and 115 scans. My understanding is that because the data is 3D I cannot use the built in princomp function, plus I would probably run into some memory issues on my laptop due to the amount of data and finally I want to learn to do the PCA manually.

I believe there are 5 stages to performing this

  1. Calculate the mean 3D scan. BarX
  2. Subtract the mean from each of the scan. Xa - BarX = Bar Xa
  3. Create a matrix of Bar Xa * Bar Xa = Ma
  4. Calculate the eigenvalues and eigenvectors of Ma. Pa
  5. Add the mean shape, BarX to Pa to see the shape morph according the the eigenvalues and eigen vectors

I hope I haven't over simplified this too much but as I am not a mathematician/statistician this is my current understanding.

Stages 1 and 2 I have done as they are simple enough but it is the following stages which I am confused with.

As I am worried about running into memory issues I am going to create a matrix for x, y and z individually. So I am creating a diagonal matrix of 6449x6449 where x * x. Here is the code I have used to create the matrix for x of the first scan.

text <- readLines("R/location/scan1.obj", encoding="UTF-8")

xmat <- matrix(1:6449, ncol=1)
mat <- diag(6449)

for(i in 1:6449){
    xyzLine <- sub("v ", "", text[i])
    xyzList <- unlist(strsplit(xyzLine, " "))
    xmat[i, 1] = as.numeric(xyzList[1])
}

for(i in 1:6449){
    for(j in 1:6449){
        mat[i, j] <- xmat[i, 1] * xmat[j, 1]
    }
}

I do this for x, y and z. Then calculate the eigenvalues and eigenvectors using

eigenx <- eigen(x)
eigeny <- eigen(y)
eigenz <- eigen(z)

At this stage I am unsure if what I have done is correct or not? But its from here I don't know how I can combine the eigenvectors and eigenvalues into a format which I can add them onto BarX to see the shape morph?

If anyone has an advice or guidance it would be really appreciated.

Thanks in advance.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
TrueWheel
  • 997
  • 2
  • 20
  • 35
  • 6
    If you are going to run into memory problems using `prcomp()` then you will likely run into the same problems with your hand cooked code. The SVD is often the preferred way of doing PCA as it is more numerically accurate than the eigen decomposition. Try `prcomp()` but not via the `formula` method and see how that goes; your data don't sound that big to me... – Gavin Simpson Jun 04 '12 at 13:06
  • 1
    You can also try the `PCA()` function in the `FactoMineR` package, or the `dudi.pca()` function in the `ade4` package, which both perform principal component analysis. – juba Jun 04 '12 at 13:30
  • Here is also a discussion of conducting partial svd (this may save you time with a very large dataset): http://scicomp.stackexchange.com/questions/2313/apply-pca-on-very-large-sparse-matrix/2316#2316 – Marc in the box Jun 04 '12 at 13:34

0 Answers0