As far as I know, Sentinel 2 has no computed cloud-shadow mask, so I ommit that part. But for the rest, I think you should at least mask out clouds, and filter a little.
I've made public a repo I have to perform this: users/fitoprincipe/geetools
First the core:
var computeQAbits = function(image, start, end, newName) {
var pattern = 0;
for (var i=start; i<=end; i++) {
pattern += Math.pow(2, i);
}
return image.select([0], [newName]).bitwiseAnd(pattern).rightShift(start);
};
var sentinel2 = function(image) {
var cloud_mask = image.select("QA60");
var opaque = computeQAbits(cloud_mask, 10, 10, "opaque");
var cirrus = computeQAbits(cloud_mask, 11, 11, "cirrus");
var mask = opaque.or(cirrus);
return image.updateMask(mask.not());
}
You can use the function sentinel2
in a map
function.
to your question:
Using min()
, which may not be the best approach to generate a composite, (but that's another story so I am not diggin on it), this would be a complete 'solution':
var s2mask = require('users/fitoprincipe/geetools:cloud_masks').sentinel2;
var AOI = ee.Geometry.Rectangle(-85.14404296875, 46.9502622421856,
-71.87255859375, 41.60722821271717);
var collection = ee.ImageCollection("COPERNICUS/S2")
.filterBounds(AOI)
.filterMetadata('CLOUDY_PIXEL_PERCENTAGE', 'less_than', 70)
.map(s2mask());
var image = ee.Image(collection.min());
Map.addLayer(image, {bands:['B8', 'B12', 'B4'], min:0, max:3000});
Map.centerObject(AOI);
Best Answer
There has been an approach to do this using a decision tree: Ready-to-Use Methods for the Detection of Clouds, Cirrus, Snow, Shadow, Water and Clear Sky Pixels in Sentinel-2 MSI Images.
I have adapted the code to EE, and make it open source in
geetools
, both for the Python API and for the JavaScript API