NDVI Crop Stress Detection Across Agricultural Regions

Detect crop stress and irrigation deficits before yield loss occurs. Klarety agents compute normalized difference vegetation index from Sentinel-2 10-meter bands, threshold anomaly zones against seasonal baselines, and generate field-level risk maps. Farmers and agronomists receive stress alerts every 5 days — no GIS skills, no satellite expertise.

Crop stress detection for agronomists and traders

Klarety AI
Klarety AI chat composer interface

Field-level stress maps from one satellite query

Klarety agents compute NDVI anomaly zones from Sentinel-2 10m bands and return field-level risk maps every 5 days.

NDVI - Sentinel-2
Klarety satellite analysis output

Seasonal baseline anomaly thresholding

Agents compute NDVI deviations against seasonal baselines and classify stress severity by zone with confidence scores.

GIS Output
Klarety AI map annotation overlay

Stress layers for precision agriculture GIS

Export stress zone polygons with severity classifications for farm management systems and GEE workflow integration.

Sentinel-2 NDVI anomaly detection for crop stress

Klarety agents compute a 5-year seasonal NDVI baseline from Sentinel-2 for each field polygon, then flag current NDVI values more than 1.5 standard deviations below the baseline as stress zones. Severity is classified as mild (1.5-2 SD), moderate (2-3 SD), or severe (>3 SD). Output is a field-level GeoJSON with stress severity, confidence, and affected area per field.

Klarety AIMonitor crop stress in your region
analysis/ndvi_crop_stress_monitor.pyAgent code
python
import eeimport numpy as np
ee.Initialize()
# Central Valley California AOIaoi = ee.Geometry.Rectangle([-120.8, 36.4, -119.8, 37.2])
# 5-year NDVI baseline (same DOY window)def ndvi_baseline(year):    return (ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')            .filterBounds(aoi)            .filterDate(f'{year}-04-01', f'{year}-04-30')            .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))            .map(lambda img: img.normalizedDifference(['B8','B4']).rename('ndvi'))            .mean())
baseline_years = [2020, 2021, 2022, 2023, 2024]baseline_stack = ee.ImageCollection([ndvi_baseline(y) for y in baseline_years])ndvi_mean = baseline_stack.mean().rename('ndvi_mean')ndvi_std  = baseline_stack.reduce(ee.Reducer.stdDev()).rename('ndvi_std')
# Current NDVI (April 2026)current = (ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')           .filterBounds(aoi)           .filterDate('2026-04-01', '2026-04-30')           .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))           .map(lambda img: img.normalizedDifference(['B8','B4']).rename('ndvi'))           .mean())
# Z-score anomalyz_score = ndvi_mean.subtract(current).divide(ndvi_std.add(0.001)).rename('z_score')
# Stress classificationmild_stress   = z_score.gte(1.5).And(z_score.lt(2.0))mod_stress    = z_score.gte(2.0).And(z_score.lt(3.0))severe_stress = z_score.gte(3.0)
def area_ha(mask):    a = mask.multiply(ee.Image.pixelArea()).reduceRegion(        ee.Reducer.sum(), aoi, 10, maxPixels=1e9    ).values().get(0).getInfo()    return round((a or 0) / 10000, 1)
print(f"Mild stress (1.5-2.0 SD):  {area_ha(mild_stress):>8.0f} ha")print(f"Moderate stress (2-3 SD):  {area_ha(mod_stress):>8.0f} ha")print(f"Severe stress (>3 SD):     {area_ha(severe_stress):>8.0f} ha")
output/crop_stress_report.mdOutput report
python
# NDVI Crop Stress Report**AOI:** Central Valley, California (-120.8 to -119.8°W, 36.4 to 37.2°N)**Period:** April 2026 vs 5-year baseline | **Source:** Sentinel-2 SR 10m
## Stress Classification Summary| Severity     | Z-Score Range | Area (ha) | % of AOI | Action          ||--------------|---------------|-----------|----------|-----------------|| Mild         | 1.5 - 2.0     | 18,420    | 12.3%    | Monitor weekly  || Moderate     | 2.0 - 3.0     | 9,810     | 6.6%     | Inspect fields  || Severe       | >3.0          | 3,240     | 2.2%     | Urgent action   || **Total stressed** |          | **31,470**| **21.1%**|                 |
## Hotspot Locations- Fresno County NE quadrant: 4,100 ha severe — possible irrigation failure- Kings County W corridor: 2,800 ha moderate — drought stress signature- Tulare Basin S: 1,200 ha severe — consistent with fallowed fields
## Commodity Impact Estimate- Stressed area in active crop production: ~18,500 ha- Crops at risk: almonds, grapes, cotton (dominant in stressed zones)- Indicative yield impact: -8 to -15% if stress persists through May
## Methods5-year Sentinel-2 SR NDVI baseline (2020-2024), April composite.Z-score = (baseline_mean - current) / baseline_std. Confidence: High.

Try Klarety now.