Composizione, mascheramento e mosaico

Con la raccolta di riflettanza TOA Landsat 8 caricata in una variabile denominata l8, hai visto che il seguente codice genera un composito di valori recenti:

Editor di codice (JavaScript)

var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');
var landsat2016 = l8.filterDate('2016-01-01', '2016-12-31');
Map.addLayer(landsat2016, visParams, 'l8 collection');

Uno dei problemi di questa composizione è che è piena di nuvole. Anziché limitarti a prendere l'ultimo pixel della raccolta (quando aggiungi una raccolta alla mappa, Earth Engine chiama implicitamente mosaic()), puoi ridurre la ImageCollection (scopri di più sulla riduzione delle raccolte di immagini).

Composizione con i riduttori

Hai visto per la prima volta i riduttori per ottenere statistiche in un'area dell'immagine. Si è trattato di una riduzione spaziale. La riduzione di una raccolta di immagini a un'immagine è una riduzione temporale quando la raccolta rappresenta immagini nel tempo. Il tipo di Reducer che utilizzi definisce il modo in cui Earth Engine gestisce i pixel sovrapposti. Landsat 8 visita lo stesso punto della Terra ogni 16 giorni. Ciò significa che in un periodo di 6 mesi saranno disponibili circa 12 immagini (e altre ancora in cui le scene si sovrappongono). Ogni pixel sulla mappa è derivato da una serie di pixel, uno per ogni immagine della raccolta visualizzata.

La semplice aggiunta della raccolta alla mappa comporta la selezione del pixel più recente, ovvero quello dell'ultima immagine nello stack. Questo comportamento può essere modificato utilizzando i riduttori di Earth Engine. Ad esempio, invece di prendere il pixel più recente dallo stack, Earth Engine può essere istruito a scegliere il valore mediano nello stack. In questo modo, è possibile rimuovere le nuvole (che hanno un valore elevato) e le ombre (che hanno un valore basso). Quando una raccolta di immagini viene ridotta utilizzando il riduttore mediano, il valore composito è la mediana in ogni banda, nel tempo. Ad esempio, utilizzando le scene Landsat nel 2016:

Editor di codice (JavaScript)

// Get the median over time, in each band, in each pixel.
var median = l8.filterDate('2016-01-01', '2016-12-31').median();

// Make a handy variable of visualization parameters.
var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};

// Display the median composite.
Map.addLayer(median, visParams, 'median');

La novità di questo codice è il metodo median() applicato a una raccolta di immagini. Come i metodi di filtro, questa è una scorciatoia per il metodo reduce() più generale sulle raccolte di immagini che accetta un ee.Reducer() come argomento. Consulta il pacchetto ee.Reducer nella scheda Documenti dell'editor di codice per visualizzare un elenco di tutti i riduttori di Earth Engine. Quando prendi in considerazione un riduttore per una raccolta di immagini, tieni presente che l'output è un'immagine, quindi i riduttori con output non numerici, ad esempio i riduttori histogram o toList, non funzioneranno con una raccolta di immagini.

Tutorial_api_06_median_composite
Figura 6. Composito mediano di Landsat 8.

Quando diminuisci lo zoom sulla composizione mediana, dovresti vedere qualcosa di simile alla Figura 6. Questa immagine dovrebbe avere un aspetto notevolmente migliore rispetto al composito di valori recenti che hai creato in precedenza. A questo punto, vale la pena fare un passo indietro e considerare cosa è stato fatto per creare l'immagine composita mediana. Earth Engine ha caricato l'intera raccolta Landsat 8 sugli Stati Uniti continentali e ha calcolato la mediana per ogni pixel. Sono davvero tanti dati. Naturalmente, puoi calcolare le mediane annuali filtrando prima la raccolta, come hai fatto in precedenza. Il punto è che se dovessi scaricare tutte quelle immagini e creare questa composizione, sarebbe un progetto enorme. Con Earth Engine, ottieni un risultato in pochi secondi.

Scopri di più sulla composizione e sulla creazione di mosaici qui.

Mascheramento

Sebbene il composito mediano sia un miglioramento rispetto al composito del valore recente, potresti voler mascherare parti dell'immagine. La mascheratura dei pixel di un'immagine li rende trasparenti e li esclude dall'analisi. Ogni pixel in ogni banda di un'immagine ha una maschera. Quelli con un valore di maschera pari o inferiore a 0 saranno trasparenti. Verranno visualizzati quelli con una maschera di qualsiasi valore superiore a 0. La maschera di un'immagine viene impostata utilizzando una chiamata come image1.mask(image2). Questa chiamata prende i valori di image2 e li rende la maschera di image1. Tutti i pixel in image2 con valore 0 verranno resi trasparenti in image1.

Ad esempio, supponiamo che tu voglia mascherare tutti i pixel dell'acqua nella composizione mediana. È possibile creare una maschera dell'acqua utilizzando il set di dati descritto da Hansen et al. (2013), che si trova nel Data Catalog di Earth Engine. (Scopri di più sul set di dati di Hansen et al. in questo tutorial.) In questo set di dati, l'acqua ha un valore pari a 2, la terra ha un valore pari a 1 e "nessun dato" ha un valore pari a 0. Utilizza un po' di logica per creare un'immagine maschera che abbia zeri dove non c'è terra:

Editor di codice (JavaScript)

// Load or import the Hansen et al. forest change dataset.
var hansenImage = ee.Image('UMD/hansen/global_forest_change_2025_v1_13');

// Select the land/water mask.
var datamask = hansenImage.select('datamask');

// Create a binary mask.
var mask = datamask.eq(1);

// Update the composite mask with the water mask.
var maskedComposite = median.updateMask(mask);
Map.addLayer(maskedComposite, visParams, 'masked');

In questo codice sono presenti un paio di novità che vale la pena menzionare in dettaglio. Innanzitutto, la funzione select() è utile per estrarre le bande di interesse da un'immagine. Qui selezioniamo solo la band che ci interessa: datamask. La novità successiva è l'operatore logico eq(), che sta per "uguale". Utilizziamo eq(1) per creare un'immagine binaria in cui tutti i pixel che non hanno il valore 1 nella banda datamask (quelli che sono acqua o nessun dato) ottengono un valore pari a 0 nell'immagine risultante.

Come risultato di questo mascheramento, tutti i pixel nel composito mediano che si trovano sulla terraferma (secondo il set di dati Hansen et al.) sono visibili, ma quelli sull'acqua (o nodata) sono trasparenti e verranno esclusi da qualsiasi analisi eseguita sull'immagine maskedComposite.

Mosaicking

Combinando i concetti di raccolte di immagini, operatori logici, mascheramento e composizione, puoi ottenere risultati cartografici interessanti. Ad esempio, supponiamo che tu voglia un'immagine in cui i pixel della terra siano visualizzati in colori reali e tutti gli altri pixel siano visualizzati in blu. Puoi fare qualcosa come:

Editor di codice (JavaScript)

// Make a water image out of the mask.
var water = mask.not();

// Mask water with itself to mask all the zeros (non-water).
water = water.mask(water);

// Make an image collection of visualization images.
var mosaic = ee.ImageCollection([
  median.visualize(visParams),
  water.visualize({palette: '000044'}),
]).mosaic();

// Display the mosaic.
Map.addLayer(mosaic, {}, 'custom mosaic');

In questo codice succedono molte cose, quindi analizziamolo. Innanzitutto, utilizziamo l'operatore logico not() per invertire la maschera creata in precedenza. In particolare, not() trasforma tutti gli zeri in uno e tutti i valori diversi da zero in zero. Non è del tutto corretto chiamare questa variabile water perché include anche alcuni pixel senza dati, ma va bene nel contesto cartografico attuale. Il passaggio successivo consiste nel mascherare l'acqua con se stessa. In questo modo si ottiene un'immagine in cui tutti i pixel dell'acqua sono 1 e tutto il resto è mascherato. Il passaggio finale consiste nel combinare le immagini con mosaic(). Poiché mosaic() funziona su una raccolta di immagini, passiamo un elenco di immagini che vogliamo combinare nel costruttore della raccolta di immagini, quindi chiamiamo mosaic() come passaggio finale. L'ordine delle immagini nell'elenco è importante. In particolare, l'immagine di output conterrà l'ultimo pixel non mascherato dello stack di immagini nella raccolta di input. In questo caso, funziona perché lo strato dell'acqua è l'ultima immagine (in alto) della raccolta e contiene solo pixel non mascherati in cui è presente l'acqua.

Tieni presente che le immagini nella raccolta sono immagini di visualizzazione. Quando chiami visualize() su un'immagine, questa viene convertita in un'immagine a 3 bande e 8 bit in base ai parametri di visualizzazione che passi. I parametri di visualizzazione predefiniti funzionano bene per le immagini a 3 bande e 8 bit, quindi non sono necessari parametri di visualizzazione quando aggiungi l'immagine alla mappa. Il risultato dovrebbe essere simile alla Figura 7.

Tutorial_api_07_mosaic.png
Figura 7. Mosaico personalizzato che rende le aree acquatiche di un colore uniforme.

A questo punto, hai visto i modi per visualizzare le raccolte di immagini come compositi di valori recenti, i metodi per comporre le raccolte di immagini utilizzando i riduttori e i metodi per creare compositi personalizzati mascherando e creando un mosaico di una raccolta di immagini. Nella pagina successiva, scopri come aggiungere un indice di vegetazione a ogni immagine di una raccolta e utilizzarlo per creare un composito "pixel più verde".