2

I'm running a script on GEE to download EVI images from a certain time period and place, and also the cloud masks from each image calculated from the QA60 band with the following function. But the mask I always export gives me all 1s, even when it's cloudy. Why could this be?

function maskS2clouds(image) {
  // Seleccionar la banda 'QA60' de la imagen.
  var qa = image.select('QA60');

  // Los bits 10 y 11 representan las nubes y el cirrus, respectivamente.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Crear una máscara donde 1 indica nubes y 0 indica condiciones despejadas.
  var mask = qa.bitwiseAnd(cloudBitMask).or(qa.bitwiseAnd(cirrusBitMask)).not();

  // Convertir la máscara a un formato uint8.
  var maskBand = mask.toUint8();

  // Renombrar la banda de la máscara.
  maskBand = maskBand.rename('cloudMask');

  // Devolver la imagen con la banda de la máscara añadida y la misma información de fecha.
  return image.addBands(maskBand).set('system:time_start', image.get('system:time_start'));
}

var colMask = col.map(maskS2clouds)
                .select('cloudMask');
                  

function exportmask(collection, folder, scale, region, crs) {
  var list = collection.toList(collection.size());
  var n = list.size().getInfo();
  for (var i = 0; i < n; i++) {
    var image = ee.Image(list.get(i));
    var id = campo + '_' + ee.Date(image.date().format('YYYY-MM-dd')).format('YYYYMMdd').getInfo() + '_mask';
    Export.image.toDrive({
      image: image.toUint8(),
      description: id,
      folder: folder,
      scale: scale,
      region: region,
      crs: 'EPSG:32720'
    });
  }
}

// Exportar todas las imágenes de la colección colEVI a Google Drive
exportmask(colMask, 'EVI_exports', 10, geometry);

2 Answers 2

2

I don't think anything is wrong with your code. It's QA60 that is really lousy. It's working bad enough that I wonder if something isn't wrong with the ingestion.

Clouds are detected in this image: ee.Image('COPERNICUS/S2_HARMONIZED/20171003T100009_20171003T100257_T32TQM'), but not this ee.Image('COPERNICUS/S2_HARMONIZED/20230505T100029_20230505T100612_T32TQM').

https://code.earthengine.google.com/addd0b59ea196bba514b49a8072d403b

You might want to consider using COPERNICUS/S2_CLOUD_PROBABILITY for cloud masking instead. It's slower but a lot better.

var geometry = Map.getBounds(true)
var cloudThreshold = 30 // Tweak to be more or less aggressive in the cloud masking

var filter = ee.Filter.and(
  ee.Filter.bounds(geometry),
  ee.Filter.date('2023-01-01', '2023-06-01')
)

var col = ee.ImageCollection(
    ee.Join.saveFirst('cloudProbability').apply({
        primary: ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
          .filter(filter)
          .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 75)), // Filter out really cloudy scenes up-front
        secondary: ee.ImageCollection('COPERNICUS/S2_CLOUD_PROBABILITY')
          .filter(filter),
        condition: ee.Filter.equals({leftField: 'system:index', rightField: 'system:index'})
    })
).map(maskClouds)

Map.addLayer(col.mosaic(), {bands: 'B4,B3,B2', max: 3000, gamma: 1.5})


function maskClouds(image) {
  var cloudFree = ee.Image(image.get('cloudProbability')).lt(cloudThreshold)
  return image.updateMask(cloudFree)
}
0

Thank you for your response. The curious thing is that I have downloaded the QA60 band from the Sentinel's page for a scene with clouds and the QA60 pixels mark it, but when I run it in GEE it doesn't work.

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Jun 3, 2023 at 12:39

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.