3 votos

Encontrar regiones forestales con un valor constantemente bajo de NDVI

Utilizando el siguiente código, he filtrado mi colección de imágenes (imágenes Landsat) sobre las regiones forestales de la India. (Las regiones forestales se encontraron utilizando la imagen de Hansen). Tengo una imagen media por mes a lo largo de 6 años desde 2013 hasta 2018. Necesito encontrar y demarcar aquellas regiones que tienen un valor NDVI consistentemente bajo (NDVI<0.25).

Dado que existen variaciones estacionales en el valor del NDVI, un píxel correspondiente a un punto concreto puede tener un valor de NDVI mayor o menor que 0,25 en diferentes momentos. Así que cuando doy una condición como updateMask(image.lte(0.25)) sobre una colección de imágenes y luego visualizando las regiones en el mapa, obtengo todas aquellas regiones en las que ndvi fue menor de 0,25 al menos una vez. Pero sólo necesito las regiones en las que ndvi es inferior a 0,25 todo el tiempo.

¿Qué cambio debo hacer en mi código?

// FILTERING OUT FOREST COVER IN INDIA

var treeCanopyCover = hansen.clip(india).select('treecover2000');
var greater25 = treeCanopyCover.gte(25);

// NDVI FUNCTION

function addNDVI(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return image.addBands(ndvi);
}

// FILTERING THE COLLECTION

var startDate = ee.Date('2013-01-01');
var endDate = ee.Date('2018-12-31');
var filtered = l8.filterBounds(india)
      .filterDate(startDate, endDate)
      .filterMetadata('CLOUD_COVER','less_than',25)
      .map(addNDVI);  

var maskedCollection = filtered.map(function(image){
  var x = image.updateMask(greater25);
  return x;
});

// FILTERING MONTHLY WISE OVER YEARS

var map_m = function(y)
{
  y = ee.Number(y);
  var months = ee.List.sequence(1, 12);
  var filtered_col = months.map(function(m) 
{
var filt = maskedCollection.filter(ee.Filter.calendarRange(y, y, 'year'))
                .filter(ee.Filter.calendarRange(m, m, 'month'))
                .mean();

return filt.set('year', y)
      .set('month', m)
      .set('system:time_start',ee.Date.fromYMD(y,m,1)) ;
  });
  return filtered_col;
};

var years = ee.List.sequence(2013, 2018);
var monthlyimages = years.map(map_m).flatten();
var z = ee.ImageCollection(monthlyimages);

// // DISCARDING NULL IMAGES //

var nullimages = z.map(function(image) 
{
  return image.set('count', image.bandNames().length());
})
.filter(ee.Filter.eq('count', 13));

// Finding regions where ndvi is less than 0.25

var ndviViz = {min: 0, max: 0.25, palette: ['red',  'blue']};
var ndviMasked = nullimages.map(function(image){
  image = image.select("NDVI");
  var x = image.updateMask(image.lte(0.25));
  return x;
});
Map.addLayer(ndviMasked.mean(), ndviViz);

También tengo la duda de si es correcto utilizar ndviMasked.mean() o ndviMasked.mosaic() mientras se añade la capa al mapa.

2voto

Julius Jackson Puntos 59

Para ello, puede utilizar un mosaico de calidad ( https://developers.google.com/earth-engine/ic_composite_mosaic ).

Si se calcula un mosaico de calidad utilizando la banda NDVI, se obtiene el máximo NDVI sobre la serie temporal. Si el valor máximo sobre la serie temporal es inferior a 0,25, entonces el píxel siempre estuvo por debajo de ese umbral. Una vez que tenga el mosaico de calidad, simplemente enmascare esos valores.

// FILTERING OUT FOREST COVER IN INDIA
var treeCanopyCover = hansen.clip(india).select('treecover2000');
var greater25 = treeCanopyCover.gte(25);

// NDVI FUNCTION
function addNDVI(image) {
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return image.addBands(ndvi);
}

// FILTERING THE COLLECTION
var startDate = ee.Date('2013-01-01');
var endDate = ee.Date('2018-12-31');
var filtered = l8.filterBounds(india)
      .filterDate(startDate, endDate)
      .filterMetadata('CLOUD_COVER','less_than',25)
      .map(addNDVI);  

var maskedCollection = filtered.map(function(image){
  var x = image.updateMask(greater25);
  return x;
});

// FILTERING MONTHLY WISE OVER YEARS
var map_m = function(y)
{
  y = ee.Number(y);
  var months = ee.List.sequence(1, 12);
  var filtered_col = months.map(function(m) 
{
var filt = maskedCollection.filter(ee.Filter.calendarRange(y, y, 'year'))
                .filter(ee.Filter.calendarRange(m, m, 'month'))
                .mean();

return filt.set('year', y)
      .set('month', m)
      .set('system:time_start',ee.Date.fromYMD(y,m,1)) ;
  });
  return filtered_col;
};

var years = ee.List.sequence(2013, 2018);
var monthlyimages = years.map(map_m).flatten();
var z = ee.ImageCollection(monthlyimages);

// // DISCARDING NULL IMAGES //
var nullimages = z.map(function(image) 
{
  return image.set('count', image.bandNames().length());
})
.filter(ee.Filter.eq('count', 13));

// get quality mosiac using NDVI band
var qm = nullimages.qualityMosaic('NDVI');

// have a look at the quality mosaic
var ndvi_viz = {bands:'NDVI', min:-0.2, max:1, palette:['green', 'orange','red']};
Map.addLayer(qm, ndvi_viz, 'quality mosaic');

// let´s mask out values below 0.25
var mask = qm.select('NDVI').lt(0.25);
var ndviMasked = qm.updateMask(mask);

// have a look at the final result (few pixels)
var ndvi_viz2 = {bands:'NDVI', min:-0.2, max:0.25, palette:['grey', 'white','blue']};
Map.addLayer(ndviMasked, ndvi_viz2, 'masked');

0 votos

Exacto. Esto era lo que necesitaba. Muchas gracias. Esto me da un mapa que está casi en blanco que creo que es justificable porque el número de píxeles con un valor NDVI consistentemente menos de 0,25 será muy menor en las regiones forestales. De todos modos, muchas gracias.

0voto

Simplemente sustituya ndviMasked.mean() con ndviMasked.min()

0 votos

No, esto no resuelve mi problema. Mi problema es que las mismas regiones están marcadas con un valor de NDVI inferior y superior a 0,25.

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