Ich habe ein Raster, mit dem ich einige Punktinterpolationen durchführen möchte. Hier bin ich:
from osgeo import gdal
from numpy import array
# Read raster
source = gdal.Open('my_raster.tif')
nx, ny = source.RasterXSize, source.RasterYSize
gt = source.GetGeoTransform()
band_array = source.GetRasterBand(1).ReadAsArray()
# Close raster
source = None
# Compute mid-point grid spacings
ax = array([gt[0] + ix*gt[1] + gt[1]/2.0 for ix in range(nx)])
ay = array([gt[3] + iy*gt[5] + gt[5]/2.0 for iy in range(ny)])
Bisher habe ich die interp2d- Funktion von SciPy ausprobiert :
from scipy import interpolate
bilinterp = interpolate.interp2d(ax, ay, band_array, kind='linear')
Auf meinem 32-Bit-Windows-System mit einem Raster von 317 × 301 wird jedoch ein Speicherfehler angezeigt:
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python25\Lib\site-packages\scipy\interpolate\interpolate.py", line 125, in __init__
self.tck = fitpack.bisplrep(self.x, self.y, self.z, kx=kx, ky=ky, s=0.)
File "C:\Python25\Lib\site-packages\scipy\interpolate\fitpack.py", line 873, in bisplrep
tx,ty,nxest,nyest,wrk,lwrk1,lwrk2)
MemoryError
Ich gebe zu , ich begrenzte Vertrauen in diese SciPy Funktion haben, wie die bounds_error
oder fill_value
Parameter funktionieren nicht dokumentiert. Ich verstehe nicht, warum ich einen Speicherfehler haben sollte, da mein Raster 317 × 301 ist und der bilineare Algorithmus nicht schwierig sein sollte.
Hat jemand einen guten bilinearen Interpolationsalgorithmus gefunden, vorzugsweise in Python, der möglicherweise auf NumPy zugeschnitten ist? Irgendwelche Hinweise oder Ratschläge?
(Hinweis: Der Interpolationsalgorithmus für den nächsten Nachbarn ist einfach:
from numpy import argmin, NAN
def nearest_neighbor(px, py, no_data=NAN):
'''Nearest Neighbor point at (px, py) on band_array
example: nearest_neighbor(2790501.920, 6338905.159)'''
ix = int(round((px - (gt[0] + gt[1]/2.0))/gt[1]))
iy = int(round((py - (gt[3] + gt[5]/2.0))/gt[5]))
if (ix < 0) or (iy < 0) or (ix > nx - 1) or (iy > ny - 1):
return no_data
else:
return band_array[iy, ix]
... aber ich bevorzuge bilineare Interpolationsmethoden)
quelle
MemoryError
weil NumPy versucht, über deine Grenzen hinaus zuzugreifenband_array
? Sie solltenax
und überprüfenay
.gt
.Antworten:
Ich habe die folgende Formel (aus Wikipedia ) in Python-Sprache übersetzt, um den folgenden Algorithmus zu erhalten, der zu funktionieren scheint.
Beachten Sie, dass das Ergebnis mit einer offensichtlich höheren Genauigkeit als die Quelldaten zurückgegeben wird, da es dem
dtype('float64')
Datentyp von NumPy zugeordnet ist . Sie können den Rückgabewert mit verwenden.astype(band_array.dtype)
, um den Ausgabedatentyp mit dem Eingabearray gleichzusetzen.quelle
Ich habe es lokal mit ähnlichen Ergebnissen versucht, aber ich arbeite auf einer 64-Bit-Plattform, sodass das Speicherlimit nicht überschritten wurde. Versuchen Sie stattdessen, kleine Teile des Arrays gleichzeitig zu interpolieren, wie in diesem Beispiel .
Sie könnten dies auch einfach mit GDAL tun, von der Kommandozeile aus wäre es:
Verwenden Sie ReprojectImage () , um die entsprechende Operation in Python auszuführen :
quelle
ReprojectImage
Technik von GDAL nicht verwenden .Ich hatte das genaue Problem in der Vergangenheit und habe es nie mit interpolate.interp2d gelöst. Ich hatte Erfolg mit scipy.ndimage.map_coordinates . Versuche Folgendes:
scipy.ndimage.map_coordinates (band_array, [ax, ay]], order = 1)
Dies scheint die gleiche Ausgabe zu liefern wie bilinear.
quelle
scipy.interpolate.interp2d () funktioniert gut mit moderneren scipy. Ich denke, ältere Versionen gehen von unregelmäßigen Rastern aus und nutzen die regulären Raster nicht aus. Ich bekomme den gleichen Fehler wie bei scipy. version = 0.11.0, aber auf scipy. version = 0.14.0, funktioniert problemlos mit einigen 1600x1600-Modellausgaben.
Vielen Dank für die Hinweise in Ihrer Frage.
quelle