2

I have to create NDVI's for multiple raster images, and so want to find out the most efficient way to do it.

The code below works, but I wondered if there was a more efficient way to do it?

# Strip out the red and near infrared bands    
arcpy.CompositeBands_management(input_raster + r"\Band_3", "raster_red")
arcpy.CompositeBands_management(input_raster + r"\Band_4", "raster_nearir")

# Create the ndvi numerator and denominators 
arcpy.Minus_3d("raster_nearir", "raster_red", "numerator")

arcpy.Plus_3d("raster_nearir", "raster_red", "denominator")

# Set local variables
top = arcpy.sa.Raster("numerator")
bottom = arcpy.sa.Raster("denominator")

# Execute Divide
raster_ndvi = top / bottom

# Save the output
raster_ndvi.save("ndvi_result")```
  • Also, if anyone can explain how to use GenerateRasterFromRasterFunction to do this(see arc pro documentation here) I would be much obliged. – Andrew Einhorn Jan 20 at 13:48
  • Ooops, sorry! Thanks again for your assistance here :) – Andrew Einhorn Jan 21 at 11:13
3

I would do something like this:

from arcpy.sa import *

input_raster = 'path/to/raster'

red = Float(Raster(input_raster + r"\Band_3"))  
nir = Float(Raster(input_raster + r"\Band_4"))

ndvi = (nir - red) / (nir + red)

ndvi.save("ndvi_result")

You could also use GenerateRasterFromRasterFunction_management, but that seems to take much the same processing time

import time

from arcpy.sa import *

input_raster = r"c:\temp\LC80900812014223LGN00.TIF"  # Some Landsat 8 data

s = time.time()
red = Float(Raster(input_raster + r"\Band_4"))    # Band names are 1 indexed
nir = Float(Raster(input_raster + r"\Band_5"))

ndvi = (nir - red) / (nir + red)

ndvi.save("c:/temp/ndvitest1.tif")

print("Map algebra:", time.time() - s)

s = time.time()
arcpy.GenerateRasterFromRasterFunction_management(
    raster_function="NDVI",
    out_raster_dataset=r"c:\temp\ndvitest2.tif", 
    raster_function_arguments=r"Raster c:\temp\LC80900812014223LGN00.TIF; VisibleBandID 3;InfraredBandID 4;ScientificOutput 1",  # Bands are 0 indexed
    format="TIFF")
print("GenerateRasterFromRasterFunction:", time.time() - s)
Map algebra: 17.283000230789185
GenerateRasterFromRasterFunction: 17.730000257492065
  • Thanks @user2856, this is a lot more succinct than my code, but has more or less the same runtime. Have you ever come across GenerateRasterFromRasterFunction - arcpro raster functions? And do you think it can be used for this purpose? – Andrew Einhorn Jan 20 at 13:42
  • 1
    @AndrewEinhorn See edit – user2856 Jan 21 at 0:30
  • Thanks a million for the demonstration! Try as I might, when I run the following code, I get an error. Can you see where I'm going wrong? from arcpy.sa import * arcpy.GenerateRasterFromRasterFunction_management(raster_function="NDVI", out_raster_dataset=r"D:\output_image.tif", raster_function_arguments=r"Raster D:\input_image.tif; VisibleBandID 3; InfraredBandID 4; ScientificOutput 1", format="TIFF") arcgisscripting.ExecuteError: Parameters are not valid. ERROR 000814: Invalid file type ERROR 000840: The value is not a String Failed to execute (GenerateRasterFromRasterFunction) – Andrew Einhorn Jan 21 at 6:31
  • 1
    Looks ok to me, suggest you ask a new question and provide your code, the error, full details of the input raster, and whether you can apply the ndvi raster function manually via ArcGIS Pro (not GenerateRasterFromRasterFunction, just the function itself). – user2856 Jan 21 at 7:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.