𝗟𝗮𝗻𝗱 𝗰𝗼𝘃𝗲𝗿 𝗰𝗹𝗮𝘀𝘀𝗶𝗳𝗶𝗰𝗮𝘁𝗶𝗼𝗻 𝘂𝘀𝗶𝗻𝗴 𝘀𝘂𝗽𝗲𝗿𝘃𝗶𝘀𝗲𝗱 𝗹𝗲𝗮𝗿𝗻𝗶𝗻𝗴 𝗺𝗲𝘁𝗵𝗼𝗱 𝗶𝗻 𝗚𝗼𝗼𝗴𝗹𝗲 𝗘𝗮𝗿𝘁𝗵 𝗘𝗻𝗴𝗶𝗻𝗲¶
Written by Men Vuthy, 2022
Overview
In this project, I try to classify the land use land cover using Random Forest Classifier in Google Earth Engine by:
using the images from Sentinel-2 satellite in January 2022
using Random Forest Classifier with parameter of 300 trees
using the training data from 1000 random points with the label from ESA WorldCover dataset.
Objective
Classify land use and land cover in Google Earth Engine and then visualize it in GEE App.
Code
The script to classify the land cover type is detailed as follows:
var roi = ee.Geometry.Polygon([[[103.63665096774587, 13.584793535905758],
[103.63665096774587, 13.264209644744009],
[104.07061092868337, 13.264209644744009],
[104.07061092868337, 13.584793535905758]]], null, false);
var baseChange = [{featureType: 'all', stylers: [{invert_lightness: true}]}];
Map.setOptions('baseChange', {'baseChange': baseChange});
Map.centerObject(roi, 10)
/**
* Function to mask clouds using the Sentinel-2 QA band
* @param {ee.Image} image Sentinel-2 image
* @return {ee.Image} cloud masked Sentinel-2 image
*/
function maskS2clouds(image) {
var qa = image.select('QA60');
// Bits 10 and 11 are clouds and cirrus, respectively.
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
.and(qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.updateMask(mask).divide(10000);
}
var dataset = ee.ImageCollection('COPERNICUS/S2_SR')
.filterDate('2022-01-01', '2022-01-30')
// Pre-filter to get less cloudy granules.
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',5))
.map(maskS2clouds);
var visualization = {
min: 0.0,
max: 0.3,
bands: ['B4', 'B3', 'B2'],
};
var img = ee.Image(dataset.mean()).select('B.*');
// ESA WorldCover land cover map, used as label source in classifier training.
var lc = ee.Image('ESA/WorldCover/v100/2020');
// Remap the land cover class values to a 0-based sequential series.
var classValues = [10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 100];
var remapValues = ee.List.sequence(0, 10);
var label = 'lc';
lc = lc.remap(classValues, remapValues).rename(label).toByte();
// Add land cover as a band of the reflectance image and sample 100 pixels at
// 10 m scale from each land cover class within a region of interest.
var sample = img.addBands(lc).stratifiedSample({
numPoints: 1000,
classBand: label,
region: roi,
scale: 10,
geometries: true
});
// Add a random value field to the sample and use it to approximately split 80%
// of the features into a training set and 20% into a validation set.
sample = sample.randomColumn();
var trainingSample = sample.filter('random <= 0.8');
var validationSample = sample.filter('random > 0.8');
// Train a 10-tree random forest classifier from the training sample.
var trainedClassifier = ee.Classifier.smileRandomForest(300).train({
features: trainingSample,
classProperty: label,
inputProperties: img.bandNames()
});
// Get information about the trained classifier.
print('Results of trained classifier', trainedClassifier.explain());
// Get a confusion matrix and overall accuracy for the training sample.
var trainAccuracy = trainedClassifier.confusionMatrix();
print('Training error matrix', trainAccuracy);
print('Training overall accuracy', trainAccuracy.accuracy());
// Get a confusion matrix and overall accuracy for the validation sample.
validationSample = validationSample.classify(trainedClassifier);
var validationAccuracy = validationSample.errorMatrix(label, 'classification');
print('Validation error matrix', validationAccuracy);
print('Validation accuracy', validationAccuracy.accuracy());
// Classify the reflectance image from the trained classifier.
var imgClassified = img.classify(trainedClassifier);
// Add the layers to the map.
var classVis = {
min: 0,
max: 10,
palette: ['006400' ,'b59475', '77a123', '9b7653', 'fa0000', 'c3d593',
'f0f0f0', '0064c8', '0096a0', '00cf75', 'fae6a0']
};
Map.addLayer(img.clip(roi), {bands: ['B11', 'B8', 'B3'], min: 0, max: 0.5}, 'img');
Map.addLayer(lc.clip(roi), classVis, 'lc', false);
Map.addLayer(imgClassified.clip(roi), classVis, 'Classified');
Map.addLayer(roi, {color: 'white'}, 'ROI', false, 0.5);
Map.addLayer(trainingSample, {color: 'yellow'}, 'Training sample', false);
Map.addLayer(validationSample, {color: 'white'}, 'Validation sample', false);
//----------------------------- Display legend on the map --------------------------//
var panel = ui.Panel({
style: {
position: 'bottom-left',
padding: '5px;'
}
})
var title = ui.Label({
value: 'Classification',
style: {
fontSize: '14px',
fontWeight: 'bold',
margin: '0px;'
}
})
panel.add(title)
var color = ['006400' ,'b59475', '77a123', '9b7653', 'fa0000', 'c3d593',
'f0f0f0', '0064c8', '0096a0', '00cf75', 'fae6a0']
var lc_class = ['Trees', 'Shrubland', 'Grassland', 'Cropland', 'Built-up',
'Barren / sparse vegetation', 'Snow and ice', 'Open water', 'Herbaceous wetland',
'Mangroves', 'Moss and lichen']
var list_legend = function(color, description) {
var c = ui.Label({
style: {
backgroundColor: color,
padding: '10px',
margin: '4px'
}
})
var ds = ui.Label({
value: description,
style: {
margin: '5px'
}
})
return ui.Panel({
widgets: [c, ds],
layout: ui.Panel.Layout.Flow('horizontal')
})
}
for(var a = 0; a < 11; a++){
panel.add(list_legend(color[a], lc_class[a]))
}
Map.add(panel)
Result in GEE App
