2

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());                  
1

1 Answer 1

3

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: 10,
    crs:'EPSG:32719'
  });
  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

10
  • 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 Sep 11, 2019 at 22:26
  • I correct myself, after doing lots of probes, it is necessary to use 'cloud' instead of 'CLOUDY_PIXEL_PERCENTAGE' Sep 12, 2019 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, 2019 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. Sep 12, 2019 at 18:28
  • 1
    @Waleed93 sorry, I made a mistake. The scale is 10, determined by S2's RGB NIR bands, but you can select the spatial resolution you want. I added CRS as well, in this example is WGS 82 UTM 19s ('EPSG:32719'), for meter unit in the result. This CRS must be set up according to your zone.
    – aldo_tapia
    Jul 5, 2020 at 23:24

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.