Please, read the related answer.
Use the right parameters and always check metadata
You're trying to filter with BQA
band and in SR product, there is no BQA
band, there is pixel_qa
band instead. Also, bits used are different (3 and 5). Finally, if you are trying to create a cloud-free composite, first sort by cloud cover.
var point = /* color: #98ff00 */ee.Geometry.Point([35.83946228027344, -3.5380934964711126]);
//load images for composite
var sr14= ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(point)
.filterDate('2014-01-01','2014-03-01').sort('CLOUD_COVER',false);
// Temporally composite the images with a maximum value function.
var visParams = {bands: ['B4', 'B3', 'B2'], min:0,max: 1000};
Map.setCenter(35.8244, -3.5799);
Map.addLayer(sr14, visParams, 'max value composite');
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 cloud_shadows = function(image) {
// Select the QA band.
var QA = image.select(['pixel_qa']);
// Get the internal_cloud_algorithm_flag bit.
return getQABits(QA, 3,3, 'cloud_shadows').eq(0);
// Return an image masking out cloudy areas.
};
// A function to mask out cloudy pixels.
var clouds = function(image) {
// Select the QA band.
var QA = image.select(['pixel_qa']);
// Get the internal_cloud_algorithm_flag bit.
return getQABits(QA, 5,5, 'Cloud').eq(0);
// Return an image masking out cloudy areas.
};
var maskClouds = function(image) {
var cs = cloud_shadows(image);
var c = clouds(image);
image = image.updateMask(cs);
return image.updateMask(c);
};
var composite_free = sr14.map(maskClouds);
Map.addLayer(composite_free,visParams, 'composite collection without clouds');
Link: https://code.earthengine.google.com/6a9d2bce417076d1f1b677e775584690
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
var cld = require('users/fitoprincipe/geetools:cloud_masks')
var image = ee.Image('COPERNICUS/S2/20151123T142942_20170221T180430_T19GCN')
Map.centerObject(image)
var mask_shadow = cld.hollstein_S2(['shadow'])(image)
Map.addLayer(mask_shadow, {bands:['B8', 'B11','B4'], min:0, max:5000})
Best Answer
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:
You can use the function
sentinel2
in amap
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':