[GIS] Sentinel Cloud-free Collection Google Earth Engine Code Editor

cloud covergoogle-earth-enginemaskingsentinel-2

I am trying to create and map an image collection (not image or mosaic if that is even possible), where QA60 defines the Cloud-mask. I have written the code below – however, it seems the Jan2016 images do not correspond the cloud mask, even though the pixel inspector shows the same image time stamp for all layers. Hence, "NoCLouds" layer contains many pixels with clouds and has many other without masked. Maybe my mask is wrong?

var Jan2016 = ee.ImageCollection('COPERNICUS/S2')
      .filterBounds(NSW)
      .filterDate('2016-01-01', '2016-01-30');

var trueColor = {bands: ['B4', 'B3', 'B2'], min: 0, max: 3000};
var falseColor= {bands: ['B8', 'B3', 'B4'], min: 0, max: 3000};
//Define the CLoud layer (here: QA60 is MSI2's quality mask)
var Clouds = {bands: ['QA60']};

//Add the cloud mask as layer; PROBLEM: SEEMS QA60 is taken from different images every time..
//Clouds is just a band, do i need to specify the threshold?
Map.addLayer(Jan2016, Clouds, "CloudsJan16");

// Mask clouds
var noclouds = Jan2016.map(function(img) {
              var mask = 
img.select(['QA60']).neq(11); 
//.neq(xx) doesn't seem to make a difference
                   return img.updateMask(mask);

});

//Add the layer/imagery to the map with variable, display type, and name  
Map.addLayer(noclouds, trueColor, "NoClouds");
Map.addLayer(Jan2016, falseColor, "Jan2016false");

Best Answer

Here is an example of cloud masking for Sentinel-2:

var s2 = ee.ImageCollection("COPERNICUS/S2");
var pt = ee.Geometry.Point([-122.41653442382812, 37.77180027337861]);

var cloudyImage = ee.Image('COPERNICUS/S2/20151207T190417_20151207T221905_T10SEG');
Map.centerObject(cloudyImage, 10);
Map.addLayer(cloudyImage, {bands: ['B4', 'B3', 'B2'], max: 2000}, 'cloudy image');

// Bits 10 and 11 are clouds and cirrus, respectively.
var cloudBitMask = ee.Number(2).pow(10).int();
var cirrusBitMask = ee.Number(2).pow(11).int();

var qa = cloudyImage.select('QA60');

Map.addLayer(qa.bitwiseAnd(cloudBitMask).neq(0), {}, 'clouds');
Map.addLayer(qa.bitwiseAnd(cirrusBitMask).neq(0), {}, 'cirrus');

function maskS2clouds(image) {
  var qa = image.select('QA60');
  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
             qa.bitwiseAnd(cirrusBitMask).eq(0));
  return image.updateMask(mask);
}

var cloudMasked = s2.filterBounds(pt).map(maskS2clouds);

var median = cloudMasked.median();
Map.addLayer(median, {bands: ['B4', 'B3', 'B2'], max: 2000}, 'median');