Processamento de imagens usando Python, GDAL e Scikit-Image

11

Estou lutando com um processamento e espero ser capaz de resolver aqui.

Trabalho com sensoriamento remoto aplicado à silvicultura, principalmente trabalhando com dados LiDAR. A idéia é usar o Scikit-image para detecção de copas das árvores. Como sou novo em Python, considerei um grande triunfo pessoal fazer o seguinte:

  1. Importar um CHM (com matplotlib);
  2. Execute um filtro gaussiano (com pacote scikit-image);
  3. Execute um filtro maxima (com pacote scikit-image);
  4. Execute o peak_local_max (com o pacote scikit-image);
  5. Mostre o CHM com o máximo local (com matplotlib);

Agora meu problema. Quando importo com matplot, a imagem perde suas coordenadas geográficas. Portanto, as coordenadas que tenho são apenas coordenadas básicas da imagem (ou seja, 250.312). O que eu preciso é obter o valor do pixel abaixo do ponto máximo local na imagem (pontos vermelhos na imagem). Aqui no fórum, vi um cara perguntando a mesma coisa ( Obtendo valor de pixel da varredura GDAL sob o ponto OGR sem NumPy? ), Mas ele já tinha os pontos em um shapefile. No meu caso, os pontos foram calculados com scikit-image (é uma matriz com as coordenadas de cada topo de árvore). Então, eu não tenho o shapefile.

Em conclusão, o que eu quero no final é um arquivo txt com as coordenadas de cada máximo local em coordenadas geográficas, por exemplo:

525412 62980123 1150 ...

Máximos locais (pontos vermelhos) em um CHM

João Paulo Pereira
fonte

Respostas:

11

Em primeiro lugar, bem-vindo ao site!

Matrizes numpy não têm um conceito de sistemas de coordenadas embutido na matriz. Para uma varredura 2D, eles são indexados por coluna e linha.

Observe que estou assumindo que você está lendo um formato raster suportado pelo GDAL .

No Python, a melhor maneira de importar dados de varredura espacial é com o rasteriopacote. Os dados brutos importados pelo rasterio ainda são uma matriz numpy sem acesso a sistemas de coordenadas, mas o rasterio também fornece acesso a um método afim na matriz de origem que você pode usar para transformar colunas e linhas de varredura em coordenadas projetadas. Por exemplo:

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 a partir daí, você pode escrever seus resultados em um arquivo de texto da maneira que desejar (sugiro dar uma olhada no módulo embutido csv, por exemplo).

om_henners
fonte
Muito obrigado. Parece que isso pode funcionar. Desde que sou novo nisso, ainda tenho que me familiarizar com muitas coisas. Obrigado pela paciência.
João Paulo Pereira
1
No Rasterio 1.x, você pode usar o source.xy (linha, coluna) para obter a coordenada geográfica.
precisa
0

De uma rápida olhada no matplotlib, eu diria que é necessário alterar as escalas de eixo após a importação.

ymirsson
fonte
Eu acho que o problema está na imagem do scikit. Quando o executo, o scikit muda automaticamente para as coordenadas da imagem.
João Paulo Pereira
0

Por favor, tente com o seguinte trecho de código. Isso pode ser usado para ler dados de imagem da varredura e gravar dados processados ​​na varredura (arquivo .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
fonte