Fahimeh Orvati Nia
update
c170961
raw
history blame
2.66 kB
"""
Minimal vegetation index extraction (NDVI, ARI, GNDVI only).
"""
import numpy as np
from typing import Dict, Any
import logging
logger = logging.getLogger(__name__)
class VegetationIndexExtractor:
"""Minimal vegetation index extraction."""
def __init__(self, epsilon: float = 1e-10, soil_factor: float = 0.5):
"""Initialize with defaults."""
self.epsilon = epsilon
self.soil_factor = soil_factor
self.index_formulas = {
"NDVI": lambda nir, red: (nir - red) / (nir + red + self.epsilon),
"GNDVI": lambda nir, green: (nir - green) / (nir + green + self.epsilon),
"SAVI": lambda nir, red: ((nir - red) / (nir + red + self.soil_factor)) * (1.0 + self.soil_factor),
}
self.index_bands = {
"NDVI": ["nir", "red"],
"GNDVI": ["nir", "green"],
"SAVI": ["nir", "red"],
}
def compute_vegetation_indices(self, spectral_stack: Dict[str, np.ndarray],
mask: np.ndarray) -> Dict[str, Dict[str, Any]]:
"""Compute NDVI, ARI, and GNDVI."""
indices = {}
for index_name, formula in self.index_formulas.items():
try:
required_bands = self.index_bands[index_name]
if not all(band in spectral_stack for band in required_bands):
continue
band_data = []
for band in required_bands:
arr = spectral_stack[band]
if isinstance(arr, np.ndarray):
arr = arr.squeeze(-1)
band_data.append(np.asarray(arr, dtype=np.float64))
index_values = formula(*band_data).astype(np.float64)
binary_mask = (np.asarray(mask).astype(np.int32) > 0)
masked_values = np.where(binary_mask, index_values, np.nan)
valid_values = masked_values[~np.isnan(masked_values)]
if len(valid_values) > 0:
stats = {
'mean': float(np.mean(valid_values)),
'std': float(np.std(valid_values)),
}
else:
stats = {'mean': 0.0, 'std': 0.0}
indices[index_name] = {
'values': masked_values,
'statistics': stats
}
except Exception as e:
logger.error(f"Failed to compute {index_name}: {e}")
return indices