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

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).


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

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()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.