0

I conducted a landcover classification, distinguishing between mangrove and non-mangrove areas. For each landcover type, I gathered fewer than 10 samples. I utilized Random Forest (RF) for classification. Yet, when attempting to add the results to the map using Map.addLayer, I encountered an error signaling computed value is too large. Could you assist me in resolving this issue? Here's my code:

var guyana = ee.FeatureCollection("FAO/GAUL/2015/level0").filter(ee.Filter.eq("ADM0_NAME", 'Guyana'));

// Function to remove cloud and snow pixels from Sentinel-2 SR image

function maskCloudAndShadowsSR(image) {
  var cloudProb = image.select('MSK_CLDPRB');
  var snowProb = image.select('MSK_SNWPRB');
  var cloud = cloudProb.lt(10);
  var scl = image.select('SCL'); 
  var shadow = scl.eq(3); // 3 = cloud shadow
  var cirrus = scl.eq(10); // 10 = cirrus
  // Cloud probability less than 10% or cloud shadow classification
  var mask = cloud.and(cirrus.neq(1)).and(shadow.neq(1));
  return image.updateMask(mask);
}
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED');
var filtered = s2
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 30))
  .filter(ee.Filter.date('2019-01-01', '2019-12-31'))
  .filter(ee.Filter.bounds(guyana))
  .map(maskCloudAndShadowsSR)
  .select('B.*')

var composite = filtered.median().clip(guyana) 

var addIndices = function(image) {
  // compute NDVI
  var ndvi = image.normalizedDifference(['B8', 'B4']).rename(['ndvi']);
  // compute MNDWI
  var mndwi = image.normalizedDifference(['B3', 'B11']).rename(['mndwi']); 
  // compute GVCI
  var gcvi = image.expression('(NIR/GREEN) - 1', {
    'NIR': image.select('B8'),
    'GREEN': image.select('B3')
  }).rename("gcvi");
  // compute BSI
  var bsi = image.expression(
      '(( X + Y ) - (A + B)) /(( X + Y ) + (A + B)) ', {
        'X': image.select('B11'), //swir1
        'Y': image.select('B4'),  //red
        'A': image.select('B8'), // nir
        'B': image.select('B2'), // blue
  }).rename('bsi');
  // compute SR (Simple Ratio)
  var sr = image.select('B8').divide(image.select('B4')).rename('sr');
  var ratio54 = image.select('B11').divide(image.select('B8')).rename('r54');
  var ratio35 = image.select('B4').divide(image.select('B11')).rename('r35');
  return image.addBands(ndvi)
              .addBands(mndwi)
              .addBands(gcvi)
              .addBands(bsi)
              .addBands(sr)
              .addBands(ratio54)
              .addBands(ratio35);
}

composite = addIndices(composite);


// Calculate Slope and Elevation
var srtm = ee.Image("USGS/SRTMGL1_003");
var elev = srtm.select('elevation').clip(aoi).rename('elev');
var slope = ee.Terrain.slope(srtm.select('elevation')).rename('slope');
var visParams = {bands: ['B4', 'B3', 'B2'], min: 0, max: 3000, gamma: 1.2};
var mangroveVizParams = {bands: ['B8', 'B4', 'B3'], min: 0, max: 3000, gamma: 1.2};
var composite = composite.addBands(elev).addBands(slope);
var guyana_mangrove = composite.clip(aoi);

// create masks to dileanate mangrove areas
// remove areas with too high elevation
var elevationMask = elev.lt(65);
// remove areas with low vegetation cover
var ndviMask = guyana_mangrove.select("ndvi").gt(0.25);
// remove areas that are not associated with water
var mndwiMask = guyana_mangrove.select("mndwi").gt(-0.5);

guyana_mangrove = guyana_mangrove
                        .updateMask(elevationMask)
                        .updateMask(ndviMask)
                        .updateMask(mndwiMask);
// add layer to map
// Map.addLayer(composite, visParams, "Guyana 2019");
// Map.addLayer(guyana_mangrove, mangroveVizParams, "Guyana Mangrove 2019");
Map.centerObject(aoi, 7);

// **************************Training Sample Collection**************
// merge training samples
var training_samples = Mangrove_2019.merge(nonMangrove_2019);
print(training_samples)

// define bands to be included in model
var spectral_subset = ['B8', 'B4', 'B3', 'ndvi', 'mndwi', 'gcvi'];

// perform spectral subset
var imagery_guyana = guyana_mangrove.select(spectral_subset).clip(aoi);
// assemble samples for model
var samples = imagery_guyana.sampleRegions({
  collection: training_samples,
  properties: ['landcover'],
  scale: 10
}).randomColumn('random');

function normalize(image){
  var bandNames = image.bandNames();
  // Compute min and max of the image
  var minDict = image.reduceRegion({
    reducer: ee.Reducer.min(),
    geometry: guyana,
    scale: 20,
    maxPixels: 1e9,
    bestEffort: true,
    tileScale: 16
  });
  var maxDict = image.reduceRegion({
    reducer: ee.Reducer.max(),
    geometry: guyana,
    scale: 20,
    maxPixels: 1e9,
    bestEffort: true,
    tileScale: 16
  });
  var mins = ee.Image.constant(minDict.values(bandNames));
  var maxs = ee.Image.constant(maxDict.values(bandNames));

  var normalized = image.subtract(mins).divide(maxs.subtract(mins))
  return normalized
}

imagery_guyana = normalize(imagery_guyana);
// split samples into training and test sets
var split = 0.8;
// set up 80% of the data for training and 20% for testing the model accuracy
var training_set = samples.filter(ee.Filter.lt('random', split));
var test_set = samples.filter(ee.Filter.gte('random', split));


// set up classifier with 50 trees and 5 randomly selected predictors per split
var classifier = ee.Classifier.smileRandomForest(50, 5).train({
  features: training_set.select(['B4', 'B3', 'B2', 'ndvi', 'mndwi', 'gcvi', 'landcover']),
  classProperty: 'landcover',
  inputProperties: spectral_subset
});

// classify image
var landcover_2019 = imagery_guyana.select(spectral_subset).classify(classifier);
// add classified image to map
var classVizParams = {
  min: 1,
  max: 3,
  palette: ['#33a02c', '#fb9a99']
}
Map.addLayer(landcover_2019, classVizParams, "Landcover 2019");
// validate model accuracy
var test = landcover_2019.sampleRegions({
  collection: test_set,
  properties: ['landcover'],
  tileScale: 30,
  scale: 10,
});



var testConfusionMatrix = test.errorMatrix('landcover', 'classification')
var fc = ee.FeatureCollection([
  ee.Feature(null, {
    'overall accuracy': testConfusionMatrix.accuracy(),
    'producer accurary': testConfusionMatrix.producersAccuracy(),
    'consumer accuracy': testConfusionMatrix.consumersAccuracy(),
    'kappa statistic': testConfusionMatrix.kappa(),
    'matrix': testConfusionMatrix.array()
  })
]);

Export.table.toDrive({
  collection: fc,
  description: "Matrix_2019",
  folder: 'earthengine',
  fileFormat: 'CSV'
});

1 Answer 1

0

Whatever Mangrove_2019 and nonMangrove_2019 are, they're not in your script. Most likely, these are polygons, and sampleRegions is taking every pixel in those polygons, resulting in a training table thats too large. Use stratifiedSample to get a fixed/known/mangeable number of points.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.