3

I Have multiple Landsat8 images at the same place in different years.

I want to have a cloud mask for each image, then merge the mask so that all images will be masked with a same aggregated mask.

I've got masked image for each year using code from this post Using cloud confidence to create cloud mask from Landsat 8 BQA? .

var RADIX = 2;  // Radix for binary (base 2) data.
var extractQABits = function (qaBand, bitStart, bitEnd) {
  var numBits = bitEnd - bitStart + 1;
  var qaBits = qaBand.rightShift(bitStart).mod(Math.pow(RADIX, numBits));
  return qaBits;
};

var getMaskedImg = function (i){

  // Reference a sample Landsat 8 TOA image.
  var image = ee.Image(i).clip(geometry);

  // Extract the QA band.
  var image_qa = image.select('BQA');

  // Create a mask for the dual QA bit "Cloud Confidence".
  var bitStartCloudConfidence = 5;
  var bitEndCloudConfidence = 6;
  var qaBitsCloudConfidence = extractQABits(image_qa, bitStartCloudConfidence, bitEndCloudConfidence);
  // Test for clouds, based on the Cloud Confidence value.
  var testCloudConfidence = qaBitsCloudConfidence.gte(2);

  // Create a mask for the dual QA bit "Cloud Shadow Confidence".
  var bitStartShadowConfidence = 7;
  var bitEndShadowConfidence = 8;
  var qaBitsShadowConfidence = extractQABits(image_qa, bitStartShadowConfidence, bitEndShadowConfidence);
  // Test for shadows, based on the Cloud Shadow Confidence value.
  var testShadowConfidence = qaBitsShadowConfidence.gte(2);

  // Calculate a composite mask and apply it to the image.   
  var maskComposite = (testCloudConfidence.or(testShadowConfidence)).not();
  var imageMasked = image.updateMask(maskComposite);  
  return(imageMasked)
}

How can I merge the masks and let all images share this merged mask?

1 Answer 1

0

The following code shows my approach to

  • get landsat8_sr data from multiple years with multiple images from each year
  • calculate mean value for each year
  • calculate min mask for each year (mask only if cloud appear in all images in a year)
  • calculate max mask for all years (mask as long as cloud appears in one year)
// Landsat 8 Cloud Masking Example (source:https://gis.stackexchange.com/questions/292835/using-cloud-confidence-to-create-cloud-mask-from-landsat-8-bqa)
var RADIX = 2;  // Radix for binary (base 2) data.

var extractQABits = function (qaBand, bitStart, bitEnd) {
  var numBits = bitEnd - bitStart + 1;
  var qaBits = qaBand.rightShift(bitStart).mod(Math.pow(RADIX, numBits));
  //Map.addLayer(qaBits, {min:0, max:(Math.pow(RADIX, numBits)-1)}, 'qaBits');
  return qaBits;
};

var cloudCompositeList = [];

var getMaskedImg = function (i){

  // Reference a sample Landsat 8 TOA image.
  var image = ee.Image(i).clip(geometry);

  // Extract the QA band.
  var image_qa = image.select('pixel_qa');

  // Create a mask for the dual QA bit "Cloud Confidence".
  var bitStartCloudConfidence = 6;
  var bitEndCloudConfidence = 7;
  var qaBitsCloudConfidence = extractQABits(image_qa, bitStartCloudConfidence, bitEndCloudConfidence);
  // Test for clouds, based on the Cloud Confidence value.
  var testCloudConfidence = qaBitsCloudConfidence.gte(2);

  // Create a mask for the dual QA bit "Cloud Shadow Confidence".
  var bitStartShadowConfidence = 8;
  var bitEndShadowConfidence = 9;
  var qaBitsShadowConfidence = extractQABits(image_qa, bitStartShadowConfidence, bitEndShadowConfidence);
  // Test for shadows, based on the Cloud Shadow Confidence value.
  var testShadowConfidence = qaBitsShadowConfidence.gte(2);

  // Calculate a composite mask and apply it to the image.   
  var maskComposite = (testCloudConfidence.or(testShadowConfidence)).not();
  var imageMasked = image.updateMask(maskComposite);

  return(imageMasked);
};


