Math operations
Mathematical operations
Reference: https://developers.google.com/earth-engine/guides/image_math
Earth Engine supports many basic mathematical operators. They share some common features. Earth Engine performs math operations per pixel. When an operator is applied to an image, it's applied to each unmasked pixel of each band. In the case of operations on two images, the operation is only applied at the locations where pixels in both images are unmasked. Earth Engine automatically matches bands between images. When an operator is applied to two images, the images are expected to have the same number of bands so they can be matched pairwise. However, if one of the images has only a single band, it is matched with all of the bands in the other image, essentially replicating that band enough times to match the other image.
import ee
import geemap
Map = geemap.Map()
Operators¶
Math operators perform basic arithmetic operations on image bands. They take two inputs: either two images or one image and a constant term, which is interpreted as a single-band constant image with no masked pixels. Operations are performed per pixel for each band.
As a simple example, consider the task of calculating the Normalized Difference Vegetation Index (NDVI) using Landsat imagery, where add()
, subtract()
, and divide()
operators are used:
# Load a 5-year Landsat 7 composite 1999-2003.
landsat1999 = ee.Image('LANDSAT/LE7_TOA_5YEAR/1999_2003')
# Compute NDVI.
NIR = landsat1999.select('B4')
Red = landsat1999.select('B3')
ndvi1999 = NIR.subtract(Red).divide(NIR.add(Red))
# ndvi1999 = landsat1999.normalizedDifference(['B4', 'B3'])
palette = [
'FFFFFF',
'CE7E45',
'DF923D',
'F1B555',
'FCD163',
'99B718',
'74A901',
'66A000',
'529400',
'3E8601',
'207401',
'056201',
'004C00',
'023B01',
'012E01',
'011D01',
'011301',
]
Map.addLayer(ndvi1999, {'palette': palette}, "NDVI 1999")
Map
Only the intersection of unmasked pixels between the two inputs are considered and returned as unmasked, all else are masked. In general, if either input has only one band, then it is used against all the bands in the other input. If the inputs have the same number of bands, but not the same names, they're used pairwise in the natural order. The output bands are named for the longer of the two inputs, or if they're equal in length, in the first input's order. The type of the output pixels is the union of the input types.
The following example of multi-band image subtraction demonstrates how bands are matched automatically, resulting in a “change vector” for each pixel for each co-occurring band.
# Load a 5-year Landsat 7 composite 2008-2012.
landsat2008 = ee.Image('LANDSAT/LE7_TOA_5YEAR/2008_2012')
# Compute multi-band difference between the 2008-2012 composite and the
# previously loaded 1999-2003 composite.
diff = landsat2008.subtract(landsat1999)
Map.addLayer(diff, {'bands': ['B4', 'B3', 'B2'], 'min': -32, 'max': 32}, 'difference')
# Compute the squared difference in each band.
squaredDifference = diff.pow(2)
Map.addLayer(
squaredDifference, {'bands': ['B4', 'B3', 'B2'], 'max': 1000}, 'squared diff.'
)
Map
In the second part of this example, the squared difference is computed using image.pow(2)
. For the complete list of mathematical operators handling basic arithmetic, trigonometry, exponentiation, rounding, casting, bitwise operations and more, see the API documentation (in the Docs tab of the Earth Engine Code Editor).
Expressions¶
To implement more complex mathematical expressions, it may be more convenient to use image.expression()
, which parses a text representation of a math operation. The following example uses expression()
to compute the Enhanced Vegetation Index (EVI):
Map = geemap.Map()
# Load a Landsat 8 image.
image = ee.Image('LANDSAT/LC08/C01/T1_TOA/LC08_044034_20140318')
# Compute the EVI using an expression.
evi = image.expression(
'2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))',
{'NIR': image.select('B5'), 'RED': image.select('B4'), 'BLUE': image.select('B2')},
)
Map.centerObject(image, 9)
Map.addLayer(image, {'bands': ['B5', 'B4', 'B3']}, 'Landsat 8')
Map.addLayer(evi, {'min': -1, 'max': 1, 'palette': ['FF0000', '00FF00']}, 'EVI')
Map
Observe that the first argument to expression is the textual representation of the math operation, the second argument is a dictionary where the keys are variable names used in the expression and the values are the image bands to which the variables should be mapped. Bands in the image may be referred to as b("band name")
or b(index)
, for example b(0)
, instead of providing the dictionary. Note that division functions as it does in Python: dividing two integers results in an integer. For example 10 / 20 = 0
. To change this behavior, multiply one of the operands by 1.0: 10 * 1.0 / 20 = 0.5
. Supported expression operators are listed in the following table.