Caricare completamente il raster in un array intorpidito?


26

Ho provato a controllare i miei filtri su DEM raster per il riconoscimento di schemi e mi risulta sempre che mancino le ultime righe e colonne (come..20) . Ho provato con la libreria PIL, caricamento dell'immagine. Quindi con intorpidimento. L'output è lo stesso.

Ho pensato, qualcosa non va nei miei loop, quando ho verificato i valori nell'array (solo selezionando i pixel con Identification in ArcCatalog) mi sono reso conto che i valori dei pixel non erano caricati in un array.

Quindi, basta semplicemente aprire, mettere in array e salvare l'immagine dall'array:

a=numpy.array(Image.open(inraster)) #raster is .tif Float32, size 561x253
newIm=Image.new(Im.mode, Im.size)
Image.fromarray(a).save(outraster)

Risultati nel tagliare via le ultime righe e colonne. Siamo spiacenti, non posso pubblicare l'immagine

Qualcuno potrebbe aiutare a capire perché? E consigliare qualche soluzione?

MODIFICARE:

Quindi, sono riuscito a caricare piccoli raster nell'array intorpidito con l'aiuto di ragazzi, ma quando ho un'immagine più grande inizio a ricevere errori. Suppongo si tratti dei limiti dell'array intorpidito, e quindi l'array viene automaticamente rimodellato o smth in quel modo ... Quindi es:

Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    ima=numpy.array(inDs.GetRasterBand(1).ReadAsArray())
  File "C:\Python25\lib\site-packages\osgeo\gdal.py", line 835, in ReadAsArray
    buf_xsize, buf_ysize, buf_obj )
  File "C:\Python25\lib\site-packages\osgeo\gdal_array.py", line 140, in BandReadAsArray
    ar = numpy.reshape(ar, [buf_ysize,buf_xsize])
  File "C:\Python25\lib\site-packages\numpy\core\fromnumeric.py", line 108, in reshape
    return reshape(newshape, order=order)
ValueError: total size of new array must be unchanged

Il punto è che non voglio leggere blocco per blocco poiché ho bisogno di filtraggio, più volte con filtri diversi, dimensioni diverse. C'è qualche soluzione o devo imparare a radicare per blocchi: O

Risposte:


42

se hai attacchi python-gdal:

import numpy as np
from osgeo import gdal
ds = gdal.Open("mypic.tif")
myarray = np.array(ds.GetRasterBand(1).ReadAsArray())

E hai finito:

myarray.shape
(2610,4583)
myarray.size
11961630
myarray
array([[        nan,         nan,         nan, ...,  0.38068664,
     0.37952521,  0.14506227],
   [        nan,         nan,         nan, ...,  0.39791253,
            nan,         nan],
   [        nan,         nan,         nan, ...,         nan,
            nan,         nan],
   ..., 
   [ 0.33243281,  0.33221543,  0.33273876, ...,         nan,
            nan,         nan],
   [ 0.33308044,  0.3337177 ,  0.33416209, ...,         nan,
            nan,         nan],
   [ 0.09213851,  0.09242494,  0.09267616, ...,         nan,
            nan,         nan]], dtype=float32)

Sì, con Gdal immagino di non avere problemi, ma sto cercando di usare meno librerie ... E intorpidito mi è sembrato così popolare per quel "mentre cercavo su Google". Qualche idea, infatti, perché numpy / PIL smette di caricarsi ???
najuste,

Non lo so. PIL dovrebbe essere abbastanza robusto da essere spedito con Python. Ma imho geotiff sono più che immagini - portano ad esempio molti metadati - e PIL non è (di nuovo imho) lo strumento giusto.
Nicks,

A volte odio quei requisiti di quotazione diff e barra, quando si aprono i dati .. Ma per quanto riguarda la scrittura di array numpy di nuovo su Raster? Funziona con la libreria PIL, ma utilizzando outputRaster.GetRasterBand (1) .WriteArray (myarray) produce un raster non valido ..
najuste

non dimenticare di scaricare i dati sul disco, con outBand.FlushCache (). Puoi trovare alcuni tutorial qui: gis.usu.edu/~chrisg/python/2009
nickves,

1
Controlla " lists.osgeo.org/pipermail/gdal-dev/2010-January/023309.html " - sembra che tu abbia esaurito o speronato.
Nickves,

21

È possibile utilizzare rasterio per interfacciarsi con gli array NumPy. Per leggere un raster su un array:

import rasterio

with rasterio.open('/path/to/raster.tif', 'r') as ds:
    arr = ds.read()  # read all raster values

print(arr.shape)  # this is a 3D numpy array, with dimensions [band, row, col]

Questo leggerà tutto in un array 3D intorpidito arr, con dimensioni [band, row, col].


Ecco un esempio avanzato per leggere, modificare un pixel, quindi salvarlo nel raster:

with rasterio.open('/path/to/raster.tif', 'r+') as ds:
    arr = ds.read()  # read all raster values
    arr[0, 10, 20] = 3  # change a pixel value on band 1, row 11, column 21
    ds.write(arr)

Il raster verrà scritto e chiuso alla fine dell'istruzione "with" .


Perché non possiamo vedere tutti i valori quando scrivo print (arr). Separa i valori con questo ..., ...,?
Mustafa Uçar,

@ MustafaUçar questo è il modo in cui NumPy stampa gli array, che è possibile modificare . O tagliare una finestra dell'array da stampare, tra molti altri trucchi Numpy.
Mike T,

Una domanda generale Se voglio produrre un singolo array con più scene, essendo quattro dimensioni come (scena, altezza, larghezza, bande), come devo modificare questo frammento?
Ricardo Barros Lourenço,

@ RicardoBarrosLourenço Immagino che la tua quarta dimensione (scena?) Sia memorizzata in ogni file. Innanzitutto popolerei un array numpy 4D vuoto, quindi eseguo il ciclo attraverso ogni file (scena) e inserisco la porzione 3D di ciascuno. Potrebbe essere necessario arr.transpose((1, 2, 0))ottenere (altezza, larghezza, bande) da ciascun file.
Mike T

@MikeT questa popolazione sarebbe tale np.append()?
Ricardo Barros Lourenço,

3

Concesso che sto leggendo una semplice vecchia immagine png, ma funziona con scipy ( imsaveusa però PIL):

>>> import scipy
>>> import numpy
>>> img = scipy.misc.imread("/home/chad/logo.png")
>>> img.shape
(81, 90, 4)
>>> array = numpy.array(img)
>>> len(array)
81
>>> scipy.misc.imsave('/home/chad/logo.png', array)

Il mio png risultante è anche 81 x 90 pixel.


Grazie, ma sto cercando di usare meno librerie .. E per ora posso farcela con gdal + numpy ... (speriamo senza PIL).
najuste,

1
@najuste Su quali sistemi operativi sono attivi? Mac e la maggior parte dei gusti Linux vengono forniti con scipye numpy.
Chad Cooper,

Apparentemente ... Sono su Windows, varie versioni di Win. : /
najuste l'

2

La mia soluzione usando gdal è simile a questa. Penso che sia molto riutilizzabile.

import gdal
import osgeo.gdalnumeric as gdn

def img_to_array(input_file, dim_ordering="channels_last", dtype='float32'):
    file  = gdal.Open(input_file)
    bands = [file.GetRasterBand(i) for i in range(1, file.RasterCount + 1)]
    arr = np.array([gdn.BandReadAsArray(band) for band in bands]).astype(dtype)
    if dim_ordering=="channels_last":
        arr = np.transpose(arr, [1, 2, 0])  # Reorders dimensions, so that channels are last
    return arr

0

sto usando un'immagine iperspettrale con 158 bande. Voglio calcolare il raster. ma capisco

import gdal # Import GDAL library bindings
from osgeo.gdalnumeric import *
from osgeo.gdalconst import *
import pylab as plt
import numpy as np
import xlrd
# The file that we shall be using
# Needs to be on current directory
filename = ('C:/Users/KIFF/Desktop/These/data/Hyperion/10th_bandmathref')
outFile = ('C:/Users/KIFF/Desktop/These/data/Hyperion/Math')
XLS=('C:/Users/KIFF/Desktop/These/data/Coef/bcoef.xlsx')
wb = xlrd.open_workbook(XLS)
sheet = wb.sheet_by_index(0)
sheet.cell_value(0, 0)


g = gdal.Open(filename, GA_ReadOnly)

# g should now be a GDAL dataset, but if the file isn't found
# g will be none. Let's test this:
if g is None:
    print ("Problem opening file %s!" % filename)
else:
    print ("File %s opened fine" % filename )

#band_array = g.ReadAsArray()
#print(band_array)
print ("[ RASTER BAND COUNT ]: ", g.RasterCount)

for band in range( g.RasterCount ):
    print (band)
    band += 1
    outFile = ('C:/Users/KIFF/Desktop/These/data/Results/Temp/Math_1_sur_value'+str(band)+'.tiff')
    #print ("[ GETTING BAND ]: ", band )
    srcband = g.GetRasterBand(band)
    if srcband is None:
        continue
    data1 = BandReadAsArray(srcband).astype(np.float)
    print(data1)
   # for i in range(3,sheet.nrows):
    b=sheet.cell_value(band+2,1)
    #print(b)
    dataOut = (1/data1)
    driver = gdal.GetDriverByName("ENVI")
    dsOut = driver.Create(outFile, g.RasterXSize, g.RasterYSize, 1)
    CopyDatasetInfo(g,dsOut)
    bandOut=dsOut.GetRasterBand(1)
    BandWriteArray(bandOut, dataOut)

per il print(data1)ho solo un po '"1", ma i valori reali sono alcuni float

0
[[1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 ...
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]]
1
[[1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 ...
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]
 [1. 1. 1. ... 1. 1. 1.]]
2

Valore pixel 0,139200

Per favore aiutate a trovare l'errore

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.