var getCloudComposite = function (i){

  // Reference a sample Landsat 8 TOA image.
  var image = ee.Image(i).clip(geometry);

  // Extract the QA band.
  var image_qa = image.select('pixel_qa');

  // Create a mask for the dual QA bit "Cloud Confidence".
  var bitStartCloudConfidence = 6;
  var bitEndCloudConfidence = 7;
  var qaBitsCloudConfidence = extractQABits(image_qa, bitStartCloudConfidence, bitEndCloudConfidence);
  // Test for clouds, based on the Cloud Confidence value.
  var testCloudConfidence = qaBitsCloudConfidence.gte(2);

  // Create a mask for the dual QA bit "Cloud Shadow Confidence".
  var bitStartShadowConfidence = 8;
  var bitEndShadowConfidence = 9;
  var qaBitsShadowConfidence = extractQABits(image_qa, bitStartShadowConfidence, bitEndShadowConfidence);
  // Test for shadows, based on the Cloud Shadow Confidence value.
  var testShadowConfidence = qaBitsShadowConfidence.gte(2);

  // Calculate a composite mask and apply it to the image.   
  var maskComposite = (testCloudConfidence.or(testShadowConfidence)).not();

  return(maskComposite);
};

var accumulateCloudAnd = function(image, list) {
  var previous = ee.Image(ee.List(list).get(-1));
  var merged = image.and(previous);
  return (ee.List(list)).add(merged);
};

var accumulateCloudOr = function(image, list) {
  var previous = ee.Image(ee.List(list).get(-1));
  var merged = image.or(previous);
  return (ee.List(list)).add(merged);
};



//run mask on all relevant images
var maskedImgs = [];
var maskedImgMeans = [];
var reMaskImg = function(img) {
  return img.mask(img);
};
var bestImg = [];

var allClouds = [];
var allComposite = null;

for (var year = 2014; year < 2019; year++) {
  if (year == 2016)
    continue;
  var startDate = year + '-08-15';
  var endDate = year + '-10-15';

  //get landsat images
  var ic=ee.ImageCollection(Landsat_8_SR
  // Filter the region
  .filter(ee.Filter.eq('WRS_PATH', 231))
  .filter(ee.Filter.eq('WRS_ROW', 62))
  // Filter the time
  .filterDate(startDate, endDate));


  //mask out clouds
  var result = ic.map(getMaskedImg);
  var clouds = ic.map(getCloudComposite);

  var cloudComposite = ee.ImageCollection(ee.List(clouds.iterate(accumulateCloudOr, ee.List([ee.Image(0)]))));
  var cloudCompositeList = cloudComposite.toList(cloudComposite.size());
  var compositeResult = cloudCompositeList.get(cloudCompositeList.length().subtract(1));
  allClouds.push(compositeResult);

  maskedImgs.push(result);
  bestImg.push(result.sort('system:asset_size').first());

  var result2 = result.map(reMaskImg);
  var result3  = result2.reduce(ee.Reducer.mean());

  maskedImgMeans.push(result3);

}


print(maskedImgs);
print(maskedImgMeans);
print(bestImg);
print(allClouds);

var allCloudsCollection = ee.ImageCollection(allClouds);
var allCloudComposite = ee.ImageCollection(ee.List(allCloudsCollection.iterate(
  accumulateCloudAnd, ee.List([ee.Image(1)]))));
var allCloudCompositeList = allCloudComposite.toList(allCloudComposite.size());
var finalComposite = allCloudCompositeList.get(allCloudCompositeList.length().subtract(1))

var im = ee.Image(finalComposite);
Map.addLayer(im.mask(im), {min:0, max:1, pallete:'green'}, 'finalMaskComposite', false);

var getMaskedImgWithComposite = function (i) {
  var image = ee.Image(i).clip(geometry);
  var imageMasked = image.updateMask(finalComposite);
  return(imageMasked);
};

var newMaskedImgs = maskedImgMeans.map(getMaskedImgWithComposite);

print(newMaskedImgs)


//visualise
var x = 0;
for (var year = 2014; year < 2019; year++) { 
  if (year == 2016)
    continue;
  Map.addLayer(newMaskedImgs[x], {bands:"B4_mean,B3_mean,B2_mean", min:-2000, max: 10000}, 'new image'+ year, false);
  x++;
}
2
  • 1
    Is this an answer to your question?
    – Aaron
    Sep 14, 2020 at 17:18
  • It's a working solution and solved my problem. I didn't "accept" my own answer was hoping there can be better solitions
    – eth4io
    Sep 14, 2020 at 22:29

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.