Geotiff di Raw Sentinel 2 jp2 su RGB


11

Sto cercando un modo per unire i file di banda Sentinel 2 jp2 ( B02, B03, B04 ) e correggere i colori RGB. Tutto dovrebbe essere fatto con script bash o python. Per il mio esempio, lavoro su queste immagini . Idealmente la soluzione sarà vicina a questo tutorial.

Sono in grado di unire le bande con questo comando

gdal_merge.py -separate -co PHOTOMETRIC=RGB -o merged.tif B04.jp2 B03.jp2 B02.jp2

Ma per qualche motivo non riesco a correggere i colori RGB con il comando imagemagic. L'output è un'immagine nera di ~ 700 MB.

convert -channel B -gamma 1.05 -channel RGB -sigmoidal-contrast 20,20% -modulate 100,150 merged.tif merged-cc.tif

Alla fine vorrei avere un file geotiff per caricarlo su mapbox. Spiegazione su come si dovrebbero scegliere i convertparametri è il benvenuto.

Sto sviluppando un'applicazione che dovrebbe indovinare quale parte dell'immagine satellitare è un terreno agricolo. Un'immagine di scena verrà tagliata in patch più piccole (forse 64x64) e sarà classificata dalla CNN ( crop o non crop ). Uso questo set di dati per addestrare il modello Inception-v3. Il set di dati contiene immagini RGB 64x64 con risoluzione spaziale di 10 m.


Maggiori informazioni su merged.tif

Band 1 Block=10980x1 Type=UInt16, ColorInterp=Red
  Metadata:
    STATISTICS_MAXIMUM=4818
    STATISTICS_MEAN=320.61101402206
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=536.76609312554
Band 2 Block=10980x1 Type=UInt16, ColorInterp=Green
  Metadata:
    STATISTICS_MAXIMUM=4206
    STATISTICS_MEAN=350.98505344194
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=534.43264268631
Band 3 Block=10980x1 Type=UInt16, ColorInterp=Blue
  Metadata:
    STATISTICS_MAXIMUM=3801
    STATISTICS_MEAN=364.44611471973
    STATISTICS_MINIMUM=0
    STATISTICS_STDDEV=544.55509661709

Questo è merged.tif prima e dopo l'applicazione della soluzione di @ ben prima dopo


1
Qual è la profondità di bit di merged.tif e min, media e massima nell'istogramma? Verificare congdalinfo -hist merged.tif
user30184

@ user30184 Ho aggiunto le informazioni richieste alla mia domanda
gkiko

Ho provato a convertire jp2 in geotiff e quindi ad applicare la correzione del colore ma ho ancora un'immagine nera
gkiko

perché non usi semplicemente l'immagine TCI.jp2 che è sostanzialmente la stessa di -scale 0 4096 0 255?
pLumo,

1
per crop / non crop, forse puoi usare questo esa-sen2agri.org/resources/software invece di creare la tua applicazione da zero
radouxju,

Risposte:


8

Ci sono 2 parti del problema. Il primo è che vuoi convertire da 16 bit a 8 bit, e l'opzione -scale di gdal_translate lo fa, come menzionato nella risposta precedente.

 -scale minOriginal maxOriginal minOutput maxOutput  

Il secondo problema è un problema di miglioramento del contrasto: quando ridimensioni, vuoi avere un contrasto elevato per i pixel che ti interessano. AVVERTENZA: non c'è contrasto "magico" perché, quando ridimensioni, di solito perdi alcune informazioni : viene fatto per migliorare la visualizzazione dei dati e software professionali lo fanno al volo senza scrivere un nuovo file. Se vuoi elaborare ulteriormente i tuoi dati, il tuo geotiff "nero" contiene le stesse informazioni del tuo jp2 ed è pronto per essere elaborato. Se si calcola, ad esempio, l'indice di vegetazione, questo dovrebbe essere fatto con i valori di riflettanza "originali", non quelli riscalati. Detto questo, ecco alcuni passaggi per creare un'immagine 8bit visivamente migliorata.

