Hello,
I am encountering an issue while translating a Google Earth Engine (GEE) script to OpenEO.
In GEE, I developed a script that calculates the monthly median NDVI from Sentinel-2 L2A data, applying a cloud mask using the SCL band. I have attempted to translate this script for use with OpenEO, using the CDSE back-end.
However, I am observing significant differences in the resulting NDVI values and I am unable to determine the cause.
In particular, I have the following questions:
- Are there any differences between the two datasets (GEE vs. CDSE)?
- Are there differences in how missing or invalid values are handled when computing the median after applying the mask? (It seems not, since I have the same issue even without applying the mask.)
Thank you in advance for your help.
GEE script:
// 1. Import de la ROI
var roi = ee.FeatureCollection("projects/ee-leolgrcsigma/assets/roi");
Map.centerObject(roi, 11);
Map.addLayer(roi, {color: 'red', fillColor: '00000000'}, 'ROI');
// 2. Masque des nuages Sentinel-2
function maskS2clouds(image) {
var scl = image.select('SCL');
var mask = scl.neq(3).and(scl.neq(9)).and(scl.neq(8)).and(scl.neq(10));
return image.updateMask(mask);
}
// 3. Calcul NDVI
function addNDVI(image) {
var ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI');
return image.addBands(ndvi);
}
// 4. Période : septembre 2022
var startDate = '2022-09-01';
var endDate = '2022-09-30';
// 5. Chargement de Sentinel-2 et traitement
var s2 = ee.ImageCollection('COPERNICUS/S2_SR')
.filterBounds(roi)
.filterDate(startDate, endDate)
.map(maskS2clouds)
.map(addNDVI);
// 6. Calcul NDVI médian
var ndvi_median = s2.select('NDVI').median().clip(roi);
// 7. Affichage
Map.addLayer(ndvi_median, {min: -1, max: 1, palette: ['brown','white','green']}, 'NDVI_median_Sep_2022');
// 8. Export vers Google Drive
Export.image.toDrive({
image: ndvi_median,
description: 'NDVI_median_Sep_2022_roi',
scale: 10,
region: roi,
crs: 'EPSG:4326',
maxPixels: 1e13
});
OpenEO script :
import openeo
import rasterio
import matplotlib.pyplot as plt
connection = openeo.connect("openeo.dataspace.copernicus.eu").authenticate_oidc()
caen = {"west": -0.39291668372321487, "south": 49.121819796877894, "east": -0.0411832949045951441, "north": 49.31929639176561}
t = ["2022-09-01", "2022-09-30"]
datacube = connection.load_collection(
"SENTINEL2_L2A",
spatial_extent = caen,
temporal_extent = t,
bands = ["B04", "B08", "SCL"],
max_cloud_cover=100,
)
SCL = datacube.band("SCL")
mask = ((SCL == 3) | (SCL == 8) | (SCL == 9) | (SCL == 10))
datacube_masked = datacube.mask(mask)
# Calcul du NDVI
ndvi = datacube_masked.process("ndvi", {
"data": datacube_masked,
"nir": "B08",
"red": "B04"
})
# Médiane temporelle
ndvi_median = ndvi.reduce_dimension(
dimension="t",
reducer="median"
)
# Téléchargement
ndvi_median.download("median_ndvi.tif")
# Visualisation
with rasterio.open("median_ndvi.tif") as src:
data = src.read(1)
plt.imshow(data, cmap="YlGn", vmin=-1, vmax=1)
plt.colorbar(label="NDVI")
plt.title("NDVI Médian 2023")
plt.show()