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