A Normalized Difference Vegetation Index (NDVI) is one of the oldest remote sensing algorithms used to detect green vegetation in an area of interest, using the red and near-infrared bands of an image. The chlorophyll in plants absorbs visible light, including the red band, while the cell structures of plants reflect near-infrared light. The NDVI formula provides a ratio of near-infrared light to the total incoming radiation, which serves as an indicator of vegetation density. This recipe will use Python to control the QGIS raster calculator in order to create an NDVI using a multispectral image of a farm field.
Download the image from https://geospatialpython.googlecode.com/svn/farm-field.tif and place it in your qgis_data
to a directory named rasters
.
We will load the raster as a QGIS raster layer, perform the NDVI algorithm, and finally apply a color ramp to the raster so that we can easily visualize the green vegetation in the image. To do this, we need to perform the following steps:
from PyQt4.QtGui import * from PyQt4.QtCore import * from qgis.analysis import *
rasterName = "farm" raster = QgsRasterLayer("/Users/joellawhead/qgis_data/ rasters/farm-field.tif", rasterName)
ir = QgsRasterCalculatorEntry() r = QgsRasterCalculatorEntry()
ir.raster = raster r.raster = raster
ir.bandNumber = 2 r.bandNumber = 1
@
symbol and the band number as a suffix:ir.ref = rasterName + "@2" r.ref = rasterName + "@1"
references = (ir.ref, r.ref, ir.ref, r.ref) exp = "1.0 * (%s - %s) / 1.0 + (%s + %s)" % references
output = "/Users/joellawhead/qgis_data/rasters/ndvi.tif"
e = raster.extent() w = raster.width() h = raster.height() entries = [ir,r]
ndvi = QgsRasterCalculator(exp, output, "GTiff", e, w, h, entries) ndvi.processCalculation()
lyr = QgsRasterLayer(output, "NDVI")
algorithm = QgsContrastEnhancement.StretchToMinimumMaximum limits = QgsRaster.ContrastEnhancementMinMax lyr.setContrastEnhancement(algorithm, limits)
s = QgsRasterShader() c = QgsColorRampShader() c.setColorRampType(QgsColorRampShader.INTERPOLATED)
ColorRampItem
object:i = [] qri = QgsColorRampShader.ColorRampItem i.append(qri(0, QColor(0,0,0,0), 'NODATA')) i.append(qri(214, QColor(120,69,25,255), 'Lowest Biomass')) i.append(qri(236, QColor(255,178,74,255), 'Lower Biomass')) i.append(qri(258, QColor(255,237,166,255), 'Low Biomass')) i.append(qri(280, QColor(173,232,94,255), 'Moderate Biomass')) i.append(qri(303, QColor(135,181,64,255), 'High Biomass')) i.append(qri(325, QColor(3,156,0,255), 'Higher Biomass')) i.append(qri(400, QColor(1,100,0,255), 'Highest Biomass'))
c.setColorRampItemList(i) s.setRasterShaderFunction(c) ps = QgsSingleBandPseudoColorRenderer(lyr.dataProvider(), 1, s) lyr.setRenderer(ps)
QgsMapLayerRegistry.instance().addMapLayer(lyr)
The QGIS raster calculator is exactly what its name implies. It allows you to perform array math on images. Both the QGIS raster menu and the Processing Toolbox have several raster processing tools, but the raster calculator can perform custom analysis that can be defined in a single mathematical equation. The NDVI algorithm is the infrared band minus the red band divided by the infrared band plus the red band, or (IR-R)/(IR+R). In our calculator expression, we multiply each side of the equation by 1.0
to avoid division-by-zero errors. Your output should look similar to the following image if you load the result into QGIS. In this screenshot, NODATA
values are represented as black; however, your QGIS installation may default to using white: