La transformation des composants principaux (PC) (également appelée transformation Karhunen-Loeve) est une rotation spectrale qui prend des données d'image corrélées spectralement et produit des données non corrélées. La transformation PC effectue cette opération en diagonalisant la matrice de corrélation des bandes d'entrée via l'analyse des valeurs propres. Pour ce faire dans Earth Engine, utilisez un réducteur de covariance sur une image de tableau et la commande eigen()
sur le tableau de covariance obtenu.
Pour ce faire, considérez la fonction suivante (un exemple d'application est disponible en tant que script Code Editor et notebook Colab).
Éditeur de code (JavaScript)
var getPrincipalComponents = function(centered, scale, region) { // Collapse the bands of the image into a 1D array per pixel. var arrays = centered.toArray(); // Compute the covariance of the bands within the region. var covar = arrays.reduceRegion({ reducer: ee.Reducer.centeredCovariance(), geometry: region, scale: scale, maxPixels: 1e9 }); // Get the 'array' covariance result and cast to an array. // This represents the band-to-band covariance within the region. var covarArray = ee.Array(covar.get('array')); // Perform an eigen analysis and slice apart the values and vectors. var eigens = covarArray.eigen(); // This is a P-length vector of Eigenvalues. var eigenValues = eigens.slice(1, 0, 1); // This is a PxP matrix with eigenvectors in rows. var eigenVectors = eigens.slice(1, 1); // Convert the array image to 2D arrays for matrix computations. var arrayImage = arrays.toArray(1); // Left multiply the image array by the matrix of eigenvectors. var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage); // Turn the square roots of the Eigenvalues into a P-band image. var sdImage = ee.Image(eigenValues.sqrt()) .arrayProject([0]).arrayFlatten([getNewBandNames('sd')]); // Turn the PCs into a P-band image, normalized by SD. return principalComponents // Throw out an an unneeded dimension, [[]] -> []. .arrayProject([0]) // Make the one band array image a multi-band image, [] -> image. .arrayFlatten([getNewBandNames('pc')]) // Normalize the PCs by their SDs. .divide(sdImage); };
import ee import geemap.core as geemap
Colab (Python)
def get_principal_components(centered, scale, region): # Collapse bands into 1D array arrays = centered.toArray() # Compute the covariance of the bands within the region. covar = arrays.reduceRegion( reducer=ee.Reducer.centeredCovariance(), geometry=region, scale=scale, maxPixels=1e9, ) # Get the 'array' covariance result and cast to an array. # This represents the band-to-band covariance within the region. covar_array = ee.Array(covar.get('array')) # Perform an eigen analysis and slice apart the values and vectors. eigens = covar_array.eigen() # This is a P-length vector of Eigenvalues. eigen_values = eigens.slice(1, 0, 1) # This is a PxP matrix with eigenvectors in rows. eigen_vectors = eigens.slice(1, 1) # Convert the array image to 2D arrays for matrix computations. array_image = arrays.toArray(1) # Left multiply the image array by the matrix of eigenvectors. principal_components = ee.Image(eigen_vectors).matrixMultiply(array_image) # Turn the square roots of the Eigenvalues into a P-band image. sd_image = ( ee.Image(eigen_values.sqrt()) .arrayProject([0]) .arrayFlatten([get_new_band_names('sd')]) ) # Turn the PCs into a P-band image, normalized by SD. return ( # Throw out an an unneeded dimension, [[]] -> []. principal_components.arrayProject([0]) # Make the one band array image a multi-band image, [] -> image. .arrayFlatten([get_new_band_names('pc')]) # Normalize the PCs by their SDs. .divide(sd_image) )
L'entrée de la fonction est une image de moyenne nulle, une échelle et une région sur laquelle effectuer l'analyse. Notez que les images d'entrée doivent d'abord être converties en image de tableau à une dimension, puis réduites à l'aide de ee.Reducer.centeredCovariance()
. Le tableau renvoyé par cette réduction est la matrice de variance-covariance symétrique de l'entrée.
Utilisez la commande eigen()
pour obtenir les valeurs propres et les vecteurs propres de la matrice de covariance. La matrice renvoyée par eigen()
contient les valeurs propres à la position 0 de l'axe 1. Comme indiqué dans la fonction précédente, utilisez slice()
pour séparer les valeurs propres et les vecteurs propres. Chaque élément le long de l'axe 0 de la matrice des vecteurs propres est un vecteur propre. Comme dans l'exemple de casquette à pompon (TC), effectuez la transformation en multipliant la matrice arrayImage
par les vecteurs propres.
Dans cet exemple, chaque multiplication d'un vecteur propre donne lieu à un PC.