Membaca, memodifikasi, dan menulis geotiff dengan GDAL dengan python

11

Saya mencoba mempelajari tali pemrosesan gambar Penginderaan Jauh menggunakan binding Python GDAL dan numpy. Sebagai upaya pertama, saya membaca file geotiff Landsat8, melakukan manipulasi sederhana dan menulis hasilnya ke file baru. Kode di bawah ini tampaknya berfungsi dengan baik, kecuali bahwa raster asli dibuang di file output, daripada raster yang dimanipulasi.

Setiap komentar atau saran dipersilahkan, tetapi terutama catatan tentang mengapa raster yang dimanipulasi tidak muncul dalam hasilnya.

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

Saya menggunakan Python 2.7.1 pada mesin Windows 7 32 bit.

Hans Roelofsen
sumber
Saya membuatnya untuk bekerja pada DEM (Ubuntu, python 2.7.1) dan menghasilkan hasil yang diharapkan, dengan segala sesuatu di bawah nilai rata-rata diatur ke 10.000 dan ditulis ke tiff baru. Anda tidak menyalin geotransformasi ke gambar baru sehingga tidak diproyeksikan, jadi Anda mungkin perlu mempertimbangkan bahwa ketika mencoba untuk melihatnya (ada satu-liner untuk melakukan ini, tetapi saya harus menggali itu). Jika Anda dapat mengedit pertanyaan Anda dengan output dari gdainfo -stats original.tiffdan gdal-config --versionjuga itu bisa membantu.
Steven Kay
Hai, terima kasih telah melihat ini! Saya tahu saya mengabaikan geotransformasinya, berpikir untuk mengunyahnya nanti. Saya memang melihat seluruh gambar output (menggunakan Irfanview), jadi tidak mungkin itu saya pikir. Saya akan menghasilkan info yang Anda minta ketika saya kembali duduk malam ini.
Hans Roelofsen
Hai, saya kesulitan memberikan info yang Anda minta. Saya menggunakan Python GDAL binding dan saya tidak yakin bagaimana perintah yang Anda tentukan sesuai dengan perintah Python. Bagaimanapun, saya menggunakan GDAL-1.11.2-cp27-none-win32, seperti yang diperoleh dari sini . Saya akan memperbarui posting saya dengan beberapa statistik pada .tiff asli.
Hans Roelofsen
apa yang akan menjadi arr_min?
fluidmotion
arr_min = 0. Saya telah memperbarui posting untuk menunjukkan ini. Terima kasih!
Hans Roelofsen

Jawaban:

13

Skrip Anda tidak memiliki metode ds.FlushCache, yang menyimpan ke disk apa yang Anda miliki di memori di akhir modifikasi. Lihat di bawah versi contoh Anda yang sudah diperbaiki. Perhatikan bahwa saya juga menambahkan dua baris untuk mengatur proyeksi dan geotransform sebagai 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
Andrea Massetti
sumber
Sampah tidak diproyeksikan. Saya membaca file HDF5 dan memilih proyeksi dari band yang ingin saya ekspor GetProjection()memberikan EPSG yang benar, tetapi sepertinya tidak diterapkan. GDAL warp hilang? Terima kasih!
Michael
apa yang harus saya ganti dengan outdata.GetRasterBand(1).WriteArray(arr_out)untuk menulis gambar multispektral yang memiliki lebih dari satu band?
Sai Kiran
"1" di driver.Create () menunjukkan jumlah band. Kemudian Anda dapat menulis pada setiap band dengan outdata.GetRasterBand (band_number). Dimulai dari 1, bukan nol.
Andrea Massetti