Spectral Indices

Let’s see how to compute built-in spectral indices with eemont!

Before anything, let’s import our modules and authenticate in Google Earth Engine:

import ee, eemont

ee.Authenticate()
ee.Initialize()

Now, we are ready to go!

Overview

The eemont package extends the ee.Image and ee.ImageCollection classes with the method index():

ee.Image

index(self[, index, G, C1, C2, L])

Computes one or more spectral indices (indices are added as bands) for an image.

ee.ImageCollection

index(self[, index, G, C1, C2, L])

Computes one or more spectral indices (indices are added as bands) for an image collection.

List of Indices

Vegetation Indices

The following table shows the list of built-in vegetation indices:

Built-in vegetation indices.

Index

Description

Reference

BNDVI

Blue Normalized Difference Vegetation Index

Index DataBase BNDVI

CIG

Chlorophyll Index - Green

Index DataBase CIG

CVI

Chlorophyll Vegetation Index

Index DataBase CVI

EVI

Enhanced Vegetation Index

Index DataBase EVI

EVI2

Two-Band Enhanced Vegetation Index

(Jiang et al., 2008)

GBNDVI

Green-Blue Normalized Difference Vegetation Index

Index DataBase GBNDVI

GNDVI

Green Normalized Difference Vegetation Index

Index DataBase GNDVI

GRNDVI

Green-Red Normalized Difference Vegetation Index

Index DataBase GRNDVI

MNDVI

Modified Normalized Difference Vegetation Index

Index DataBase MNDVI

NDVI

Normalized Difference Vegetation Index

Index DataBase NDVI

NGRDI

Normalized Green Red Difference Index

Index DataBase NGRDI

RVI

Ratio Vegetation Index

Index DataBase RVI

SAVI

Soil-Adjusted Vegetation Index

Index DataBase SAVI

Burn Indices

The following table shows the list of built-in burn indices:

Built-in burn indices.

Index

Description

Reference

BAI

Burned Area Index

(Martín, 1998) [spanish]

BAIS2

Burned Area Index for Sentinel 2

(Filipponi, 2018)

CSIT

Char Soil Index Thermal

(Smith et al., 2007)

NBR

Normalized Burn Ratio

Index DataBase NBR

NBRT

Normalized Burn Ratio Thermal

(Holden et al., 2005)

NDVIT

Normalized Difference Vegetation Index Thermal

(Smith et al., 2007)

SAVIT

Soil-Adjusted Vegetation Index Thermal

(Smith et al., 2007)

Water Indices

The following table shows the list of built-in water indices:

Built-in water indices.

Index

Description

Reference

MNDWI

Modified Normalized Difference Water Index

(Xu, 2006)

NDWI

Normalized Difference Water Index

(McFeeters, 1996)

Snow Indices

The following table shows the list of built-in snow indices:

Built-in snow indices.

Index

Description

Reference

NDSI

Normalized Difference Snow Index

(Riggs et al., 1994)

List of Bands

The following table shows the list of bands used for spectral indices computation:

Bands used for spectral indices computation.

Description

Name

Sentinel-2

Landsat 8

Landsat 4, 5, 7

MODIS

Aerosols

A

B1

B1

Blue

B

B2

B2

B1

B3

Green

G

B3

B3

B2

B4

Red

R

B4

B4

B3

B1

Red Edge 1

RE1

B5

Red Edge 2

RE2

B6

Red Edge 3

RE3

B7

Red Edge 4

RE4

B8A

NIR

N

B8

B5

B4

B2

SWIR 1

S1

B11

B6

B5

B6

SWIR 2

S2

B12

B7

B7

B7

Thermal 1

T1

B10

B6

Thermal 2

T2

B11

Warning

If the satellite platform doesn’t have the required bands for computing an index, it won’t be computed.

Usage

The index() method computes the specified spectral index and adds it as a new band.

Let’s take the Sentinel-2 SR image collection as example (remember to scale your image or image collection!):

S2 = ee.ImageCollection('COPERNICUS/S2_SR').scale()

By default, the index() method computes the NDVI:

S2withIndices = S2.index()
S2withIndices.select('NDVI')

If required, any of the above-mentioned indices can be computed by modifying the index parameter:

S2withIndices = S2.index(index = 'EVI')
S2withIndices.select('EVI')

Specific index-parameters can be changed, for example, the canopy background adjustment L is set to 1.0 for EVI, but for SAVI it can be changed to 0.5:

S2withIndices = S2.index('SAVI',L = 0.5)
S2withIndices.select('SAVI')

If more than one index is required, a list of indices can be used:

S2withIndices = S2.index(['CIG','NBR','NDWI'])
S2withIndices.select('CIG')
S2withIndices.select('NBR')
S2withIndices.select('NDWI')

Indices can also be computed for single images:

S2withIndices = S2.first().index(['GBNDVI','MNDVI','EVI'])
S2withIndices.select('GBNDVI')
S2withIndices.select('MNDVI')
S2withIndices.select('EVI')

All vegetation indices can be computed by setting index = vegetation:

S2withIndices = S2.index('vegetation')
S2withIndices.select('NDVI')
S2withIndices.select('GNDVI')
S2withIndices.select('RVI')
# ...

All burn indices can be computed by setting index = burn:

S2withIndices = S2.index('burn')
S2withIndices.select('BAI')
S2withIndices.select('BAIS2')
S2withIndices.select('NBR')

All water indices can be computed by setting index = water:

S2withIndices = S2.index('water')
S2withIndices.select('NDWI')
S2withIndices.select('MNDWI')

All snow indices can be computed by setting index = snow:

S2withIndices = S2.index('snow')
S2withIndices.select('NDSI')

If you want to compute all available indices, you can set index = all:

S2withIndices = S2.index('all')
S2withIndices.select('NDVI')
S2withIndices.select('BAI')
S2withIndices.select('NDWI')
S2withIndices.select('NDSI')
# ...

Contribute

Do you know a spectral index that would fit in here? Check this, I’ll show you how to add it to eemont!

First, fork the eemont repository and clone it to your local machine. Then, create a development branch:

git checkout -b name-of-dev-branch

Now, you’ll have to look for the common.py module (eemont > eemont > common.py). Open this module and look for the _get_indices() method. Inside this method, you’ll find 4 dictionaries: vegetationIndices, burnIndices, waterIndices, and snowIndices. Go for the dictionary that best fits your spectral index and create a new item (this new item will be the new spectral index). Indices in each dictionary are structured as follows:

vegetationIndices = {
    ...,
    'NGRDI' : {
         'formula' : '(G - R) / (G + R)',
         'description' : 'Normalized Green Red Difference Index',
         'type' : 'vegetation',
         'requires' : ['G','R'],
         'reference' : 'https://www.indexdatabase.de/db/i-single.php?id=390',
         'contributor' : 'davemlz'
     },
     ...
}

Now, let’s image you are going to create a new index. Each index is a dictionary with the following items:

  • Key of dictionary: This is the official index name, make sure the index doesn’t exist yet.

  • formula (string): Spectral index expression. This is the formula that eemont will use to compute the index. Follow the names described in the List of Bands table.

  • description (string): Full name of the spectral index.

  • type (string): One of ‘vegetation’, ‘burn’, ‘water’, ‘snow’.

  • requires (list[string]): List of bands required to compute the spectral index. Follow the names described in the List of Bands table.

  • reference (string): Link to the DOI of the spectral index paper or to the Index Database Link. Include the full link.

  • contributor (string | list[string]): Your GitHub username, and, if you want, your Twitter username (If using both, please create a list with both usernames [‘gh_username’,’t_username’]).

Important

Make sure you have all the items. Spectral indices with missing elements WON’T be accepted.

After you have your own index, add it to the dictionary that best fits. It should look like this:

vegetationIndices = {
    ...,
    'your_index_name' : {
         'formula' : 'expression_formula_of_your_index',
         'description' : 'full_name_of_your_index',
         'type' : 'vegetation',
         'requires' : ['band1_used','band2_used',...], # e.g. ['N','R']
         'reference' : 'link_to_index_reference',
         'contributor' : 'your_gh_username'
     },
}

Now it’s time to test your index! Go to the tests folder (eemont > tests) and run the following lines:

cd tests
python test_image.py
python test_imagecollection.py

The tests will start running for ee.Image and ee.ImageCollection classes. At the end, no ERRORS should appear and the final message should be OK. If any deprecation warning appears, please ignore it, I’ll look into it later.

Now it’s time to commit your changes and push your development branch:

git add .
git commit -m "Description of your work"
git push origin name-of-dev-branch

And finally, submit a pull request (and don’t forget to add the tests!).