1

I intend to create an image collection of Landsat-8 surface reflectance not TOA that has 100% free cloud over my Region of Interest (ROI). Not surprisingly the code I have found in the forum ( Filter Landsat images base on cloud cover over a region of interest ) did not work for me.

Based on https://gis.stackexchange.com/users/51905/intotecho, I tried to clip the collection first by var clippedLan8 = lan8.clipToCollection(ROI); where lan8 is my collection and of course ROI is the geometry defining my area, but it does not work.

So I am asking: 1) Is the code mentioned applicable for surface reflectance (SR) or not? If not, is there a way to achieve the goal in GEE? 2) Why doesn't the code for the clip work?

0

I have not used ee.Algorithms.Landsat.simpleCloudScore before but it appears to have been written for TOA images. .clipToCollection() clips an ee.Image() to an ee.FeatureCollection (see documnetation.

A solution to the problem is to,

  1. Create a cloud mask using the QA band included in Landsat SR products
  2. Count the number of pixels in your ROI that are masked
  3. Add the pixel count as an image property and use it to filter your image collection

Say lan8 is an ee.ImageCollection and ROI is an ee.Geometry:

var lan8_filt = lan8
  
  .map(function(image){
    
    // first create cloud_mask using the QA band (there is a tutorial on the GEE website somehwere, but I could not find the link 

    // bits 3 and 5 are cloud shadow and cloud, respectively.
    var cloudShadowBitMask = 1 << 3
    var cloudsBitMask = 1 << 5
  
    // get pixel QA band 
    var qa = image.select('pixel_qa');
  
    // set clouds and cloud shadows to 0 
    var cloud_mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
        .and(qa.bitwiseAnd(cloudsBitMask).eq(0))
        .rename('cloud_mask')
    
    // next get the fraction masked pixels in the roi 

    // reduce a histogram over the cloud mask 
    var hist = ee.Dictionary(cloud_mask.reduceRegion({reducer: ee.Reducer.frequencyHistogram(),
      geometry: ROI, maxPixels:1e10}).get('cloud_mask'))
    
    // get total pixel count 
    var N = hist.values().reduce(ee.Reducer.sum())

    // get relative histogram 
    var histr = hist.map(function(key,val){return ee.Number(val).divide(N).multiply(100).int()})
    
    // return image with cloud mask and new properties which are relative counts ('0' is masked pix and '1' is non-masked pix)
    return image.addBands(cloud_mask).set(histr)
  })

  // filter collection for 100% cloud cover (i.e. i.e. count for '1' is null)
  .filter(ee.Filter.notNull(['1']))

  // filter collection for quality pixels in the ROI. say less than 10% cloud cover
  .filter(ee.Filter.gt('1',90))

3
  • I can't thank you enough. what you have done sounds perfect; however when I ran I faced "computation timed out" error, even by a much smaller area. Do you have any suggestion why it happens?
    – Fafa
    Dec 10 '20 at 15:15
  • @Fafa Great to hear that it is helping. Not immediately sure. Are you getting this message when printing to the screen? You may need to consider how large your image collection is or how many computations you have made made before printing.
    – korndog
    Dec 10 '20 at 20:25
  • thanks. yes when i wanted to print it showed up... so its related to the volume of computation. ok then! thanks once again for your great help. I am gonna work more to figure it out.
    – Fafa
    Dec 10 '20 at 22:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.