La trasformazione dei componenti principali (PC) (nota anche come trasformazione di Karhunen-Loeve) è una rotazione spettrale che prende i dati delle immagini correlati spettralmente e genera dati non correlati. La trasformazione PC lo ottiene diagonalizzando la matrice di correlazione delle bande di input tramite l'analisi degli autovalori. Per farlo in Earth Engine, utilizza un riduttore di varianza su un'immagine array e il comando eigen()
sull'array di varianza risultante.
A questo scopo, considera la seguente funzione (un esempio di applicazione è disponibile come
script di Code Editor
e come notebook di Colab).
Editor di codice (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'input della funzione è un'immagine con media zero, una scala e una regione su cui eseguire l'analisi. Tieni presente che le immagini di input devono prima essere convertite in un'immagine array 1D e poi ridotte utilizzando ee.Reducer.centeredCovariance()
. L'array restituito da questa riduzione è la matrice di varianza-covarianza simmetrica dell'input.
Utilizza il comando eigen()
per ottenere i valori propri e gli autovettori della
matrice di covarianza. La matrice restituita da eigen()
contiene i valori propri
nella posizione 0 dell'asse 1. Come mostrato nella funzione precedente, utilizza slice()
per separare gli autovalori e gli autovettori. Ogni elemento lungo l'asse 0 della
matrice eigenVectors è un autovettore. Come nell'esempio del berretto con fiocco, esegui la trasformazione moltiplicando per matrice arrayImage
per gli autovalori.
In questo esempio, ogni moltiplicazione di vettori autovalori genera un PC.