5 votos

Aplicar máscara de nubes a las imágenes Landsat en el motor de Google Earth API de Python

Estoy tratando de enmascarar una colección de landsat 7 y 8 utilizando el QA_imagery a través de la API python del motor de google earth pero no elimina los píxeles nublados. He probado en la página web usando javascript y funciona bien

// 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)

Este código funciona bien. Pero cuando lo aplico en la API de python la máscara de la nube no funciona

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)

Este código exporta las imágenes pero no funciona la máscara de la nube, ¿algún consejo?

7voto

hibbelig Puntos 176

for i in range(start,end-1): debe ser for i in range(start,end+1):

Lo he probado y tu código funciona bien.

0voto

skwllsp Puntos 116

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"])

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X