Bildverarbeitung mit Python, GDAL und Scikit-Image


11

Ich habe Probleme mit einer Verarbeitung und hoffe, dass ich sie hier lösen kann.

Ich arbeite mit Fernerkundung in der Forstwirtschaft, insbesondere mit LiDAR-Daten. Die Idee ist, Scikit-Bild für die Baumkronenerkennung zu verwenden. Da ich neu in Python bin, habe ich einen großen persönlichen Triumph in Betracht gezogen, um Folgendes zu tun:

  1. Importieren Sie ein CHM (mit matplotlib);
  2. Führen Sie einen Gauß-Filter aus (mit Scikit-Image-Paket).
  3. Führen Sie einen Maxima-Filter aus (mit Scikit-Image-Paket).
  4. Führen Sie den Peak_local_max aus (mit dem Scikit-Image-Paket).
  5. Zeigen Sie das CHM mit den lokalen Maxima (mit matplotlib);

Nun mein Problem. Wenn ich mit Matplot importiere, verliert das Bild seine geografischen Koordinaten. Die Koordinaten, die ich habe, sind also nur grundlegende Bildkoordinaten (dh 250.312). Was ich brauche, ist, den Wert des Pixels unter den lokalen Maxima-Punkt im Bild (rote Punkte im Bild) zu bekommen. Hier im Forum sah ich einen Mann, der dasselbe fragte ( Pixelwert des GDAL-Rasters unter OGR-Punkt ohne NumPy erhalten? ), Aber er hatte die Punkte bereits in einem Shapefile. In meinem Fall wurden die Punkte mit einem Scikit-Bild berechnet (es ist ein Array mit den Koordinaten jeder Baumkrone). Ich habe also kein Shapefile.

Abschließend möchte ich am Ende eine txt-Datei mit den Koordinaten der einzelnen lokalen Maxima in geografischen Koordinaten, zum Beispiel:

525412 62980123 1150 ...

Lokale Maxima (rote Punkte) in einem CHM

Antworten:


11

Erstens, willkommen auf der Website!

Numpy Arrays haben kein Konzept von Koordinatensystemen, die in das Array integriert sind. Bei einem 2D-Raster werden sie nach Spalte und Zeile indiziert.

Hinweis Ich gehe davon aus, dass Sie ein Rasterformat lesen, das von GDAL unterstützt wird .

In Python können räumliche Rasterdaten am besten mit dem rasterioPaket importiert werden . Die von Rasterio importierten Rohdaten sind immer noch ein Numpy-Array ohne Zugriff auf Koordinatensysteme. Mit Rasterio können Sie jedoch auch auf eine affine Methode im Quell-Array zugreifen, mit der Sie Rasterspalten und -zeilen in projizierte Koordinaten umwandeln können. Beispielsweise:

import rasterio

# The best way to open a raster with rasterio is through the context manager
# so that it closes automatically

with rasterio.open(path_to_raster) as source:

    data = source.read(1) # Read raster band 1 as a numpy array
    affine = source.affine

# ... do some work with scikit-image and get an array of local maxima locations
# e.g.
# maxima = numpy.array([[0, 0], [1, 1], [2, 2]])
# Also note that convention in a numy array for a 2d array is rows (y), columns (x)

for point in maxima: #Loop over each pair of coordinates
    column = point[1]
    row = point[0]
    x, y = affine * (column, row)
    print x, y

# Or you can do it all at once:

columns = maxima[:, 1]
rows = maxima[:, 0]

xs, ys = affine * (columns, rows)

Und von dort aus können Sie Ihre Ergebnisse in eine Textdatei schreiben, wie Sie möchtencsv (ich würde zum Beispiel einen Blick auf das eingebaute Modul werfen ).


Vielen Dank. Sieht so aus, als könnte das funktionieren. Da ich neu in diesem Bereich bin, muss ich mich noch mit vielen Dingen vertraut machen. Danke für die Geduld.
João Paulo Pereira

1
In Rasterio 1.x können Sie source.xy (Zeile, Spalte) verwenden, um die Geokoordinate abzurufen.
Bugmenot123


0

Bitte versuchen Sie es mit folgendem Code. Dies kann verwendet werden, um Bilddaten aus dem Raster zu lesen und verarbeitete Daten in das Raster zu schreiben (.geotiff-Datei).

from PIL import Image,ImageOps
import numpy as np
from osgeo import gdal
#from osgeo import gdal_array
#from osgeo import osr
#from osgeo.gdalconst import *
#import matplotlib.pylab as plt

#from PIL import Image, ImageOps
#import gdal
#from PIL import Image
gdal.AllRegister()

################## Read Raster #################
inRaster='C:\python\Results\Database\Risat1CRS\CRS_LEVEL2_GEOTIFF\scene_HH\imagery_HH.tif'

inDS=gdal.Open(inRaster,1)
geoTransform = inDS.GetGeoTransform()
band=inDS.GetRasterBand(1)
datatype=band.DataType
proj = inDS.GetProjection()
rows = inDS.RasterYSize
cols=inDS.RasterXSize
data=band.ReadAsArray(0,0,cols,rows)#extraction of data to be processed#
############write raster##########
driver=inDS.GetDriver()
outRaster='C:\\python\\Results\\Database\\Temporary data base\\clipped_26July2017\\demo11.tif'
outDS = driver.Create(outRaster, cols,rows, 1,datatype)
geoTransform = inDS.GetGeoTransform()
outDS.SetGeoTransform(geoTransform)
proj = inDS.GetProjection()
outDS.SetProjection(proj)
outBand = outDS.GetRasterBand(1)
outBand.WriteArray(data1,0,0)
#data is the output array to written in tiff file
outDS=None 
im2=Image.open('C:\\python\\Results\\Database\\Temporary data base\\clipped_26July2017\\demo11.tif');
im2.show()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.