Leggere, modificare e scrivere un geotiff con GDAL in python


11

Sto provando a imparare le corde dell'elaborazione delle immagini di telerilevamento usando i collegamenti Python GDAL e numpy. Come primo tentativo, sto leggendo un file geotiff di Landsat8, faccio una semplice manipolazione e scrivo il risultato in un nuovo file. Il codice seguente sembra funzionare correttamente, tranne per il fatto che il raster originale viene scaricato nel file di output, anziché nel raster manipolato.

Eventuali commenti o suggerimenti sono ben accetti, ma in particolare note sul perché il raster manipolato non viene visualizzato nel risultato.

import os
import gdal

gdal.AllRegister()

file = "c:\~\LC81980242015071LGN00.tiff"
(fileRoot, fileExt) = os.path.splitext(file)
outFileName = fileRoot + "_mod" + fileExt

ds = gdal.Open(file)
band = ds.GetRasterBand(1)
arr = band.ReadAsArray()

[cols, rows] = arr.shape
arr_min = arr.Min()
arr_max = arr.Max()
arr_mean = int(arr.mean())

arr_out = numpy.where((arr < arr_mean), 10000, arr)

driver = gdal.GetDriverByName("GTiff")
outdata = driver.Create(outFileName, rows, cols, 1, gdal.GDT_UInt16)
outband = outdata.GetRasterBand(1)
outband.WriteArray(arr_out)
outdata = None

print arr_min
> 0
print arr_max
> 65535
print arr_mean
> 4856

Uso Python 2.7.1 su un computer Windows 7 a 32 bit.


L'ho fatto funzionare su un DEM (Ubuntu, python 2.7.1) e ha prodotto il risultato atteso, con tutto sotto il valore medio impostato su 10000 e scritto su un nuovo tiff. Non stai copiando la geotrasformata sulla nuova immagine, quindi non è proiettata, quindi potresti aver bisogno di tenerne conto quando provi a visualizzarla (c'è un one-liner per farlo, ma dovrò scavarla). Se riesci a modificare la tua domanda con l'output di gdainfo -stats original.tiffe gdal-config --versionanche questo potrebbe aiutare.
Steven Kay,

Ciao, grazie per aver esaminato questo! So di aver trascurato la geotrasformazione, ho pensato di masticarlo più tardi. Vedo comunque l'intera immagine di output (usando Irfanview), quindi non può essere, credo. Genererò le informazioni richieste quando tornerò al posto stasera.
Hans Roelofsen,

Ciao, faccio fatica a fornire le informazioni che hai chiesto. Sto usando l'associazione Python GDAL e non sono sicuro di come i comandi specificati corrispondano a un comando Python. In ogni caso, sto usando GDAL-1.11.2-cp27-none-win32, come acquisito da qui . Aggiornerò il mio post con alcune statistiche sul file .tiff originale.
Hans Roelofsen,

quale sarebbe arr_min?
fluidmotion

arr_min = 0. Ho aggiornato il post per mostrarlo. Grazie!
Hans Roelofsen,

Risposte:


13

Nel tuo script manca il metodo ds.FlushCache, che salva su disco ciò che hai in memoria al termine delle modifiche. Vedi sotto una versione corretta del tuo esempio. Si noti che ho anche aggiunto due righe per impostare la proiezione e la geotrasformazione come input

import os
import gdal

file = "path+filename"
ds = gdal.Open(file)
band = ds.GetRasterBand(1)
arr = band.ReadAsArray()
[cols, rows] = arr.shape
arr_min = arr.min()
arr_max = arr.max()
arr_mean = int(arr.mean())
arr_out = numpy.where((arr < arr_mean), 10000, arr)
driver = gdal.GetDriverByName("GTiff")
outdata = driver.Create(outFileName, rows, cols, 1, gdal.GDT_UInt16)
outdata.SetGeoTransform(ds.GetGeoTransform())##sets same geotransform as input
outdata.SetProjection(ds.GetProjection())##sets same projection as input
outdata.GetRasterBand(1).WriteArray(arr_out)
outdata.GetRasterBand(1).SetNoDataValue(10000)##if you want these values transparent
outdata.FlushCache() ##saves to disk!!
outdata = None
band=None
ds=None

Il file di output non viene proiettato. Sto leggendo un file HDF5 e seleziono la proiezione dalla banda che voglio esportare GetProjection()fornisce l'EPSG corretto, ma sembra non essere applicato. Warp GDAL mancante? Grazie!
Michael,

con cosa dovrei sostituire outdata.GetRasterBand(1).WriteArray(arr_out)per scrivere un'immagine multispettrale con più di una banda?
Sai Kiran

"1" in driver.Create () indica il numero di bande. Quindi puoi scrivere su ogni banda con outdata.GetRasterBand (band_number). Inizia da 1, non da zero.
Andrea Massetti
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.