Band math#

Vegetation indices#

Enhanced Vegetation Index (EVI)#

In [1]: import geowombat as gw

In [2]: from geowombat.data import rgbn

Calculate a vegetation index, returning an xarray.DataArray.

In [3]: with gw.open(rgbn) as ds:
   ...:     print(ds)
   ...:     evi = ds.gw.evi(sensor='rgbn', scale_factor=0.0001)
   ...:     print(evi)
   ...: 
<xarray.DataArray (band: 4, y: 403, x: 515)> Size: 830kB
dask.array<open_rasterio-f76a38cf5a66a7e54eebac0d30c2d07f<this-array>, shape=(4, 403, 515), dtype=uint8, chunksize=(4, 64, 64), chunktype=numpy.ndarray>
Coordinates:
  * band     (band) int64 32B 1 2 3 4
  * x        (x) float64 4kB 7.93e+05 7.93e+05 7.93e+05 ... 7.956e+05 7.956e+05
  * y        (y) float64 3kB 2.05e+06 2.05e+06 2.05e+06 ... 2.048e+06 2.048e+06
Attributes: (12/14)
    transform:           (5.0, 0.0, 792988.0, 0.0, -5.0, 2050382.0)
    crs:                 32618
    res:                 (5.0, 5.0)
    is_tiled:            1
    nodatavals:          (nan, nan, nan, nan)
    _FillValue:          nan
    ...                  ...
    filename:            /home/docs/checkouts/readthedocs.org/user_builds/geo...
    resampling:          nearest
    AREA_OR_POINT:       Area
    DataType:            Generic
    _data_are_separate:  0
    _data_are_stacked:   0
<xarray.DataArray (band: 1, y: 403, x: 515)> Size: 2MB
dask.array<where, shape=(1, 403, 515), dtype=float64, chunksize=(1, 64, 64), chunktype=numpy.ndarray>
Coordinates:
  * x        (x) float64 4kB 7.93e+05 7.93e+05 7.93e+05 ... 7.956e+05 7.956e+05
  * y        (y) float64 3kB 2.05e+06 2.05e+06 2.05e+06 ... 2.048e+06 2.048e+06
  * band     (band) <U3 12B 'evi'
Attributes: (12/18)
    transform:           (5.0, 0.0, 792988.0, 0.0, -5.0, 2050382.0)
    crs:                 32618
    res:                 (5.0, 5.0)
    is_tiled:            1
    nodatavals:          (nan,)
    _FillValue:          nan
    ...                  ...
    _data_are_separate:  0
    _data_are_stacked:   0
    pre-scaling:         0.0001
    sensor:              rgbn
    vi:                  evi
    drange:              (0, 1)

Use the configuration context to set parameters.

In [4]: with gw.config.update(sensor='rgbn', scale_factor=0.0001):
   ...:     with gw.open(rgbn) as ds:
   ...:         evi = ds.gw.evi()
   ...:         print(evi)
   ...: 
<xarray.DataArray (band: 1, y: 403, x: 515)> Size: 2MB
dask.array<where, shape=(1, 403, 515), dtype=float64, chunksize=(1, 64, 64), chunktype=numpy.ndarray>
Coordinates:
  * x        (x) float64 4kB 7.93e+05 7.93e+05 7.93e+05 ... 7.956e+05 7.956e+05
  * y        (y) float64 3kB 2.05e+06 2.05e+06 2.05e+06 ... 2.048e+06 2.048e+06
  * band     (band) <U3 12B 'evi'
Attributes: (12/18)
    transform:           (5.0, 0.0, 792988.0, 0.0, -5.0, 2050382.0)
    crs:                 32618
    res:                 (5.0, 5.0)
    is_tiled:            1
    nodatavals:          (nan,)
    _FillValue:          nan
    ...                  ...
    DataType:            Generic
    _data_are_separate:  0
    _data_are_stacked:   0
    pre-scaling:         0.0001
    vi:                  evi
    drange:              (0, 1)

Two-band Enhanced Vegetation Index (EVI2)#

