Lire, modifier et écrire un géotiff avec GDAL en python


11

J'essaie d'apprendre les ficelles du traitement d'image de télédétection en utilisant les liaisons Python GDAL et numpy. Dans un premier temps, je lis un fichier géotiff Landsat8, je fais une manipulation simple et j'écris le résultat dans un nouveau fichier. Le code ci-dessous semble fonctionner correctement, sauf que le raster d'origine est sauvegardé dans le fichier de sortie, plutôt que le raster manipulé.

Tous les commentaires ou suggestions sont les bienvenus, mais en particulier les notes expliquant pourquoi le raster manipulé n'apparaît pas dans le résultat.

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

J'utilise Python 2.7.1 sur une machine Windows 7 32 bits.


Je l'ai fait fonctionner sur un DEM (Ubuntu, python 2.7.1) et il a produit le résultat attendu, avec tout en dessous de la valeur moyenne fixée à 10000 et écrit sur un nouveau tiff. Vous ne copiez pas la géotransformation vers la nouvelle image, elle n'est donc pas projetée, vous devrez donc peut-être en tenir compte lorsque vous essayez de la visualiser (il y a une seule ligne pour le faire, mais je vais devoir la creuser). Si vous pouvez modifier votre question avec la sortie de gdainfo -stats original.tiffet gdal-config --versionaussi cela pourrait aider.
Steven Kay

Salut, merci de regarder ça! Je sais que j'ai négligé la géotransformation, j'ai pensé à mâcher plus tard. Je vois cependant l'image de sortie entière (en utilisant Irfanview), donc ça ne peut pas être ça je pense. Je générerai les informations que vous avez demandées lorsque je serai de retour ce soir.
Hans Roelofsen du

Bonjour, j'ai du mal à fournir les informations que vous avez demandées. J'utilise la liaison Python GDAL et je ne sais pas comment les commandes que vous spécifiez correspondent à une commande Python. Dans tous les cas, j'utilise GDAL-1.11.2-cp27-none-win32, tel qu'acquis à partir d' ici . Je mettrai à jour mon article avec quelques statistiques sur le .tiff d'origine.
Hans Roelofsen

que serait arr_min?
fluidmotion

arr_min = 0. J'ai mis à jour le message pour le montrer. Merci!
Hans Roelofsen

Réponses:


13

Votre script ne contient pas la méthode ds.FlushCache, qui enregistre sur disque ce que vous avez en mémoire à la fin des modifications. Voir ci-dessous une version corrigée de votre exemple. Notez que j'ai également ajouté deux lignes pour définir la projection et la géotransformation en entrée

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

Le fichier externe n'est pas projeté. Je lis un fichier HDF5 et je sélectionne la projection de la bande que je veux exporter GetProjection()délivre le bon EPSG, mais il semble ne pas être appliqué. Chaîne GDAL manquante? Merci!
Michael

que dois-je remplacer outdata.GetRasterBand(1).WriteArray(arr_out)pour écrire une image multispectrale qui a plus d'une bande?
Sai Kiran

Le "1" dans driver.Create () indique le nombre de bandes. Ensuite, vous pouvez écrire sur chaque bande avec outdata.GetRasterBand (band_number). Cela commence à 1, pas à zéro.
Andrea Massetti
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.