Last active
August 6, 2025 16:05
-
-
Save 7yl4r/f1e3889911c50ce08189e5daaf80e22e to your computer and use it in GitHub Desktop.
Claudia's Placencia mangrove
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
MANGROVE CLASSIFICATION SCRIPT | |
For Placencia 2025 USING SENTINEL 2 | |
2025/06/09 | |
Claudia Baron-Aguilar | |
Previous steps. | |
1. Selection of best image (Using Image selection code) | |
2. selection of positive and negative goriud-truth points | |
(Creating List of coordinates code with anotehr code) | |
3. Build ground-Truth matrix with positive and negative points | |
with data from step 2 (Presence-absence/ gt_data import above) | |
Steps. | |
1. Load image | |
2. Preprocess image | |
3. Sample data | |
4. Train model & Classify | |
5. Accuracy assessment | |
*/ | |
//////////////////////////////////////////////////////////////////////////// | |
// 1. LOAD IMAGE // | |
//////////////////////////////////////////////////////////////////////////// | |
// Previously obtained with "seleccion_imagen" code | |
// Image ID | |
var id = '20250321T161011_20250321T161849_T16QCD'; | |
//Load image | |
var image = ee.Image('COPERNICUS/S2_SR_HARMONIZED/' + id); | |
// see image | |
print (image); | |
// Apply scale factor to the Image | |
var scaledImage = image.multiply(0.0001); | |
// Print Scaled Image to the console to inspect | |
print('scaledImage',scaledImage); | |
var image = scaledImage; //Image is now equal to scaled Image | |
//COLOR PALETTES (RGB)// | |
var visualization = { | |
min: 0.0, | |
max: 0.3, | |
gamma:2, | |
bands: ['B4', 'B3', 'B2'], | |
}; | |
//Visualize Image | |
Map.addLayer(image, visualization,"image"); | |
//Now we have an Image that is ready to be processed | |
////////////////////////////////////////////////////////////////////// | |
// // 2. IMAGE PREPROCESSING // | |
// /////////////////////////////////////////////////////////////////// | |
//Calculate the ndvi (Normalized Difference Vegetation Index) | |
var ndvi = image.normalizedDifference(['B8','B4']); | |
print ('ndvi', ndvi); | |
var ndviVis = {min: -1, max: 1, palette: ['blue', 'white', 'green']}; | |
Map.addLayer(ndvi, ndviVis, 'ndvi'); | |
//Create Mask where NDVI is greater than the threshold | |
var ndviMask = ndvi.gte(0.25); | |
//Apply the ndvi mask to the image | |
var maskedImage = image.updateMask(ndviMask); | |
print ('maskedImage', maskedImage); | |
Map.addLayer (maskedImage, visualization, 'maskedImage'); | |
// // // //////////////////////////////////////////////////////////////////////////// | |
// // // // 3. SAMPLE DATA // | |
// // // //////////////////////////////////////////////////////////////////////////// | |
// Ground truth data | |
var data = gt_data; | |
print('Class Codes', data.aggregate_array('class').distinct()); | |
// class Codes are: | |
// 0: no mangrove | |
// 1: mangrove | |
print('Ground truth Points per class', data.aggregate_histogram('class')); | |
// Number of ground truth points per class | |
// 0:362 | |
// 1: 40 | |
//select bands to sample | |
var samplingBands = ['B2', 'B3', 'B4','B5','B6','B7','B8','B8A','B9','B11','B12']; | |
// Sample multi-espectral dara using all ground truth points | |
var sampleData = maskedImage.select(samplingBands).sampleRegions({ | |
collection:data, | |
properties: ['class'], | |
scale: 10}); | |
// Generate random numbers from 0 to 1 for each sampled class. | |
var random = sampleData.randomColumn('random'); | |
print ('random', random); | |
// Split ground truth data:70% for training and 30% for validation, | |
// to use in the classification model training | |
var trainingPoints = random.filter(ee.Filter.lt('random', 0.7)); | |
var validationPoints = random.filter(ee.Filter.gte('random', 0.3)); | |
print('Training Samples (70%)', trainingPoints); | |
// // // //////////////////////////////////////////////////////////////////////////// | |
// // // // 4. TRAIN MODEL & CLASSIFY // | |
// // // //////////////////////////////////////////////////////////////////////////// | |
//Define and train the classifier. In this case the SVM Classifier. | |
var SVM = ee.Classifier.libsvm ({ | |
kernelType:'RBF', | |
// Low gamma measn less curvature. | |
// High gamma means more curvature. | |
// Range between 0.001 and 100 | |
gamma: 4, | |
// Low cost: smooth decision surface. | |
// Higher cost: you aim to classify more points correctly | |
// (more missclassification possible). | |
// Range between 1 and 1000 | |
cost: 50 | |
}); | |
var model = SVM.train({ | |
features:trainingPoints, | |
classProperty: 'class', | |
inputProperties: samplingBands | |
}); | |
// Classify the image using the trained classifier | |
var classified = maskedImage.classify(model); | |
// Define a palette for the distint classes | |
var classPalette = {min:0, max:1, plaette:['#3090C7','#CD7F32']}; | |
// Dis[play map with classification | |
Map.addLayer(classified, classPalette,"SVM classification",false); | |
// Display presence pixels ONLY (Useful to export layer of only mangrove to QGis) | |
var class1Mask = classified.eq(1); | |
var class1Image = classified.updateMask(class1Mask); | |
Map.addLayer(class1Image, {}, "class1"); | |
//We crate a mask associated to a polygon to clean the image in the more inland areas where | |
//we know there is not mangrove | |
var class1ImageMasked = class1Image.updateMask( | |
ee.Image.constant(1).clip(inlandPolygon).mask().not() | |
); | |
Map.addLayer(class1ImageMasked, {}, 'clean class1'); | |
// // / //////////////////////////////////////////////////////////////////////////// | |
// // // // 5. ACCURACY ASSESSMENT // | |
// // // //////////////////////////////////////////////////////////////////////////// | |
// Calculate accuracy using validation data created in point 3 | |
// Classify the image using the trained classifier | |
var validation = validationPoints.classify(model); | |
// Get a confusion matrix representing expected accuracy (Using validation points- 30%) | |
var errorMatrix = validation.errorMatrix('class', 'classification'); | |
print('validation overall accuracy', errorMatrix.accuracy()); | |
//Estimate user and producer accuracies | |
var producerAccuracy = errorMatrix.producersAccuracy(); | |
var userAccuracy = errorMatrix.consumersAccuracy(); | |
print('Producer Acuracy SVM', producerAccuracy); | |
print('User Accuracy SVM', userAccuracy); | |
// The Kappa Coefficient is generated from a statistical test to evaluate the accuracy | |
// of a classification. Kappa evaluates how well the classification performed | |
// as compared to just randomly assigning values, i.e. did the classification do better | |
// than random. The Kappa Coefficient can range from -1 t0 1. A value of 0 indicated that | |
// the classification is no better than a random classification. A negative number | |
// indicates the classification is significantly worse than random. A value close to 1 | |
// indicates that the classification is significantly better than random. | |
var kappa = errorMatrix.kappa(); | |
print ('Kappa statistic', kappa); | |
////////////////////////////////////////////////////////////////////////////////////// | |
// // // 6. EXPORT SHAPE FILE TO DRIVE // // | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Si le cambias el nombre a la variable "roi", tambien tienes que cambiarlo en la linea "var region = roi ;" | |
// cambiar especificamente al area que quieres guardar | |
// The order of the coordinates goes as follows: | |
// [[[westLon, southLat], | |
// [eastLon, southLat], | |
// [eastLon, northLat], | |
// [westLon, northLat], | |
// [westLon, southLat]]]); // repetiddo como la primera | |
var roi = // south area -Belize- | |
ee.Geometry.Polygon( | |
[[[ -88.13157854678775,16.46213607050848], | |
[-88.13157854678775,16.84992519338283], | |
[-88.46631111711997,16.84992519338283], | |
[-88.46631111711997,16.46213607050848], | |
[-88.13157854678775,16.46213607050848]]]); | |
// Save the cleaned Sentinel Mosaic RGB at full resolution | |
var description = 'export_Mnagrove_layer_geotiff_' ; // Description for the export task | |
var region = roi ; // Region of interest described above | |
var scale = 10 ; // Spatial resolution in meters. Put here the resolution of you image/satellite. | |
var crs = 'EPSG:4326' ; // Coordinate reference system (WGS 84) | |
var maxPix = 1e13 ; // Maximun number of pixels alloed for export | |
var fileNamePre = 'Mangrove_Placencia_2025' ; // Name the file to save | |
Export.image.toDrive({ | |
image: class1ImageMasked, // The image variable you want to export | |
description: description, | |
region: region, | |
scale: scale, | |
fileFormat: 'GeoTIFF', | |
fileNamePrefix: fileNamePre, | |
crs: crs, | |
maxPixels: maxPix, | |
skipEmptyTiles: true | |
}) ; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment