Чтение, изменение и запись геотифа с помощью GDAL в Python

11

Я пытаюсь изучить канвы обработки изображений с помощью дистанционного зондирования с использованием привязок Python GDAL и numpy. В качестве первой попытки я читаю файл геотекса Landsat8, делаю простую манипуляцию и записываю результат в новый файл. Приведенный ниже код работает нормально, за исключением того, что исходный растр выгружается в выходной файл, а не в управляемый растр.

Любые комментарии или предложения приветствуются, но особенно заметки о том, почему манипулирующий растр не отображается в результате.

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

Я использую Python 2.7.1 на 32-битной машине с Windows 7.

Ханс Рёлофсен
источник
Я заставил его работать на DEM (Ubuntu, python 2.7.1), и он дал ожидаемый результат, когда все ниже среднего значения установлено на 10000 и записано в новый формат. Вы не копируете геотрансформацию в новое изображение, чтобы оно не проецировалось, поэтому вам может потребоваться учесть это при попытке его просмотреть (для этого есть одна строка, но мне нужно ее выкопать). Если вы можете отредактировать свой вопрос с выводом от gdainfo -stats original.tiffи это gdal-config --versionтоже может помочь.
Стивен Кей,
Привет, спасибо что заглянули в это! Я знаю, что пренебрегал геотрансформацией, подумал, чтобы пережить это позже. Хотя я вижу все выходное изображение (используя Irfanview), так что я думаю, что это не может быть. Я сгенерирую информацию, которую вы запросили, когда вернусь сегодня вечером на место.
Ганс Релофсен
Привет, я стараюсь предоставить информацию, которую вы просили. Я использую привязку Python GDAL, и я не уверен, насколько указанные вами команды соответствуют команде Python. В любом случае я использую GDAL-1.11.2-cp27-none-win32, приобретенный здесь . Я обновлю свой пост некоторыми статистическими данными по оригинальному .tiff.
Ганс Релофсен
что будет arr_min?
Fluidmotion
arr_min = 0. Я обновил пост, чтобы показать это. Благодаря!
Ханс Рёлофсен

Ответы:

13

В вашем сценарии отсутствует метод ds.FlushCache, который сохраняет на диск то, что у вас есть в памяти в конце изменений. Ниже приведена исправленная версия вашего примера. Обратите внимание, что я также добавил две строки для установки проекции и геотрансформации в качестве входных данных.

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
Андреа Массетти
источник
Выходной файл не прогнозируется. Я читаю файл HDF5 и выбираю проекцию из полосы, которую я хочу экспортировать, GetProjection()чтобы получить правильный EPSG, но, похоже, он не применяется. GDAL деформация отсутствует? Благодаря!
Майкл
что я должен заменить, outdata.GetRasterBand(1).WriteArray(arr_out)чтобы написать многоспектральное изображение, которое имеет более одной полосы?
Сай Киран
«1» в driver.Create () указывает количество полос. Затем вы можете написать на каждой группе с outdata.GetRasterBand (band_number). Начинается с 1, а не с нуля.
Андреа Массетти