Elaborazione delle immagini utilizzando Python, GDAL e Scikit-Image


11

Sto lottando con un'elaborazione e spero di riuscire a risolvere qui.

Lavoro con il telerilevamento applicato a Forestry, in particolare con i dati LiDAR. L'idea è di utilizzare l'immagine Scikit per il rilevamento della parte superiore dell'albero. Da quando sono nuovo in Python, ho considerato un grande trionfo personale fare quanto segue:

  1. Importa un CHM (con matplotlib);
  2. Esegui un filtro gaussiano (con il pacchetto scikit-image);
  3. Esegui un filtro maxima (con pacchetto scikit-image);
  4. Esegui peak_local_max (con il pacchetto scikit-image);
  5. Mostra il CHM con i massimi locali (con matplotlib);

Ora il mio problema. Quando eseguo l'importazione con matplot, l'immagine perde le sue coordinate geografiche. Quindi le coordinate che ho sono solo coordinate di base dell'immagine (cioè 250.312). Ciò di cui ho bisogno è ottenere il valore del pixel sotto il punto massimo locale nell'immagine (punti rossi nell'immagine). Qui nel forum ho visto un ragazzo chiedere la stessa cosa ( Ottenere il valore in pixel di GDAL raster sotto il punto OGR senza NumPy? ), Ma aveva già i punti in uno shapefile. Nel mio caso i punti sono stati calcolati con l'immagine di scikit (è un array con le coordinate di ogni cima dell'albero). Quindi non ho lo shapefile.

In conclusione, quello che voglio alla fine è un file txt con le coordinate di ciascun massimo locale in coordinate geografiche, ad esempio:

525412 62980123 1150 ...

Massimi locali (punti rossi) in un CHM

Risposte:


11

Innanzitutto, benvenuti nel sito!

Gli array Numpy non hanno un concetto di sistemi di coordinate integrati nell'array. Per un raster 2D sono indicizzati per colonna e riga.

Nota : sto assumendo che stai leggendo un formato raster supportato da GDAL .

In Python il modo migliore per importare dati raster spaziali è con il rasteriopacchetto. I dati grezzi importati da rasterio sono ancora un array intorpidito senza accesso ai sistemi di coordinate, ma rasterio ti dà anche accesso a un metodo affine sull'array di origine che puoi usare per trasformare colonne e righe raster in coordinate proiettate. Per esempio:

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)

E da lì puoi scrivere i nostri risultati in un file di testo come preferisci (suggerirei di dare un'occhiata al modulo integratocsv per esempio).


Grazie mille. Sembra che potrebbe funzionare. Dato che sono nuovo in questo, devo ancora familiarizzare con molte cose. Grazie per la pazienza
João Paulo Pereira,

1
In Rasterio 1.x puoi usare source.xy (riga, colonna) per ottenere le coordinate geografiche.
bugmenot123


0

Prova con il seguente codice. Questo può essere usato per leggere i dati delle immagini dal raster e scrivere i dati elaborati nel raster (file .geotiff).

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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.