I am attempting to compare NDVI calculations using ArcPy (experienced) and NumPy (newbie), but running into a MemoryError
, at the line indicated in the script below.
The shape and dtype of the arrays created by RasterToNumPyArray
are (8191, 8101)
and uint16
. This is the size of a standard Landsat 8 image.
Is this an unreasonable size to expect to process? Is the problem that division promotes the dtype to accommodate decimals (diff
and sum
complete successfully)? If so, can I force an integer output somehow?
import cProfile, numpy
def arcpyNDVI():
NIRras = arcpy.Raster("LC80460222013184LGN00_B5.TIF")
REDras = arcpy.Raster("LC80460222013184LGN00_B4.TIF")
NDVIap = (NIRras - arcpy.sa.Float(REDras))/ (NIRras + REDras)
NDVIap.save(r'C:/junk/ap_ras.tif')
def numpyNDVI():
NIRras = arcpy.Raster("LC80460222013184LGN00_B5.TIF")
NIRll = arcpy.Point(NIRras.extent.XMin,NIRras.extent.YMin)
NIRcs = NIRras.meanCellWidth
REDras = arcpy.Raster("LC80460222013184LGN00_B4.TIF")
arcpy.env.outputCoordinateSystem = NIRras.spatialReference
NIRnp = arcpy.RasterToNumPyArray(NIRras)
REDnp = arcpy.RasterToNumPyArray(REDras)
diff = NIRnp - REDnp
sum = NIRnp + REDnp
NDVInp = diff / sum # MEMORY ERROR HERE
NDVInpRas = arcpy.NumPyArrayToRaster(NDVInp,NIRll,NIRcs,NIRcs)
NDVInpRas.save(r'C:/junk/np_ras.tif')
cProfile.runctx('arcpyNDVI()',None,locals())
cProfile.runctx('numpyNDVI()',None,locals())
update1: the above script sometimes runs to completion (sometimes gives MemoryError), but it outputs uint16
, while I need decimals. Upon changing the line:
NDVInp = diff / sum
to: NDVInp = numpy.true_divide(diff,sum)
, I consistently get:
Runtime error
Traceback (most recent call last):
File "<string>", line 24, in <module>
File "C:\Anaconda\Lib\cProfile.py", line 49, in runctx
prof = prof.runctx(statement, globals, locals)
File "C:\Anaconda\Lib\cProfile.py", line 140, in runctx
exec cmd in globals, locals
File "<string>", line 1, in <module>
File "<string>", line 17, in numpyNDVI
MemoryError