特徵值分析

主要元件 (PC) 轉換 (也稱為 Karhunen-Loeve 轉換) 是一種光譜旋轉,可擷取光譜相關聯的圖像資料,並輸出不相關的資料。PC 轉換會透過特徵值分析,將輸入頻帶相關矩陣對角化,以達成這項目標。如要在 Earth Engine 中執行這項操作,請在陣列圖像上使用共變異數縮減器,並在產生的共變異數陣列上使用 eigen() 指令。請考慮使用下列函式來達成這個目的 (應用程式中的範例可做為 Code Editor 指令碼Colab 筆記本)。

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);
};

請參閱「 Python 環境」頁面,瞭解 Python API 和如何使用 geemap 進行互動式開發。

import ee
import geemap.core as geemap
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)
  )

函式輸入內容為平均值為零的圖片、比例和要執行分析的區域。請注意,輸入的圖像必須先轉換為 1D 陣列圖像,然後再使用 ee.Reducer.centeredCovariance() 進行縮減。這項縮減作業傳回的陣列,是輸入內容的對稱差異-共變異矩陣。使用 eigen() 指令取得協方差矩陣的固有值和固有向量。eigen() 傳回的矩陣包含 1 軸第 0 個位置的固有值。如前述函式所示,請使用 slice() 分隔特徵值和特徵向量。沿著特徵向量陣列的 0 軸的每個元素都是特徵向量。如同流蘇帽 (TC) 範例所示,透過矩陣將 arrayImage 乘以特徵向量,執行轉換作業。在本例中,每個特徵向量相乘結果都會產生 PC。