5

I'm trying to mask a landsat 7 & 8 collection using the QA_imagery through google earth engine python API but doesn't remove the cloudy pixels. I have been tried in the webpage using javascript and works well

// Import shape
var table = ee.FeatureCollection("users/italomoletto/LSat_ETr_Tiles");
// Load Landsat 8 surface reflectance data
var l8sr = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').filter(ee.Filter.eq('WRS_PATH', 233))
    .filter(ee.Filter.gt('WRS_ROW', 87)).filter(ee.Filter.lt('WRS_ROW', 91));
// Load Landsat 7 surface reflectance data
var l7sr = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR').filter(ee.Filter.eq('WRS_PATH', 233))
    .filter(ee.Filter.gt('WRS_ROW', 87)).filter(ee.Filter.lt('WRS_ROW', 91));   




// helper function to extract the QA bits
function getQABits(image, start, end, mascara) {
 // 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], [mascara])
 .bitwiseAnd(pattern)
 .rightShift(start);
}

// A function to mask out cloudy pixels.
var maskQuality = function(image) {
 // Select the QA band.
 var QA = image.select('pixel_qa');
// Get the internal_cloud_algorithm_flag bit.
 var sombra = getQABits(QA,3,3,  'cloud_shadow');
 var nubes = getQABits(QA,5,5,  'cloud');
 //var cloud_confidence = getQABits(QA,6,7,  'cloud_confidence');
 var cirrus_detected = getQABits(QA,9,9,  'cirrus_detected');
 //var cirrus_detected2 = getQABits(QA,8,8,  'cirrus_detected2')
 // Return an image masking out cloudy areas.
 return image.updateMask(sombra.eq(0)).updateMask(nubes.eq(0).updateMask(cirrus_detected.eq(0))
 );
}

// Apply_cloud mask
var L8SR = l8sr.filterDate('2017-01-01', '2017-12-31')
                    .map(maskQuality).filterBounds(table)
var L7SR = l7sr.filterDate('2017-01-01', '2017-12-31')
                    .map(maskQuality).filterBounds(table)

//Export_imagery
    var ExportCol = function(col, folder, scale, type,
                             nimg, maxPixels, region) {
    type = type || "float";
    nimg = nimg || 500;
    scale = scale || 1000;
    maxPixels = maxPixels || 1e10;

    var colList = col.toList(nimg);
    var n = colList.size().getInfo();

    for (var i = 0; i < n; i++) {
      var img = ee.Image(colList.get(i));
      var id = img.id().getInfo();
      region = region || img.geometry().bounds().getInfo()["coordinates"];

      var imgtype = {"float":img.toFloat(), 
                     "byte":img.toByte(), 
                     "int":img.toInt(),
                     "double":img.toDouble()
                    }

      Export.image.toDrive({
        image:imgtype[type],
        description: id,
        folder: folder,
        fileNamePrefix: id,
        region: region,
        scale: scale,
        maxPixels: maxPixels})
    }
  }
//var ExportCol = function(col, folder, scale, type,
//                         nimg, maxPixels, region)
  ExportCol(L8SR,'L8SR',100,"float",200,1e12,table)

This code works okay. But when i apply on python API the cloud mask doesn't work

import ee
from ee import batch
ee.Initialize()
# Import shapefile
table = ee.FeatureCollection("users/italomoletto/LSat_ETr_Tiles")
#Load Landsat 8 surface reflectance data
l8sr = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').filter(ee.Filter.eq('WRS_PATH', 233))\
    .filter(ee.Filter.gt('WRS_ROW', 87)).filter(ee.Filter.lt('WRS_ROW', 91))
#Load Landsat 7 surface reflectance data
l7sr = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR').filter(ee.Filter.eq('WRS_PATH', 233))\
    .filter(ee.Filter.gt('WRS_ROW', 87)).filter(ee.Filter.lt('WRS_ROW', 91))


