4 votos

Motor de Google Earth: Aplicar ee.Reducer a todos los valores de la imagen

Antecedentes

Me gustaría devolver los valores de los percentiles de una imagen multibanda, utilizando ee.Reducer.percentile() .

Por ejemplo, la imagen podría tener este aspecto:

var image = ee.ImageCollection('LANDSAT/LT05/C01/T1')
  .filterDate('2008-01-01', '2008-03-01')
  .filter(ee.Filter.eq('WRS_PATH', 44))
  .filter(ee.Filter.eq('WRS_ROW', 34))
  .select('B1', 'B2')
  .toBands();

print(image);

En mi caso estoy apilando una imageCollection (cada imagen es un año), resultando en 18 bandas:

var year_stack = imageCollectionYears.toBands();

En el R entorno, utilizaría quantile(values(image), p = seq(0, 1, by = 0.2), na.rm = TRUE) que devolvería 6 valores cuantílicos, tomados de todos los valores de las celdas de la trama image , independientemente de la estratificación.

Probado hasta ahora

He aplicado el reductor a la imagen, pero éste devuelve valores de percentil para cada banda por separado, en lugar de para todos los valores de la imagen:

var percentiles = image.reduceRegion({
                  reducer:ee.Reducer.percentile([0, 20, 40, 60, 80, 100]),
                  bestEffort:true
  });

print(percentiles);

En mi caso, cada banda es un año individual, y el código devuelve los valores del percentil para cada año.

También he intentado aplicar el reductor a mi imageCollection, que devuelve una imagen con 6 bandas.

var test = imageCollectionYears.reduce({
                  reducer:ee.Reducer.percentile([0, 20, 40, 60, 80, 100])

  });

enter image description here

Estoy luchando por recuperar los números de los percentiles en la imagen devuelta test , por lo que no sé si esto funcionó (por ejemplo print(test.get("b1_p20")) imprime null ):

Pregunta

¿Cómo puedo aplicar el reductor a todos los valores, independientemente de la banda en la que se encuentren, y devolver los valores del percentil 6? Mi objetivo es obtener los valores percentiles globales de todos los años, que luego utilizaría para el análisis posterior.

3voto

Daniel Puntos 9

Este es uno de los códigos más terribles que he escrito en EE. Realmente no es una buena idea hacerlo así, y te quedarás sin memoria cuando lo hagas a mayor escala. Tal vez haya una forma mejor de hacer esto, que no requiera que cada valor de píxel esté en la memoria a la vez, pero no se me ocurre ninguna.

Si no necesitas los percentiles, tal vez puedas crear varios histogramas, combinarlos y obtener estadísticas a partir de ellos. Eso debería permitirle obtener un tipo de información similar, y trabajar para áreas más grandes / más datos.

var percentiles = ee.List(ee.ImageCollection(ee.ImageCollection('LANDSAT/LT05/C01/T1')
  .filterDate('2008-01-01', '2008-03-01')
  .filter(ee.Filter.eq('WRS_PATH', 44))
  .filter(ee.Filter.eq('WRS_ROW', 34))
  .select('B1', 'B2')
  .map(function (image) {
    var bands = image.bandNames().map(function (bandName) {
      return image.select(ee.String(bandName)).rename('band')
    })
    return ee.ImageCollection(bands)
  })
  .flatten())
  .iterate(function (image, acc) {
    var pixels = image.reduceRegion({
      reducer: ee.Reducer.toList(), 
      bestEffort: true
    }).get('band')
    return ee.List(acc).cat(pixels)
  }, ee.List([])))
  .reduce(ee.Reducer.percentile([0, 20, 40, 60, 80, 100]))

https://code.earthengine.google.com/10718c9b3187bd65925ab9eae16f1f06

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