Announcement: All noncommercial projects registered to use Earth Engine before April 15, 2025 must verify noncommercial eligibility to maintain Earth Engine access.
Stay organized with collections
Save and categorize content based on your preferences.
The principal
components (PC) transform (also known as the Karhunen-Loeve transform) is a
spectral rotation that takes spectrally correlated image data and outputs uncorrelated
data. The PC transform accomplishes this by diagonalizing the input band correlation
matrix through Eigen-analysis. To do this in Earth Engine, use a covariance reducer on an
array image and the eigen() command on the resultant covariance array.
Consider the following function for that purpose (an example of it in application is
available as a
Code Editor script
and a Colab notebook).
The input to the function is a mean zero image, a scale and a region over which to
perform the analysis. Note that the input imagery first needs to be converted to a 1-D
array image and then reduced using ee.Reducer.centeredCovariance(). The
array returned by this reduction is the symmetric variance-covariance matrix of the input.
Use the eigen() command to get the eigenvalues and eigenvectors of the
covariance matrix. The matrix returned by eigen() contains the eigenvalues
in the 0-th position of the 1-axis. As shown in the earlier function, use slice()
to separate the eigenvalues and the eigenvectors. Each element along the 0-axis of the
eigenVectors matrix is an eigenvector. As in the
tasseled cap (TC) example, perform the
transformation by matrix multiplying the arrayImage by the eigenvectors.
In this example, each eigenvector multiplication results in a PC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-06-10 UTC."],[[["\u003cp\u003eThe principal components (PC) transform decorrelates image data by diagonalizing the input band correlation matrix.\u003c/p\u003e\n"],["\u003cp\u003eEarth Engine uses a covariance reducer and the \u003ccode\u003eeigen()\u003c/code\u003e command to perform the PC transform.\u003c/p\u003e\n"],["\u003cp\u003eThe provided function takes a mean-centered image, scale, and region to compute and return principal components.\u003c/p\u003e\n"],["\u003cp\u003eThe input image is converted to a 1D array, and covariance is calculated using \u003ccode\u003eee.Reducer.centeredCovariance()\u003c/code\u003e.\u003c/p\u003e\n"],["\u003cp\u003eEigenvalues and eigenvectors are extracted, and the image is transformed by matrix multiplication with eigenvectors.\u003c/p\u003e\n"]]],["The provided content outlines how to perform a principal component (PC) transform in Earth Engine. This involves using a covariance reducer on an array image and applying the `eigen()` command to the resulting covariance array. Key actions include: converting input imagery to a 1D array, computing band covariance, performing eigen analysis to get eigenvalues and eigenvectors, transforming via matrix multiplication, and normalizing by standard deviations derived from the eigenvalues to obtain the PCs.\n"],null,["The [principal\ncomponents (PC) transform](http://en.wikipedia.org/wiki/Principal_component_analysis) (also known as the Karhunen-Loeve transform) is a\nspectral rotation that takes spectrally correlated image data and outputs uncorrelated\ndata. The PC transform accomplishes this by diagonalizing the input band correlation\nmatrix through Eigen-analysis. To do this in Earth Engine, use a covariance reducer on an\narray image and the `eigen()` command on the resultant covariance array.\nConsider the following function for that purpose (an example of it in application is\navailable as a\n[Code Editor script](https://code.earthengine.google.com/30c0e509da3a644fc4fea031b7649f87)\nand a [Colab notebook](https://github.com/google/earthengine-community/blob/master/guides/linked/Earth_Engine_PCA.ipynb)).\n\nCode Editor (JavaScript) \n\n```javascript\nvar getPrincipalComponents = function(centered, scale, region) {\n // Collapse the bands of the image into a 1D array per pixel.\n var arrays = centered.toArray();\n\n // Compute the covariance of the bands within the region.\n var covar = arrays.reduceRegion({\n reducer: ee.Reducer.centeredCovariance(),\n geometry: region,\n scale: scale,\n maxPixels: 1e9\n });\n\n // Get the 'array' covariance result and cast to an array.\n // This represents the band-to-band covariance within the region.\n var covarArray = ee.Array(covar.get('array'));\n\n // Perform an eigen analysis and slice apart the values and vectors.\n var eigens = covarArray.eigen();\n\n // This is a P-length vector of Eigenvalues.\n var eigenValues = eigens.slice(1, 0, 1);\n // This is a PxP matrix with eigenvectors in rows.\n var eigenVectors = eigens.slice(1, 1);\n\n // Convert the array image to 2D arrays for matrix computations.\n var arrayImage = arrays.toArray(1);\n\n // Left multiply the image array by the matrix of eigenvectors.\n var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage);\n\n // Turn the square roots of the Eigenvalues into a P-band image.\n var sdImage = ee.Image(eigenValues.sqrt())\n .arrayProject([0]).arrayFlatten([getNewBandNames('sd')]);\n\n // Turn the PCs into a P-band image, normalized by SD.\n return principalComponents\n // Throw out an an unneeded dimension, [[]] -\u003e [].\n .arrayProject([0])\n // Make the one band array image a multi-band image, [] -\u003e image.\n .arrayFlatten([getNewBandNames('pc')])\n // Normalize the PCs by their SDs.\n .divide(sdImage);\n};\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\nColab (Python) \n\n```python\ndef get_principal_components(centered, scale, region):\n # Collapse bands into 1D array\n arrays = centered.toArray()\n\n # Compute the covariance of the bands within the region.\n covar = arrays.reduceRegion(\n reducer=ee.Reducer.centeredCovariance(),\n geometry=region,\n scale=scale,\n maxPixels=1e9,\n )\n\n # Get the 'array' covariance result and cast to an array.\n # This represents the band-to-band covariance within the region.\n covar_array = ee.Array(covar.get('array'))\n\n # Perform an eigen analysis and slice apart the values and vectors.\n eigens = covar_array.eigen()\n\n # This is a P-length vector of Eigenvalues.\n eigen_values = eigens.slice(1, 0, 1)\n # This is a PxP matrix with eigenvectors in rows.\n eigen_vectors = eigens.slice(1, 1)\n\n # Convert the array image to 2D arrays for matrix computations.\n array_image = arrays.toArray(1)\n\n # Left multiply the image array by the matrix of eigenvectors.\n principal_components = ee.Image(eigen_vectors).matrixMultiply(array_image)\n\n # Turn the square roots of the Eigenvalues into a P-band image.\n sd_image = (\n ee.Image(eigen_values.sqrt())\n .arrayProject([0])\n .arrayFlatten([get_new_band_names('sd')])\n )\n\n # Turn the PCs into a P-band image, normalized by SD.\n return (\n # Throw out an an unneeded dimension, [[]] -\u003e [].\n principal_components.arrayProject([0])\n # Make the one band array image a multi-band image, [] -\u003e image.\n .arrayFlatten([get_new_band_names('pc')])\n # Normalize the PCs by their SDs.\n .divide(sd_image)\n )\n```\n\nThe input to the function is a mean zero image, a scale and a region over which to\nperform the analysis. Note that the input imagery first needs to be converted to a 1-D\narray image and then reduced using `ee.Reducer.centeredCovariance()`. The\narray returned by this reduction is the symmetric variance-covariance matrix of the input.\nUse the `eigen()` command to get the eigenvalues and eigenvectors of the\ncovariance matrix. The matrix returned by `eigen()` contains the eigenvalues\nin the 0-th position of the 1-axis. As shown in the earlier function, use `slice()`\nto separate the eigenvalues and the eigenvectors. Each element along the 0-axis of the\neigenVectors matrix is an eigenvector. As in the\n[tasseled cap (TC) example](/earth-engine/guides/arrays_array_images), perform the\ntransformation by matrix multiplying the `arrayImage` by the eigenvectors.\nIn this example, each eigenvector multiplication results in a PC."]]