1

I know that there are a lot of examples of how to mask clouds for sentiel-2 images, but what I want is sort the images over an area of interest without change anything of the image.

Applying a cloud mask in zones where there are to much clouds, changes dramatically the image (in this case in over Bogota-Colombia). And, in some cases it generates holes in the image. thats why i dont want to change anything about the image.

I am taking this code Filter Landsat images base on cloud cover over a region of interest as reference.

and here is how it will be with Sentinel-2 image.

//the parameter for sentiel-2 images for clouds is
//CLOUDY_PIXEL_PERCENTAGE
var ic =ee.ImageCollection('COPERNICUS/S2');

// A polygon representing the roi.
// my_polygon es a random polygon over Bogota Colombia (very cloudy zone)
var geometry = my_poligon;

var c = ic.filterBounds(geometry);

var withCloudiness = c.map(function(image) {
  var cloud = ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud');
  var cloudiness = cloud.reduceRegion({
    reducer: 'mean', 
    geometry: geometry, 
    scale: 30,
  });
  return image.set(cloudiness);
});

var filteredCollection = withCloudiness.filter(ee.Filter.lt('cloud', 10));
print(filteredCollection);                

//my image with less clouds over my zone of interest                   
var my_image = ee.Image(filteredCollection.filterBounds(centroid)
    .filterDate('2019-01-01', '2019-06-30')
    .sort('CLOUDY_PIXEL_PERCENTAGE')
    .first());                  
2

Cloud score algorithm is for Landsat scenes. You must use another algorithm to identify clouds. Since QA60 contains dense clouds information, you can use this band.

I posted before how to convert QA band by bits in Cloud mask for Landsat8 on Google Earth Engine, the approach is the same, so you code will mutate to:

//the parameter for sentiel-2 images for clouds is
//CLOUDY_PIXEL_PERCENTAGE
var ic =ee.ImageCollection('COPERNICUS/S2');

// A polygon representing the roi.
// my_polygon es a random polygon over Bogota Colombia (very cloudy zone)
var geometry = my_poligon;

var c = ic.filterBounds(geometry);

var getQABits = function(image, start, end, newName) {
    // Compute the bits we need to extract.
    var pattern = 0;
    for (var i = start; i <= end; i++) {
       pattern += Math.pow(2, i);
    }
    // Return a single band image of the extracted QA bits, giving the band
    // a new name.
    return image.select([0], [newName])
                  .bitwiseAnd(pattern)
                  .rightShift(start);
};

// A function to mask out cloudy pixels.
var clouds = function(image) {
  // Select the QA band.
  var QA = image.select(['QA60']);
  // Get the internal_cloud_algorithm_flag bit.
  return getQABits(QA, 10,10, 'cloud');
  // Return an image masking out cloudy areas.
};

var withCloudiness = c.map(function(image) {
  var cloud = clouds(image);
  var cloudiness = cloud.reduceRegion({
    reducer: 'mean', 
    geometry: geometry, 
    scale: 30,
  });
  return image.set(cloudiness);
});

var filteredCollection = withCloudiness.filter(ee.Filter.lt('cloud', 0.1));
print(filteredCollection);                

//my image with less clouds over my zone of interest                   
var my_image = ee.Image(filteredCollection.filterBounds(centroid)
    .filterDate('2019-01-01', '2019-06-30')
    .sort('CLOUDY_PIXEL_PERCENTAGE')
    .first());

NOTE: Now the filter isn't less than 10(%) of clouds, since the cloud image is 0 (no cloud) and 1 (cloud) use the fractional notation (0.1) to filter.

Finally, is right to use 'CLOUDY_PIXEL_PERCENTAGE' instead of 'cloud' for filter the less cloudy image over your study area? If you use it, you're filtering using the whole image, not your study area. You must consider changing the last sort operation

  • It is right that the second filter is taking in consideration the hole image. But, since you are filtering at the beginning the group of images given a Area of Interest (AOI). The filteredCollection should have the AOI without clouds, so it does not matter if you take in consideration the hole image. All results will give you the AOI clean for your use. Here is an example of this code.earthengine.google.com/d8f99b4f0f6ce0bad536c560ced330a0 – Camilo Lozano Sep 11 at 22:26
  • I correct myself, after doing lots of probes, it is necessary to use 'cloud' instead of 'CLOUDY_PIXEL_PERCENTAGE' – Camilo Lozano Sep 12 at 0:14
  • @CamiloLozano great. The first filter is only a spatial filter, the second one is considering clouds. This is a very clever approach for an AOI, I'll consider this flow for further processes – aldo_tapia Sep 12 at 11:25
  • One thing to put clear, the variable called "centroid" is made of "var centroid = geometry.centroid()". i use this in order to get the image from the center of the polygon. Doing this, I´m taking the image that covers the most of the polygon instead a corner of it. – Camilo Lozano Sep 12 at 18:28
  • @CamiloLozano and why are you doing this? If the polygon is covered by two or more tiles, you'll miss information. Check: developers.google.com/earth-engine/api_docs#eefilterbounds – aldo_tapia Sep 12 at 18:32

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.