【问题标题】:Performing PCA per image over imageCollection in Google Earth Engine在 Google Earth Engine 中的 imageCollection 上对每个图像执行 PCA
【发布时间】:2020-06-18 16:34:35
【问题描述】:

我需要对图像集合中的每个图像执行 PCA。然后,我只想保留主组件轴 1,并将其作为一个带添加到我的图像集中的每个图像中。最终,我想导出一个 .csv 文件,其中行标题处的 GPS 采样位置和图像 ID 作为列标题,平均主成分轴 1 作为值。这样做背后的想法是,我想要一个代理(光谱异质性)用于 R 中的进一步统计分析。

这是我到目前为止的代码:

//Create an test image to extract information to be used during PCA
var testImage =ee.Image('LANDSAT/LC08/C01/T1_SR/LC08_168080_20130407')
.select(['B2', 'B3', 'B4', 'B5', 'B6', 'B7'],
        ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2']);

// Define variables for PCA
var region = Extent;
var scale = testImage.projection().nominalScale();
var bandNames = testImage.bandNames();
Map.centerObject(region);

// Function for performing PCA
function doPCA(image){
  // This code is from https://code.earthengine.google.com/7249153a8a0f5c79eaf562ed45a7adad
var meanDict = image.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: region,
    scale: scale,
    maxPixels: 1e9
});
var means = ee.Image.constant(meanDict.values(bandNames));
var centered = image.subtract(means);

// This helper function returns a list of new band names.
var getNewBandNames = function(prefix) {
  var seq = ee.List.sequence(1, bandNames.length());
  return seq.map(function(b) {
    return ee.String(prefix).cat(ee.Number(b).int());
  });
};

// [START principal_components]
var getPrincipalComponents = function(centered, scale, region) {
  var arrays = centered.toArray();
  var covar = arrays.reduceRegion({
    reducer: ee.Reducer.centeredCovariance(),
    geometry: region,
    scale: scale,
    maxPixels: 1e9
  });
  var covarArray = ee.Array(covar.get('array'));
  var eigens = covarArray.eigen();
  var eigenValues = eigens.slice(1, 0, 1);
  var eigenVectors = eigens.slice(1, 1);
  var arrayImage = arrays.toArray(1);
  var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage);
  var sdImage = ee.Image(eigenValues.sqrt())
    .arrayProject([0]).arrayFlatten([getNewBandNames('sd')]);
  return principalComponents
    .arrayProject([0])
    .arrayFlatten([getNewBandNames('pc')])
    .divide(sdImage);
};
var pcImage = getPrincipalComponents(centered, scale, region);
return (pcImage);
}

// map PCA function over collection
var PCA = LandsatCol.map(function(image){return doPCA(image)});
print('pca', PCA);

Extent 是我的 ROI,而LandsatCol 是经过预处理的图像集合。尝试将 PCA 映射到图像集合(代码的倒数第二行)时,此处的代码会产生错误。错误显示:“数组:需要参数‘值’”。

关于如何处理这个问题有什么建议吗?以及如何在图像集合中添加主成分轴 1 作为每个图像的带?

【问题讨论】:

    标签: javascript pca google-earth-engine


    【解决方案1】:

    我想通了。错误“Array: Parameter 'values' is required”与稀疏矩阵有关,稀疏矩阵是执行 PCA 的过滤、裁剪和指定区域的产物。 Earth Engine 无法处理稀疏矩阵。

    这是工作代码。 LandsatCol 是我的预处理图像集。

    // Display AOI
    var point = ee.Geometry.Point([30.2261, -29.458])
    Map.centerObject(point,10);
    
    // Prepairing imagery for PCA
    var Preped = LandsatCol.map(function(image){
      var orig = image;
      var region = image.geometry();
      var scale = 30;
      var bandNames = ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2'];
      var meanDict = image.reduceRegion({
        reducer: ee.Reducer.mean(),
        geometry: region,
        scale: scale,
        maxPixels: 1e9
      });
      var means = ee.Image.constant(meanDict.values(bandNames));
      var centered = image.subtract(means);
      var getNewBandNames = function(prefix) {
      var seq = ee.List.sequence(1, 6);
      return seq.map(function(b) {
        return ee.String(prefix).cat(ee.Number(b).int());
        });
      };
    
      // PCA function
      var getPrincipalComponents = function(centered, scale, region) {
        var arrays = centered.toArray();
        var covar = arrays.reduceRegion({
          reducer: ee.Reducer.centeredCovariance(),
          geometry: region,
          scale: scale,
          maxPixels: 1e9
        });
        var covarArray = ee.Array(covar.get('array'));
        var eigens = covarArray.eigen();
        var eigenValues = eigens.slice(1, 0, 1);
        var eigenVectors = eigens.slice(1, 1);
        var arrayImage = arrays.toArray(1);
        var principalComponents = ee.Image(eigenVectors).matrixMultiply(arrayImage);
        var sdImage = ee.Image(eigenValues.sqrt())
        .arrayProject([0]).arrayFlatten([getNewBandNames('sd')]);
        return principalComponents.arrayProject([0])
        .arrayFlatten([getNewBandNames('pc')])
        .divide(sdImage);
        };
    
      var pcImage = getPrincipalComponents(centered, scale, region);
      return ee.Image(image.addBands(pcImage));
    });
    print("PCA imagery: ",Preped);
    
    

    【讨论】:

      猜你喜欢
      • 2021-07-21
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多