Announcement: All noncommercial projects registered to use Earth Engine before
April 15, 2025 must
verify noncommercial eligibility to maintain Earth Engine access.
Mathematical Operations
Stay organized with collections
Save and categorize content based on your preferences.
Image math can be performed using operators like add()
and
subtract()
, but for complex computations with more than a couple of terms, the
expression()
function provides a good alternative. See the following sections
for more information on operators and
expressions.
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 basic example, consider the task of calculating the Normalized Difference Vegetation
Index (NDVI) using VIIRS imagery, where add()
, subtract()
,
and divide()
operators are used:
Code Editor (JavaScript)
// Load a VIIRS 8-day surface reflectance composite for May 2024.
var viirs202405 = ee.ImageCollection('NASA/VIIRS/002/VNP09H1').filter(
ee.Filter.date('2024-05-01', '2024-05-16')).first();
// Compute NDVI.
var ndvi202405 = viirs202405.select('SurfReflect_I2')
.subtract(viirs202405.select('SurfReflect_I1'))
.divide(viirs202405.select('SurfReflect_I2')
.add(viirs202405.select('SurfReflect_I1')));
Python setup
See the
Python Environment page for information on the Python API and using
geemap
for interactive development.
import ee
import geemap.core as geemap
Colab (Python)
# Load a VIIRS 8-day surface reflectance composite for May 2024.
viirs202405 = (
ee.ImageCollection('NASA/VIIRS/002/VNP09H1')
.filter(ee.Filter.date('2024-05-01', '2024-05-16'))
.first()
)
# Compute NDVI.
ndvi202405 = (
viirs202405.select('SurfReflect_I2')
.subtract(viirs202405.select('SurfReflect_I1'))
.divide(
viirs202405.select('SurfReflect_I2').add(
viirs202405.select('SurfReflect_I1')
)
)
)
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.
Code Editor (JavaScript)
// Load a VIIRS 8-day surface reflectance composite for September 2024.
var viirs202409 = ee.ImageCollection('NASA/VIIRS/002/VNP09H1').filter(
ee.Filter.date('2024-09-01', '2024-09-16')).first();
// Compute multi-band difference between the September composite and the
// previously loaded May composite.
var diff = viirs202409.subtract(ndvi202405);
Map.addLayer(diff, {
bands: ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],
min: -1,
max: 1
}, 'difference');
// Compute the squared difference in each band.
var squaredDifference = diff.pow(2);
Map.addLayer(squaredDifference, {
bands: ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],
min: 0,
max: 0.7
}, 'squared diff.');
Python setup
See the
Python Environment page for information on the Python API and using
geemap
for interactive development.
import ee
import geemap.core as geemap
Colab (Python)
# Load a VIIRS 8-day surface reflectance composite for September 2024.
viirs202409 = (
ee.ImageCollection('NASA/VIIRS/002/VNP09H1')
.filter(ee.Filter.date('2024-09-01', '2024-09-16'))
.first()
)
# Compute multi-band difference between the September composite and the
# previously loaded May composite.
diff = viirs202409.subtract(ndvi202405)
m = geemap.Map()
m.add_layer(
diff,
{
'bands': ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],
'min': -1,
'max': 1,
},
'difference',
)
# Compute the squared difference in each band.
squared_difference = diff.pow(2)
m.add_layer(
squared_difference,
{
'bands': ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],
'min': 0,
'max': 0.7,
},
'squared diff.',
)
display(m)
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.
Expressions
To implement more complex mathematical expressions, consider using
image.expression()
, which parses a text representation of a math operation.
The following example uses expression()
to compute the Enhanced
Vegetation Index (EVI):
Code Editor (JavaScript)
// Load a Landsat 8 image.
var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318');
// Compute the EVI using an expression.
var 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(evi, {min: -1, max: 1, palette: ['a6611a', 'f5f5f5', '4dac26']});
Python setup
See the
Python Environment page for information on the Python API and using
geemap
for interactive development.
import ee
import geemap.core as geemap
Colab (Python)
# Load a Landsat 8 image.
image = ee.Image('LANDSAT/LC08/C02/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'),
},
)
# Define a map centered on San Francisco Bay.
map_evi = geemap.Map(center=[37.4675, -122.1363], zoom=9)
# Add the image layer to the map and display it.
map_evi.add_layer(
evi, {'min': -1, 'max': 1, 'palette': ['a6611a', 'f5f5f5', '4dac26']}, 'evi'
)
display(map_evi)
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. Bands can be defined from images other than the input when using
the band map dictionary. Note that expression()
uses "floor division", which
discards the remainder and returns an integer when two integers are divided. For example
10 / 20 = 0
. To change this behavior, multiply one of the operands by
1.0
: 10 * 1.0 / 20 = 0.5
. Only the intersection of unmasked pixels
are considered and returned as unmasked when bands from more than one source image are
evaluated. Supported expression operators are listed in the following table.
Operators for expression()
Type |
Symbol |
Name |
Arithmetic |
+ - * / % ** |
Add, Subtract, Multiply, Divide, Modulus, Exponent |
Relational |
== != < > <= >= |
Equal, Not Equal, Less Than, Greater than, etc. |
Logical |
&& || ! ^ |
And, Or, Not, Xor |
Ternary |
? : |
If then else |
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2024-12-16 UTC.
[null,null,["Last updated 2024-12-16 UTC."],[[["\u003cp\u003eEarth Engine provides tools for performing image math, including operators for basic arithmetic and the \u003ccode\u003eexpression()\u003c/code\u003e function for complex computations.\u003c/p\u003e\n"],["\u003cp\u003eOperators like \u003ccode\u003eadd()\u003c/code\u003e, \u003ccode\u003esubtract()\u003c/code\u003e, and \u003ccode\u003edivide()\u003c/code\u003e enable pixel-wise calculations between images or an image and a constant.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003eexpression()\u003c/code\u003e function allows implementing custom formulas by parsing text representations of mathematical operations and mapping variables to image bands.\u003c/p\u003e\n"],["\u003cp\u003eWhen using \u003ccode\u003eexpression()\u003c/code\u003e, ensure to handle integer division appropriately by multiplying one operand by \u003ccode\u003e1.0\u003c/code\u003e to preserve decimal values if needed.\u003c/p\u003e\n"],["\u003cp\u003eBoth operators and expressions automatically handle band matching and masking, considering only unmasked pixels in the calculations.\u003c/p\u003e\n"]]],[],null,["# Mathematical Operations\n\n|---------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|\n| [Run in Google Colab](https://colab.research.google.com/github/google/earthengine-community/blob/master/guides/linked/generated/image_math.ipynb) | [View source on GitHub](https://github.com/google/earthengine-community/blob/master/guides/linked/generated/image_math.ipynb) |\n\nImage math can be performed using operators like `add()` and\n`subtract()`, but for complex computations with more than a couple of terms, the\n`expression()` function provides a good alternative. See the following sections\nfor more information on [operators](#operators) and\n[expressions](#expressions).\n\nOperators\n---------\n\nMath operators perform basic arithmetic operations on image bands. They take two inputs:\neither two images or one image and a constant term, which\nis interpreted as a single-band constant image with no masked pixels. Operations are performed\nper pixel for each band.\n\nAs a basic example, consider the task of calculating the Normalized Difference Vegetation\nIndex (NDVI) using VIIRS imagery, where `add()`, `subtract()`,\nand `divide()` operators are used:\n\n### Code Editor (JavaScript)\n\n```javascript\n// Load a VIIRS 8-day surface reflectance composite for May 2024.\nvar viirs202405 = ee.ImageCollection('NASA/VIIRS/002/VNP09H1').filter(\n ee.Filter.date('2024-05-01', '2024-05-16')).first();\n\n// Compute NDVI.\nvar ndvi202405 = viirs202405.select('SurfReflect_I2')\n .subtract(viirs202405.select('SurfReflect_I1'))\n .divide(viirs202405.select('SurfReflect_I2')\n .add(viirs202405.select('SurfReflect_I1')));\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Load a VIIRS 8-day surface reflectance composite for May 2024.\nviirs202405 = (\n ee.ImageCollection('NASA/VIIRS/002/VNP09H1')\n .filter(ee.Filter.date('2024-05-01', '2024-05-16'))\n .first()\n)\n\n# Compute NDVI.\nndvi202405 = (\n viirs202405.select('SurfReflect_I2')\n .subtract(viirs202405.select('SurfReflect_I1'))\n .divide(\n viirs202405.select('SurfReflect_I2').add(\n viirs202405.select('SurfReflect_I1')\n )\n )\n)\n```\n| **Note:** the normalized difference operation is available as a shortcut method: [`normalizedDifference()`](/earth-engine/apidocs/ee-image-normalizeddifference).\n\nOnly the intersection of unmasked pixels between the two inputs are\nconsidered and returned as unmasked, all else are masked. In general, if either input has only\none band, then it is used against all the bands in the other input. If the inputs have the same\nnumber of bands, but not the same names, they're used pairwise in the natural order. The\noutput bands are named for the longer of the two inputs, or if they're equal in length, in the\nfirst input's order. The type of the output pixels is the union of the input types.\n\nThe following example of multi-band image subtraction demonstrates how bands are matched\nautomatically, resulting in a \"change vector\" for each pixel for each co-occurring band.\n\n### Code Editor (JavaScript)\n\n```javascript\n// Load a VIIRS 8-day surface reflectance composite for September 2024.\nvar viirs202409 = ee.ImageCollection('NASA/VIIRS/002/VNP09H1').filter(\n ee.Filter.date('2024-09-01', '2024-09-16')).first();\n\n// Compute multi-band difference between the September composite and the\n// previously loaded May composite.\nvar diff = viirs202409.subtract(ndvi202405);\nMap.addLayer(diff, {\n bands: ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],\n min: -1,\n max: 1\n}, 'difference');\n\n// Compute the squared difference in each band.\nvar squaredDifference = diff.pow(2);\nMap.addLayer(squaredDifference, {\n bands: ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],\n min: 0,\n max: 0.7\n}, 'squared diff.');\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Load a VIIRS 8-day surface reflectance composite for September 2024.\nviirs202409 = (\n ee.ImageCollection('NASA/VIIRS/002/VNP09H1')\n .filter(ee.Filter.date('2024-09-01', '2024-09-16'))\n .first()\n)\n\n# Compute multi-band difference between the September composite and the\n# previously loaded May composite.\ndiff = viirs202409.subtract(ndvi202405)\n\nm = geemap.Map()\nm.add_layer(\n diff,\n {\n 'bands': ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],\n 'min': -1,\n 'max': 1,\n },\n 'difference',\n)\n\n# Compute the squared difference in each band.\nsquared_difference = diff.pow(2)\n\nm.add_layer(\n squared_difference,\n {\n 'bands': ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'],\n 'min': 0,\n 'max': 0.7,\n },\n 'squared diff.',\n)\ndisplay(m)\n```\n\nIn the second part of this example, the squared difference is computed using\n`image.pow(2)`. For the complete list of mathematical operators handling\nbasic arithmetic, trigonometry, exponentiation, rounding, casting, bitwise operations\nand more, see the [API documentation](/earth-engine/apidocs).\n\nExpressions\n-----------\n\nTo implement more complex mathematical expressions, consider using\n`image.expression()`, which parses a text representation of a math operation.\nThe following example uses `expression()` to compute the Enhanced\nVegetation Index (EVI):\n\n### Code Editor (JavaScript)\n\n```javascript\n// Load a Landsat 8 image.\nvar image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318');\n\n// Compute the EVI using an expression.\nvar evi = image.expression(\n '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {\n 'NIR': image.select('B5'),\n 'RED': image.select('B4'),\n 'BLUE': image.select('B2')\n});\n\nMap.centerObject(image, 9);\nMap.addLayer(evi, {min: -1, max: 1, palette: ['a6611a', 'f5f5f5', '4dac26']});\n```\nPython setup\n\nSee the [Python Environment](/earth-engine/guides/python_install) page for information on the Python API and using\n`geemap` for interactive development. \n\n```python\nimport ee\nimport geemap.core as geemap\n```\n\n### Colab (Python)\n\n```python\n# Load a Landsat 8 image.\nimage = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318')\n\n# Compute the EVI using an expression.\nevi = image.expression(\n '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))',\n {\n 'NIR': image.select('B5'),\n 'RED': image.select('B4'),\n 'BLUE': image.select('B2'),\n },\n)\n\n# Define a map centered on San Francisco Bay.\nmap_evi = geemap.Map(center=[37.4675, -122.1363], zoom=9)\n\n# Add the image layer to the map and display it.\nmap_evi.add_layer(\n evi, {'min': -1, 'max': 1, 'palette': ['a6611a', 'f5f5f5', '4dac26']}, 'evi'\n)\ndisplay(map_evi)\n```\n\nObserve that the first argument to `expression()` is the textual representation of\nthe math operation, the second argument is a dictionary where the keys are variable names used\nin the expression and the values are the image bands to which the variables should be\nmapped. Bands in the image may be referred to as `b(\"band name\")` or\n`b(index)`, for example `b(0)`, instead\nof providing the dictionary. Bands can be defined from images other than the input when using\nthe band map dictionary. Note that `expression()` uses \"floor division\", which\ndiscards the remainder and returns an integer when two integers are divided. For example\n`10 / 20 = 0`. To change this behavior, multiply one of the operands by\n`1.0`: `10 * 1.0 / 20 = 0.5`. Only the intersection of unmasked pixels\nare considered and returned as unmasked when bands from more than one source image are\nevaluated. Supported expression operators are listed in the following table.\n\n| Type | Symbol | Name |\n|----------------|---------------------|----------------------------------------------------|\n| **Arithmetic** | + - \\* / % \\*\\* | Add, Subtract, Multiply, Divide, Modulus, Exponent |\n| **Relational** | == != \\\u003c \\\u003e \\\u003c= \\\u003e= | Equal, Not Equal, Less Than, Greater than, etc. |\n| **Logical** | \\&\\& \\|\\| ! \\^ | And, Or, Not, Xor |\n| **Ternary** | ? : | If then else |\n[Operators for `expression()`]"]]