@ben ti ha dato un metodo generico per ridimensionare la riflettanza da 0-1 (moltiplicata per 10000 con questo prodotto) a 0-255. Questo è sicuro (nessuna esclusione), ma solo le nuvole e alcuni terreni nudi hanno riflessioni molto alte, quindi non si vede molto sulla terra (tranne i terreni nudi) e niente nell'acqua. Pertanto, i miglioramenti del contrasto comunemente applicati alle immagini consistono nel prendere solo un sottoinsieme dell'intera gamma. Per quanto riguarda la sicurezza, è possibile utilizzare la consapevolezza che la riflettanza massima del materiale comune della superficie terrestre è generalmente inferiore a 0,5 / 0,6 (vedere quiper alcuni esempi). Naturalmente, questo presuppone che la tua immagine sia stata corretta atmosfericamente (immagini L2A). Tuttavia, la gamma di riflettanza differisce in ciascuna banda spettrale e non sempre hai le superfici della Terra più luminose nella tua area di interesse. Ecco come appare il metodo "sicuro" (con una riflettanza massima di 0,4, come il 4096 suggerito da @RoVo)

inserisci qui la descrizione dell'immagine

D'altra parte, il contrasto potrebbe essere ottimizzato per ogni banda. È possibile definire questo intervallo manualmente (ad esempio, se si è interessati al colore dell'acqua e si conosce il valore massimo di riflettanza atteso dell'acqua) o in base alle statistiche dell'immagine. Un metodo comunemente usato consiste nel mantenere circa il 95% dei valori e nel "scartare" (troppo scuro -> 0 o troppo luminoso -> 255) il resto, il che è simile alla definizione dell'intervallo in base al valore medio +/- 1,96 * deviazione standard. Naturalmente, questa è solo un'approssimazione perché presuppone una distribuzione normale, ma in pratica funziona abbastanza bene (tranne quando hai troppe nuvole o se le statistiche fanno uso di alcuni valori NoData).

Prendiamo la tua prima band come esempio:

media = 320

std = 536

Intervallo di confidenza al 95% = [-731: 1372]

ma ovviamente la riflettanza è sempre maggiore di zero, quindi è necessario impostare il minimo su 0.

gdal_translate -scale 0 1372 0 255 -ot Byte  B01.jp2 B01-scaled.tif  

