2

My goal is to Filter an ImageCollection to contain only Images with uniform coverage within a given AOI (Images that have to 'holes' / masked pixels within an AOI). I'm trying to do it by mapping the collection over ee.Reducer.allNonZero() setting isNotEmpty flag and then filtering images by corresponding flags.

This is a script I created (EE code version):

var NO2_coll = ee.ImageCollection("COPERNICUS/S5P/OFFL/L3_NO2")
                .select('tropospheric_NO2_column_number_density');

var aoi = ee.Geometry.Polygon(ee.List([
  [9.18804289906566, 45.468566496899996], [10.203754688320892, 45.468566496899996], 
  [10.203754688320892,45.695567257444594], [9.18804289906566, 45.695567257444594],
  [9.18804289906566, 45.468566496899996]]));

var date_from = '2020-01-04';
var date_to = '2020-01-05'; 

function setEmptyFlag (image) {
  var isNotEmpty = image.reduceRegion({
    reducer: ee.Reducer.allNonZero(),
    geometry: aoi,
    scale: 7000,
  }).values().get(0);

  return image.set('isNotEmpty', isNotEmpty);
}

var coll_filt = NO2_coll.filterBounds(aoi).filter(ee.Filter.date(date_from, date_to));

var coll_with_zero_flag = coll_filt.map(setEmptyFlag);

var coll_filt_clean = coll_with_zero_flag.filterMetadata('isNotEmpty', 'equals', 1);

var single_scene = coll_filt_clean.first();

Map.addLayer(aoi);
Map.addLayer(single_scene);
Map.centerObject(aoi);

But ee.Reducer.allNonZero() always returnes '1' no matter the presence of masked pixels within AOI.

How do I fix it?

1

Not sure if this is what you are looking for, but similarly I was once searching for images which cover my study area with a user-defined number of pixels. Therefore, I estimated the percentage of pixels covering the aoi. I think this might help you achieving your goal.

// Function to filter out images which do not fully cover the study area
function getCover(image, aoi, scale) {

    // calculate the number of inputs 
    var totPixels = ee.Number(image.unmask(1).reduceRegion({
      reducer: ee.Reducer.count(),
      scale: scale,
      geometry: aoi,
    }).values().get(0));

    // Calculate the actual amount of pixels inside the aoi
    var actPixels = ee.Number(image.reduceRegion({
      reducer: ee.Reducer.count(),
      scale: scale,
      geometry: aoi,    
    }).values().get(0));

    // calculate the perc of cover
    var percCover = actPixels.divide(totPixels).multiply(100).round();

  // number as output
  return image.set('percCover', percCover);
}

var coll_filt = NO2_coll.filterBounds(aoi).filter(ee.Filter.date(date_from, date_to));

var coll_with_zero_flag = coll_filt.map(function(image){
  return getCover(image, aoi, 7000);
});

print('List of percentage of covers',coll_with_zero_flag.aggregate_array('percCover'))

You can then set a minimum percentage to filter your image collection. link code

EDIT: Note that if you have a bounded image, unmask() does not add pixels outside the image area. See here for another example.

| improve this answer | |
  • Thank you, @Kuik, this is pretty close! Could you just explain why ee.Reducer.allNonZero() is not a right tool for this? – Basile Mar 19 at 5:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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