Procesamiento de imagen usando Python, GDAL y Scikit-Image

11

Estoy luchando con un procesamiento y espero poder resolverlo aquí.

Trabajo con teledetección aplicada a la silvicultura, especialmente trabajando con datos LiDAR. La idea es utilizar Scikit-image para la detección de la parte superior del árbol. Como soy nuevo en Python, consideré un gran triunfo personal hacer lo siguiente:

  1. Importar un CHM (con matplotlib);
  2. Ejecute un filtro gaussiano (con el paquete scikit-image);
  3. Ejecute un filtro maxima (con el paquete scikit-image);
  4. Ejecute peak_local_max (con el paquete scikit-image);
  5. Muestre el CHM con los máximos locales (con matplotlib);

Ahora mi problema. Cuando importo con matplot, la imagen pierde sus coordenadas geográficas. Entonces, las coordenadas que tengo son solo coordenadas de imagen básicas (es decir, 250,312). Lo que necesito es obtener el valor del píxel debajo del punto máximo local en la imagen (puntos rojos en la imagen). Aquí en el foro vi a un chico preguntando lo mismo (¿ Obteniendo el valor de píxel del ráster GDAL bajo el punto OGR sin NumPy? ), Pero ya tenía los puntos en un archivo de forma. En mi caso, los puntos se calcularon con scikit-image (es una matriz con las coordenadas de cada parte superior del árbol). Entonces no tengo el shapefile.

En conclusión, lo que quiero al final es un archivo txt con las coordenadas de cada máximo local en coordenadas geográficas, por ejemplo:

525412 62980123 1150 ...

Máximos locales (puntos rojos) en un CHM

João Paulo Pereira
fuente

Respuestas:

11

En primer lugar, bienvenido al sitio!

Las matrices Numpy no tienen un concepto de sistemas de coordenadas incorporados en la matriz. Para un ráster 2D, se indexan por columna y fila.

Tenga en cuenta que supongo que está leyendo un formato ráster compatible con GDAL .

En Python, la mejor manera de importar datos ráster espaciales es con el rasteriopaquete. Los datos brutos importados por rasterio siguen siendo una matriz numpy sin acceso a sistemas de coordenadas, pero rasterio también le da acceso a un método afín en la matriz fuente que puede usar para transformar columnas y filas ráster en coordenadas proyectadas. Por ejemplo:

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)

Y a partir de ahí, puede escribir sus resultados en un archivo de texto como desee (sugeriría echar un vistazo al módulo incorporado csv, por ejemplo).

om_henners
fuente
Muchas gracias. Parece que esto puede funcionar. Como soy nuevo en esto, todavía tengo que familiarizarme con muchas cosas. Gracias por la paciencia
João Paulo Pereira
1
En Rasterio 1.x puede usar source.xy (fila, columna) para obtener la coordenada geográfica.
bugmenot123
0

De un vistazo rápido a matplotlib, diría que tiene que modificar las escalas del eje después de la importación.

ymirsson
fuente
Creo que el problema está en scikit-image. Cuando lo ejecuto, scikit cambia automáticamente a coordenadas de imagen.
João Paulo Pereira
0

Por favor, intente con el siguiente código. Esto se puede usar para leer datos de imágenes de ráster y escribir datos procesados ​​en ráster (archivo .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()
sckulkarni
fuente