E se hai una versione recente di gdal, puoi usare -scale_ {band #} (0 255 è l'output predefinito, quindi non lo ripeto) in modo da non dover dividere singole bande. Inoltre ho usato vrt invece di tif come file intermedio (non è necessario scrivere un'immagine completa: ne basta uno virtuale)

gdalbuildvrt -separate stack.vrt B04.jp2 B03.jp2 B02.jp2
gdal_translate -scale_1 0 1372 -scale_2 0 1397 -scale_3 0 1430 -ot Byte  stack.vrt im_rescaled.tif

Nota che le tue statistiche sono fortemente influenzate da "artefatti" come nuvole e NoData. Da un lato, la varianza viene sopravvalutata quando si hanno valori estremi. D'altra parte, la tua media è sottovalutata quando c'è una grande quantità di valori "zero" (rendendo l'immagine a contrasto automatico troppo luminosa come nell'esempio) e sarebbe sopravvalutata se ci fosse una maggioranza di nuvole (che renderebbe il immagine troppo scura). In questa fase, i risultati non sarebbero quindi i migliori che si possano ottenere.

inserisci qui la descrizione dell'immagine

Una soluzione automatizzata sarebbe quella di impostare i valori di sfondo e cloud su "nodata" e calcolare le tue statistiche senza NoData (vedi questo post per dettagli sulle statistiche di calcolo senza NoData, e questo per un esempio per impostare valori maggiori di 4000 anche su NoData ). Per una singola immagine, di solito calcolo le statistiche sul più grande sottoinsieme possibile senza cloud. Con le statistiche di un sottoinsieme in cui non ci sono "NoData" (in alto a sinistra dell'immagine), questo dà il risultato finale. Puoi vedere che l'intervallo è circa la metà dell'intervallo "sicuro", il che significa che hai il doppio del contrasto:

gdal_translate -scale_1 38 2225 -scale_2 553 1858 -scale_3 714 1745 -ot Byte  stack.vrt im_rescaled.tif

inserisci qui la descrizione dell'immagine

Come ultima osservazione, gdal_constrast_stretch sembra buono ma non ho ancora testato


il problema è che ogni granulo avrà una luminosità diversa. A seconda di ciò che vuole ottenere, è meglio usare una scala fissa. -scale 0 4096 0 255produce un output piuttosto buono se non abbiamo bisogno di trame cloud ...
pLumo

@RoVo concordo sul fatto che questo produrrà valori chiari e che potresti perdere il contrasto su superfici luminose come la sabbia, ma questo si basa sulle statistiche dell'immagine unita dall'OP. Non avrai un diverso contrasto sui granuli. Di solito, l'intervallo in rosso, verde e blu è molto più piccolo dell'intervallo in NIR, per questo ha senso usare un contrasto diverso per ogni banda.
Radouxju,

7

Puoi semplicemente usare il TCI.jp2file che è incluso nei SAFE.zipfile. Si noti che questi file non sono disponibili nei file S2 prima di ottobre 2016

In alternativa puoi convertire le bande usando GDAL:

# Merge bands
gdalbuildvrt -separate TCI.vrt B04.jp2 B03.jp2 B02.jp2

# Convert to uncompressed GeoTiff
gdal_translate -ot Byte -co TILED=YES -scale 0 4096 0 255 TCI.vrt TCI.tif

# _OR_ Convert to JPEG - compressed GeoTiff
gdal_translate -ot Byte -co TILED=YES -co COMPRESS=JPEG -co PHOTOMETRIC=YCBCR -scale 0 4096 0 255 TCI.vrt TCI.tif

-scale 0 4096è un valore ragionevole per le scene di Sentinel-2 e afaik utilizzato anche per le immagini TCI.jp2. Abbassa il 4096 se desideri ricevere un risultato più leggero.


5

Se stai cercando una soluzione come quella che hai collegato alla domanda, dovresti seguire e modificare lo script della shell di elaborazione di Landsat 8 fornito per il download nel tutorial.

In particolare, come è fatto lì, potresti prima voler ridimensionare le singole bande, ad esempio come segue:

gdal_translate -ot Byte -scale 0 10000 0 255 B04.jp2 B04-scaled.tif 
gdal_translate -ot Byte -scale 0 10000 0 255 B03.jp2 B03-scaled.tif
gdal_translate -ot Byte -scale 0 10000 0 255 B02.jp2 B02-scaled.tif

Nota che l'istogramma delle tue immagini suggerisce che hai solo delle superfici molto scure nell'immagine (è questo il caso?) Ma di solito la tua immagine sentinella-2 avrà un riflesso nella parte superiore dell'atmosfera o in superficie dove i valori normalmente vanno tra 0 e 10000 - a meno che non siano anche possibili valori più alti, ad esempio se nell'immagine sono presenti nuvole.

Quindi è possibile unire le bande e ottimizzare l'aspetto dell'immagine:

gdal_merge.py -v -ot Byte -separate -of GTiff -co PHOTOMETRIC=RGB -o RGB-scaled.tif B04-scaled.tif B03-scaled.tif B02-scaled.tif
convert -channel B -gamma 1.05 -channel RGB -sigmoidal-contrast 20,40% -modulate 100,150 RGB-scaled.tif RGB-scaled-cc.tif

Questo è ciò che accade alla mia immagine quando si esegue questa operazione:

inserisci qui la descrizione dell'immagine


1
Ho aggiornato la mia domanda. Come devo decidere quali parametri utilizzare per la correzione del colore geoTIFF?
gkiko,

Quando si ridimensionano i valori dall'input all'immagine di output, osservare sempre il valore massimo e minimo nell'immagine di input. Ad esempio, per la prima banda, il parametro di scala dovrebbe essere simile a questo: scala 0 4818 0 255.
Milos Miletic
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.