Awesome Spectral Indices in Python - comprehensive library for computing spectral indices from remote sensing data
Interactive access to the complete spectral indices catalogue from the Awesome Spectral Indices project. Provides over 200 standardized spectral indices with comprehensive metadata, formulas, band requirements, and platform compatibility information.
The global spyndex.indices object provides access to all available spectral indices with interactive exploration and computation capabilities.
class SpectralIndices(Box):
"""
Container for all spectral indices in the Awesome Spectral Indices catalogue.
Provides dictionary-like access to individual SpectralIndex objects.
"""
def __repr__(self) -> str:
"""Machine readable representation showing available index names."""
def __str__(self) -> str:
"""Human readable list of index names."""Usage Examples:
import spyndex
# Access the global catalogue
print(spyndex.indices)
# Output: SpectralIndices(['AFRI1600', 'AFRI2100', 'ARI', ..., 'kNDVI', 'kRVI', 'kVARI'])
# Get list of all index names
index_names = list(spyndex.indices.keys())
print(f"Total indices available: {len(index_names)}")
# Access specific indices
ndvi = spyndex.indices.NDVI
savi = spyndex.indices.SAVI
evi = spyndex.indices.EVIEach spectral index in the catalogue is represented as a SpectralIndex object containing complete metadata and computation capabilities.
class SpectralIndex:
"""
Individual spectral index with metadata and computation capability.
"""
short_name: str # Index abbreviation (e.g., "NDVI")
long_name: str # Full descriptive name
bands: tuple # Required bands/parameters as tuple
application_domain: str # Domain: 'vegetation', 'burn', 'water', 'urban', 'kernel', 'radar'
reference: str # URL to reference/DOI
formula: str # Mathematical formula as expression
date_of_addition: str # Date added to catalogue
contributor: str # GitHub contributor URL
platforms: list # Compatible satellite platforms
def compute(self, params=None, **kwargs) -> Any:
"""
Compute this spectral index with provided parameters.
Parameters:
- params: Dictionary of parameters/bands for computation
- **kwargs: Alternative parameter specification
Returns:
Computed spectral index value (type depends on input)
"""
def __repr__(self) -> str:
"""Detailed machine readable representation with metadata."""
def __str__(self) -> str:
"""Human readable summary with key information."""Usage Examples:
import spyndex
# Access individual index
ndvi = spyndex.indices.NDVI
# Explore metadata
print(ndvi.long_name) # "Normalized Difference Vegetation Index"
print(ndvi.formula) # "((N-R)/(N+R))"
print(ndvi.bands) # ('N', 'R')
print(ndvi.application_domain) # "vegetation"
print(ndvi.reference) # "https://doi.org/10.1016/0034-4257(79)90013-0"
print(ndvi.platforms) # ['Landsat-4', 'Landsat-5', 'Landsat-7', ...]
# Compute using the index object
result = ndvi.compute(params={"N": 0.67, "R": 0.12})
print(result) # 0.6971830985915493
# Alternative parameter specification
result = ndvi.compute(N=0.67, R=0.12)
print(result) # 0.6971830985915493
# Detailed information display
print(ndvi)
# Output:
# SpectralIndex(NDVI: Normalized Difference Vegetation Index)
# * Application Domain: vegetation
# * Bands/Parameters: ('N', 'R')
# * Formula: ((N-R)/(N+R))
# * Reference: https://doi.org/10.1016/0034-4257(79)90013-0Indices are categorized by application domain for easier discovery and selection:
import spyndex
# Find indices by application domain
vegetation_indices = [
name for name, idx in spyndex.indices.items()
if idx.application_domain == 'vegetation'
]
print(f"Vegetation indices: {len(vegetation_indices)}")
water_indices = [
name for name, idx in spyndex.indices.items()
if idx.application_domain == 'water'
]
print(f"Water indices: {len(water_indices)}")
burn_indices = [
name for name, idx in spyndex.indices.items()
if idx.application_domain == 'burn'
]
print(f"Burn indices: {len(burn_indices)}")
# Find indices requiring specific bands
ndvi_like = [
name for name, idx in spyndex.indices.items()
if set(idx.bands) == {'N', 'R'}
]
print(f"Indices using only NIR and Red: {ndvi_like}")
# Find indices by platform compatibility
sentinel2_compatible = [
name for name, idx in spyndex.indices.items()
if 'Sentinel-2A' in idx.platforms or 'Sentinel-2B' in idx.platforms
]
print(f"Sentinel-2 compatible indices: {len(sentinel2_compatible)}")Understanding band and parameter requirements across the catalogue:
import spyndex
from collections import Counter
# Analyze band usage frequency
all_bands = []
for idx in spyndex.indices.values():
all_bands.extend(idx.bands)
band_frequency = Counter(all_bands)
print("Most common bands:")
for band, count in band_frequency.most_common(10):
print(f"{band}: {count} indices")
# Find indices with complex requirements
complex_indices = [
(name, idx.bands) for name, idx in spyndex.indices.items()
if len(idx.bands) > 5
]
print("Indices with >5 parameters:")
for name, bands in complex_indices:
print(f"{name}: {bands}")
# Find kernel-based indices
kernel_indices = [
name for name, idx in spyndex.indices.items()
if idx.application_domain == 'kernel'
]
print(f"Kernel-based indices: {kernel_indices}")The catalogue spans multiple remote sensing application areas:
Each index includes comprehensive metadata:
Individual index objects provide direct computation without needing to call computeIndex:
import spyndex
import numpy as np
# Direct computation on index objects
ndvi_idx = spyndex.indices.NDVI
savi_idx = spyndex.indices.SAVI
# Single values
ndvi_val = ndvi_idx.compute(N=0.67, R=0.12)
savi_val = savi_idx.compute(N=0.67, R=0.12, L=0.5)
# Arrays
nir = np.random.normal(0.67, 0.12, 1000)
red = np.random.normal(0.12, 0.05, 1000)
ndvi_array = ndvi_idx.compute(N=nir, R=red)
savi_array = savi_idx.compute(N=nir, R=red, L=0.5)This approach provides object-oriented access to individual indices while maintaining the same data type compatibility as the main computeIndex function.
Install with Tessl CLI
npx tessl i tessl/pypi-spyndex