7

I'm trying to count the number of pixels that are masked by the cloud mask of the image collection given by the Earth Engine dataset. I have clipped my collection with a ROI and now I want to keep the images with 10% or less of clouds (masked pixels). By now, I am only able to count them for a single image but not for the entire collection.

I am now using this code for one image but I am not able to reproduce this for the entire collection.

var Peyto_pixelscount = Peytoclip.first().select('ALBEDO').reduceRegion({
  reducer: ee.Reducer.count(),
  geometry: Peyto_glacier.geometry(),
  scale: 30,
  maxPixels: 1e9
});

print(Peyto_pixelscount)
1
  • Thanks for the edit. You could also add a working example of your current code and your (erroneous) trials, then the question is quite complete.
    – Erik
    Jun 2, 2020 at 14:54

2 Answers 2

12

To get to your end goal of filtering your clipped image collection by 10% or less cloud cover, I would write a function that:

  1. counts the number of unmasked pixels in the image
  2. counts the number of pixels in the unmasked image
  3. calculates the percentage of masked pixels and sets this as a metadata property

I would then map this onto your image collection and filter it by the added metadata property.

Note that I'm assuming that your images are only masked by a cloud mask.


function get_cloud_cover_roi(image){ 

  var Peyto_pixelscount = image.select('ALBEDO').reduceRegion({
    reducer: ee.Reducer.count(),
    geometry: image.geometry(),
    scale: 30,
    maxPixels: 1e9
  }).get('ALBEDO')

  var npix = image.select('ALBEDO').unmask().reduceRegion({
    reducer: ee.Reducer.count(),
    geometry: image.geometry(),
    scale: 30,
    maxPixels: 1e9
  }).get('ALBEDO')

  var cloud_cover_roi = ee.Number(1)
      .subtract(ee.Number(Peyto_pixelscount).divide(npix))
      .multiply(100)

  return image.set('cloud_cover_roi', cloud_cover_roi)

}

var Peytoclip_filtered = Peytoclip
    .map(get_cloud_cover_roi)
    .filterMetadata('cloud_cover_roi', 'less_than', 10)

2
  • Thank you ! You are awsome.
    – laurent
    Jun 2, 2020 at 19:30
  • 4
    Hi @laurent, it looks like this answer satisfies your question. If so, would you kindly accept the answer (click check mark below vote tally) so that question browsers know that this is a completed Q&A. If a more suitable answer comes along in the future, you can always change the accepted answer. Jun 4, 2020 at 23:25
3

Similar logic to the previous answer but in a function call.

geom could be any region in the image, or image.geometry() for the whole image.

/** 
 * return the percentage of masked pixels in an image region. 
 */
function calculateMaskedPercent(image, band, geom) {
   var maskedPixelCount = image.select(band).reduceRegion({
    reducer: ee.Reducer.count(),
    geometry: geom,
    scale: 30,
    maxPixels: 1e9
  }).get(band);

  var totalPixelCount  = image.unmask().select(band).reduceRegion({
    reducer: ee.Reducer.count(),
    geometry: geom,
    scale: 30,
    maxPixels: 1e9
  }).get(band);
 
  var cloud_cover_roi = ee.Number(1)
      .subtract(ee.Number(maskedPixelCount).divide(totalPixelCount))
      .multiply(100)
  return cloud_cover_roi;
}

2
  • Thank you! I rewrote that to python (which I needed) and it solved my problem!
    – Kongie
    May 31 at 13:23
  • Glad its helpful. You can post your python code as another answer.
    – intotecho
    Jun 5 at 7:53

Your Answer

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

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