Czytanie, modyfikowanie i pisanie geotiff z GDAL w pythonie

11

Próbuję nauczyć się obsługi przetwarzania obrazu za pomocą teledetekcji za pomocą powiązań i numpy w Pythonie GDAL. Jako pierwszą próbę czytam plik geotiff Landsat8, wykonuję prostą manipulację i zapisuję wynik w nowym pliku. Poniższy kod wydaje się działać dobrze, z tym wyjątkiem, że oryginalny raster jest zrzucany do pliku wyjściowego, a nie zmanipulowany raster.

Wszelkie uwagi i sugestie są mile widziane, ale w szczególności uwagi na temat tego, dlaczego zmanipulowany raster nie wyświetla się w wyniku.

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

Używam Python 2.7.1 na 32-bitowym komputerze z systemem Windows 7.

Hans Roelofsen
źródło
Zmusiłem go do pracy na DEM (Ubuntu, python 2.7.1) i przyniósł oczekiwany wynik, ze wszystkim poniżej średniej wartości ustawionej na 10000 i zapisanym w nowym tiff. Nie kopiujesz geotransformy do nowego obrazu, więc nie jest projektowany, więc być może będziesz musiał wziąć to pod uwagę, próbując go wyświetlić (jest to jedna linijka, aby to zrobić, ale muszę to wykopać). Jeśli możesz edytować swoje pytanie z danymi wyjściowymi od, gdainfo -stats original.tiffa gdal-config --versiontakże to może pomóc.
Steven Kay
Cześć, dzięki za przyjrzenie się temu! Wiem, że zlekceważyłem geotransformę, pomyślałem o tym później. Widzę jednak cały obraz wyjściowy (używając Irfanview), więc myślę, że to nie może być to. Wygeneruję informacje, o które prosiłeś, kiedy wrócę dziś wieczorem.
Hans Roelofsen
Cześć, staram się podać informacje, o które prosiłeś. Korzystam z powiązania GDAL w języku Python i nie jestem pewien, w jaki sposób podane polecenia odpowiadają poleceniu w języku Python. W każdym razie używam GDAL-1.11.2-cp27-none-win32, tak jak tutaj . Zaktualizuję mój post, dodając statystyki do oryginalnego pliku .tiff.
Hans Roelofsen,
czym byłby arr_min?
fluidmotion
arr_min = 0. Zaktualizowałem post, aby to pokazać. Dzięki!
Hans Roelofsen

Odpowiedzi:

13

W twoim skrypcie brakuje metody ds.FlushCache, która zapisuje na dysku to, co masz w pamięci pod koniec modyfikacji. Zobacz poniżej poprawioną wersję swojego przykładu. Zauważ, że dodałem również dwie linie, aby ustawić projekcję i geotransform jako dane wejściowe

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
Andrea Massetti
źródło
Plik wyjściowy nie jest wyświetlany. Czytam plik HDF5 i wybieram projekcję z pasma, które chcę wyeksportować, GetProjection()dostarcza prawidłowego EPSG, ale wydaje się, że nie został zastosowany. Brak osnowy GDAL? Dzięki!
Michael
co mam zastąpić, outdata.GetRasterBand(1).WriteArray(arr_out)aby napisać obraz wielospektralny, który ma więcej niż jeden zespół?
Sai Kiran,
„1” w driver.Create () wskazuje liczbę pasm. Następnie możesz pisać na każdym paśmie za pomocą outdata.GetRasterBand (numer_pasma). Zaczyna się od 1, a nie od zera.
Andrea Massetti