Cross Validated is a question and answer site for people interested in statistics, machine learning, data analysis, data mining, and data visualization. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have some hyperspectral image data similar to this, and I want to do a PCA on it. The problem: I've never done a PCA, and its specially difficult for me to do it on 3D data.

How can I do it in MATLAB or R? [See also Analyzing 3D data: What can be done? ]

share|improve this question
up vote 4 down vote accepted

One simple way to do it is to transform your 3D data into a vector. This is a bit rough but often works fine in practice. Then you can use the prcompfunction from the R base package to compute PCA.

You can also use the "Multilinear Principal Component Analysis of Tensor Objects" (MPCA) proposed by Lu et al. (2008). It answers your question directly, as it does PCA on multidimensional objects. An implementation of their algorithm is available in MATLAB here.

share|improve this answer

You could also have a look at the "hyperspec" package in R. has a very clear documentation for dealing with hyperspectral data. I would suggest to use MATLAB if you would like to proceed further than PCA.

share|improve this answer

Put the hyperspectral (HS) image into a DxN matrix X where D is the dimension of the data (no of HS bands) and N is the number of HS pixels; then calculate the covariance of X:

   CovMat = cov(X');  %'

Now suppose you are interested in only 3 principal components so you need to find the 3 directions that the variance of the data is largest:

   [V E] = eigs(CovMat, 3);

The first 3 cols of V are the first 3 principal components and forms the subspace that you are projecting the data to:

   A = [V(:,1) V(:,2) V(:,3)];

Project your data to that subspace:

   Y = X'*A;  %'

This is the visualization of X projected to its 1st 3 principal components:

   figure; plot3(Y(:, 1), Y(:, 2), Y(:, 3), '.')

If image is very large randomly choose a subset of the pixels to make X smaller.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.