def getQABits(image, start, end, mascara):
    # Compute the bits we need to extract.
    pattern = 0
    for i in range(start,end-1):
        pattern += 2**i
    # Return a single band image of the extracted QA bits, giving the     band a new name.
    return image.select([0], [mascara]).bitwiseAnd(pattern).rightShift(start)
#A function to mask out cloudy pixels.
def maskQuality(image):
    # Select the QA band.
    QA = image.select('pixel_qa')
    # Get the internal_cloud_algorithm_flag bit.
    sombra = getQABits(QA,3,3,'cloud_shadow')
    nubes = getQABits(QA,5,5,'cloud')
    #  var cloud_confidence = getQABits(QA,6,7,  'cloud_confidence')
    cirrus_detected = getQABits(QA,9,9,'cirrus_detected')
    #var cirrus_detected2 = getQABits(QA,8,8,  'cirrus_detected2')
    #Return an image masking out cloudy areas.
    return image.updateMask(sombra.eq(0)).updateMask(nubes.eq(0).updateMask(cirrus_detected.eq(0)))
L8SR = l8sr.filterDate('2017-01-01', '2017-12-31')\
                    .map(maskQuality).filterBounds(table)
L7SR = l7sr.filterDate('2017-01-01', '2017-12-31')\
                    .map(maskQuality).filterBounds(table)
llx = -71
lly = -42
urx = -73
ury = -41
geometry = [[llx,lly], [llx,ury], [urx,ury], [urx,lly]]
name_export='SR'
def ExportCol(col, folder, scale, typei, nimg, maxPixels, region):
    #typei = "float"
    #nimg = 500
    #scale = 1000
    #maxPixels = 1e10
    colList = col.toList(nimg)
    n = colList.size().getInfo()
    for i in range(0,n):
      img = ee.Image(colList.get(i))
      id_img = img.id().getInfo()
      #region = img.geometry().bounds().getInfo()["coordinates"]

      imgtype = {"float":img.toFloat(), 
                     "byte":img.toByte(), 
                     "int":img.toInt(),
                     "double":img.toDouble()
                    }
      task_config = {
      'image': imgtype[typei],
      'description': id_img,
      'scale': scale,  
      'region': region,
      'folder': folder,
      'maxPixels': maxPixels,
      'fileNamePrefix': id_img
      }
      task = batch.Export.image(img, name_export+id_img, task_config)
      task.start()
#//var ExportCol = function(col, folder, scale, type,
#//                         nimg, maxPixels, region)
ExportCol(L8SR,'SR',100,"float",200,1e12,geometry)

This code export the imagery but doesn't work the cloud mask, any advice?

1

2 Answers 2

7

for i in range(start,end-1): should be for i in range(start,end+1):

Tested it, and your code works fine.

3
  • Hi @RodrigoE.Principe. This code works great, but when I use it in python, the mask is set to 0 and not NA. When I use GEE with javascript, the mask becomes NAs. Do you know how to set the mask to NA? I can ask this as a separate question if that would be better.
    – user44796
    Oct 22, 2020 at 20:34
  • yes @user44796, it'll be better Oct 26, 2020 at 10:52
  • Thanks @RodrigoE.Principe. I added a new question here
    – user44796
    Oct 26, 2020 at 16:14
0

Olá, segue meu exemplo para landsat 8.

#/*************************************MASCARAS DE NUVES PARA AS COLEÇÕES LANDSAT 5,7 e 8**************/
##Mascará de nuvens para a banda pixel_qa SR landsat 4,5 e 7
def cloudMaskL457(image):
  qa = image.select('pixel_qa') ##substitiu a band FMASK
  cloud1 = qa.bitwiseAnd(1<<5).eq(0)
  cloud2 = qa.bitwiseAnd(1<<7).eq(0)
  cloud3 = qa.bitwiseAnd(1<<3).eq(0)

  mask2 = image.mask().reduce(ee.Reducer.min());
  return image.updateMask(cloud1).updateMask(cloud2).updateMask(cloud3).updateMask(mask2).divide(10000).copyProperties(image, ["system:time_start"])

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.