A Python project for calculating multispectral vegetation indices from multi-band TIFF files and extracting zonal statistics from polygon shapefiles using memory-efficient processing.
- Calculate multiple vegetation indices from 8-band multispectral imagery
- Support for RGB, Green, Red, RedEdge, and NIR bands
- Memory-efficient processing using rasterstats and chunked processing
- Zonal statistics extraction for polygon features
- Export results to Excel format
- Individual index maps saved as GeoTIFF for visualization
The project calculates the following vegetation indices:
- NDVI (Normalized Difference Vegetation Index): (NIR - Red) / (NIR + Red)
- NDRE (Normalized Difference Red Edge): (NIR - RedEdge) / (NIR + RedEdge)
- GNDVI (Green Normalized Difference Vegetation Index): (NIR - Green) / (NIR + Green)
- SAVI (Soil Adjusted Vegetation Index): 1.5 * (NIR - Red) / (NIR + Red + 0.5)
- EVI (Enhanced Vegetation Index): 2.5 * (NIR - Red) / (NIR + 6 * Red - 7.5 * Blue + 1)
- MSAVI (Modified Soil Adjusted Vegetation Index): (2 * NIR + 1 - sqrt((2 * NIR + 1)^2 - 8 * (NIR - Red))) / 2
- OSAVI (Optimized Soil Adjusted Vegetation Index): (NIR - Red) / (NIR + Red + 0.16)
- MCARI (Modified Chlorophyll Absorption Ratio Index): ((RedEdge - Red) - 0.2 * (RedEdge - Green)) * (RedEdge / Red)
- TCARI (Transformed Chlorophyll Absorption Ratio Index): 3 * ((RedEdge - Red) - 0.2 * (RedEdge - Green) * (RedEdge / Red))
- CIgreen (Chlorophyll Index Green): (NIR / Green) - 1
- CIrededge (Chlorophyll Index Red Edge): (NIR / RedEdge) - 1
Multispectral_Index/
├── README.md
├── requirements.txt
├── setup.py
├── .gitignore
├── main_rasterstats.py # Main processing script (memory-efficient)
├── generate_index_files.py # Generate individual index TIFF files
├── test_installation.py # Installation test script
├── data/
│ ├── 4165_C_SAGIT25_1.tif # Multispectral TIFF files
│ ├── 4165_C_SAGIT25_2.tif
│ └── TrialDesign.shp # Polygon shapefile (+ associated files)
├── src/
│ ├── __init__.py
│ ├── config.py # Configuration settings
│ ├── multispectral_indices.py # Index calculation functions
│ ├── rasterstats_indices.py # Memory-efficient index processing
│ ├── zonal_stats.py # Zonal statistics extraction
│ └── utils.py # Utility functions
└── outputs/
├── indices/ # Individual index TIFF files
│ ├── 4165_C_SAGIT25_1_NDVI.tif
│ ├── 4165_C_SAGIT25_1_NDRE.tif
│ └── ... (all calculated indices)
└── results.xlsx # Final Excel results
- Clone the repository:
git clone https://github.com/yourusername/Multispectral_Index.git
cd Multispectral_Index- Create and activate a Python virtual environment:
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Test the installation:
python test_installation.pyRun the main script to process all TIFF files and calculate indices:
PYTHONPATH=src python main_rasterstats.pyThis script will:
- Process each TIFF file in the data directory
- Calculate all supported vegetation indices using chunked processing
- Extract zonal statistics for each polygon in the shapefile using rasterstats
- Save results to
outputs/results.xlsx
To create individual TIFF files for each index (useful for visualization):
PYTHONPATH=src python generate_index_files.pyThis will save all index maps as separate GeoTIFF files in outputs/indices/.
The project assumes the following band order in the 8-band TIFF files:
- Blue (Band 1)
- Green (Band 2)
- Red (Band 3)
- Green (Band 4) - not used
- Red (Band 5) - not used
- RedEdge (Band 6)
- NIR (Band 7)
- Additional (Band 8) - not used
This implementation uses several techniques to handle large TIFF files efficiently:
- Chunked Processing: Processes images in 2048x2048 pixel chunks
- Rasterstats Integration: Uses rasterstats for direct polygon-based processing
- Temporary Files: Creates temporary index files only when needed
- Memory Monitoring: Tracks memory usage throughout processing
The Excel output (results.xlsx) contains two sheets:
tif_file: Name of the source TIFF fileindex_name: Name of the calculated indexThesis: From shapefile polygon attributesBlock: From shapefile polygon attributesPlot: From shapefile polygon attributesmean_value: Mean index value within the polygon
- Summary statistics (count, mean, std, min, max) for each index by file
- Python 3.7+
- rasterio
- geopandas
- numpy
- pandas
- openpyxl
- rasterstats
- psutil
Successfully tested with:
- 2 TIFF files (3.3GB and 3.8GB each)
- 8 bands per file (21,400 x 15,274 and 20,424 x 14,772 pixels)
- 20 polygons in shapefile
- 11 vegetation indices
- Total processing time: ~10-15 minutes
- Memory usage: Stays under 30% during processing
MIT License