In [5]: with gw.config.update(sensor='rgbn', scale_factor=0.0001):
   ...:     with gw.open(rgbn) as ds:
   ...:         evi2 = ds.gw.evi2()
   ...:         print(evi2)
   ...: 
<xarray.DataArray (band: 1, y: 403, x: 515)> Size: 2MB
dask.array<where, shape=(1, 403, 515), dtype=float64, chunksize=(1, 64, 64), chunktype=numpy.ndarray>
Coordinates:
  * x        (x) float64 4kB 7.93e+05 7.93e+05 7.93e+05 ... 7.956e+05 7.956e+05
  * y        (y) float64 3kB 2.05e+06 2.05e+06 2.05e+06 ... 2.048e+06 2.048e+06
  * band     (band) <U4 16B 'evi2'
Attributes: (12/18)
    transform:           (5.0, 0.0, 792988.0, 0.0, -5.0, 2050382.0)
    crs:                 32618
    res:                 (5.0, 5.0)
    is_tiled:            1
    nodatavals:          (nan,)
    _FillValue:          nan
    ...                  ...
    DataType:            Generic
    _data_are_separate:  0
    _data_are_stacked:   0
    pre-scaling:         0.0001
    vi:                  evi2
    drange:              (0, 1)

Normalized difference indices#

Use the generic xarray.DataArray.gw.norm_diff() function with any two-band combination.

In [6]: with gw.config.update(sensor='rgbn'):
   ...:     with gw.open(rgbn) as ds:
   ...:         d = ds.gw.norm_diff('red', 'nir')
   ...:         print(d)
   ...: 
<xarray.DataArray (band: 1, y: 403, x: 515)> Size: 2MB
dask.array<where, shape=(1, 403, 515), dtype=float64, chunksize=(1, 64, 64), chunktype=numpy.ndarray>
Coordinates:
  * x        (x) float64 4kB 7.93e+05 7.93e+05 7.93e+05 ... 7.956e+05 7.956e+05
  * y        (y) float64 3kB 2.05e+06 2.05e+06 2.05e+06 ... 2.048e+06 2.048e+06
  * band     (band) <U9 36B 'norm-diff'
Attributes: (12/18)
    transform:           (5.0, 0.0, 792988.0, 0.0, -5.0, 2050382.0)
    crs:                 32618
    res:                 (5.0, 5.0)
    is_tiled:            1
    nodatavals:          (nan,)
    _FillValue:          nan
    ...                  ...
    DataType:            Generic
    _data_are_separate:  0
    _data_are_stacked:   0
    pre-scaling:         1.0
    vi:                  norm-diff
    drange:              (-1, 1)

Tasseled cap transformations#

In [7]: with gw.config.update(sensor='qb', scale_factor=0.0001):
   ...:     with gw.open(rgbn) as ds:
   ...:         tcap = ds.gw.tasseled_cap()
   ...:         print(tcap)
   ...: 
<xarray.DataArray (band: 3, y: 403, x: 515)> Size: 5MB
dask.array<transpose, shape=(3, 403, 515), dtype=float64, chunksize=(3, 64, 64), chunktype=numpy.ndarray>
Coordinates:
  * x        (x) float64 4kB 7.93e+05 7.93e+05 7.93e+05 ... 7.956e+05 7.956e+05
  * y        (y) float64 3kB 2.05e+06 2.05e+06 2.05e+06 ... 2.048e+06 2.048e+06
  * band     (band) <U10 120B 'brightness' 'greenness' 'wetness'
Attributes: (12/15)
    transform:           (5.0, 0.0, 792988.0, 0.0, -5.0, 2050382.0)
    crs:                 32618
    res:                 (5.0, 5.0)
    is_tiled:            1
    nodatavals:          (nan, nan, nan, nan)
    _FillValue:          nan
    ...                  ...
    filename:            /home/docs/checkouts/readthedocs.org/user_builds/geo...
    resampling:          nearest
    AREA_OR_POINT:       Area
    DataType:            Generic
    _data_are_separate:  0
    _data_are_stacked:   0

Additional useful indices are available, such as the normalized burned ratio (NBR) and woody index (WI). For a full list of indices, see the API docs