Use this Skill for agricultural remote sensing: Sentinel-2 crop type mapping (Random Forest), NDVI phenology analysis, LAI estimation, and yield prediction from satellite composites.
Instrucciones de origen · Vista previa de solo lectura
name
agri-remote-sensing
description
Use this Skill for agricultural remote sensing: Sentinel-2 crop type mapping (Random Forest), NDVI phenology analysis, LAI estimation, and yield prediction from satellite composites.
TL;DR — Map crop types with Sentinel-2 + Random Forest, extract NDVI
phenology metrics (SOS/EOS/peak), estimate LAI, and predict yield from
satellite composites using Google Earth Engine and Python.
When to Use
Use this Skill when you need to:
Map crop types across a study region using multi-temporal Sentinel-2
spectral composites and machine-learning classification.
Derive phenological metrics (start-of-season, end-of-season, peak NDVI)
from dense NDVI time series to characterize crop calendars.
Estimate leaf area index (LAI) from empirical regression models calibrated
with Sentinel-2 bands.
Predict crop yield at field or county level using phenology features derived
from satellite imagery.
Build cloud-free seasonal composites (biweekly or monthly median) at scale.
Do NOT use this Skill for individual-plant-level phenotyping (UAV/drone),
or when ground-truth training data are unavailable.
Example 1 — NDVI Time Series and Phenology for Iowa Corn Belt
defexample_iowa_corn_ndvi():
"""Build NDVI time series for a corn field in Iowa and extract phenology."""# Define a small ROI (1 km²) in central Iowa
roi = ee.Geometry.Rectangle([-93.62, 41.98, -93.61, 41.99])
print("Fetching biweekly NDVI composites for 2022 corn season ...")
df = get_biweekly_ndvi_series(roi, "2022-04-01", "2022-11-30", cloud_pct=40)
print(f" Got {len(df)} composites with valid NDVI.")
# Extract phenology
metrics = extract_phenology_metrics(df["NDVI"], pd.DatetimeIndex(df["date"]))
print("\nPhenology metrics:")
for k, v in metrics.items():
print(f" {k}: {v}")
# Plot NDVI time series with phenology markers
fig, ax = plt.subplots(figsize=(11, 4))
ax.plot(df["date"], df["NDVI"], "o-", color="#2ca02c", label="NDVI (biweekly)")
ax.axvline(metrics["SOS"], color="blue", linestyle="--", label=f"SOS ({metrics['SOS'].date()})")
ax.axvline(metrics["EOS"], color="red", linestyle="--", label=f"EOS ({metrics['EOS'].date()})")
ax.axvline(metrics["peak_date"], color="orange", linestyle=":", label=f"Peak NDVI={metrics['peak_NDVI']:.2f}")
ax.set_ylabel("NDVI")
ax.set_title("Iowa Corn NDVI Time Series — 2022")
ax.legend()
ax.grid(alpha=0.3)
plt.tight_layout()
plt.savefig("iowa_corn_ndvi.png", dpi=150)
return df, metrics
Example 2 — Crop Type Classification with Accuracy Assessment
defexample_crop_classification():
"""
Simulate Random Forest crop classification from synthetic spectral data.
In practice, replace synthetic data with real GEE-extracted pixel values.
"""import numpy as np
rng = np.random.default_rng(42)
class_names = ["corn", "soybean", "wheat", "fallow"]
n_samples_per_class = 200
n_features = 16# 8 biweekly NDVI + 4 EVI + 4 LSWI# Simulate separable spectral signatures
means = {
"corn": rng.uniform(0.4, 0.8, n_features),
"soybean": rng.uniform(0.3, 0.7, n_features),
"wheat": rng.uniform(0.2, 0.6, n_features),
"fallow": rng.uniform(0.1, 0.3, n_features),
}
features_list, labels_list = [], []
for label, (cls, mean_vec) inenumerate(means.items()):
feat = rng.normal(mean_vec, 0.05, (n_samples_per_class, n_features))
features_list.append(feat)
labels_list.extend([label] * n_samples_per_class)
features = np.vstack(features_list)
labels = np.array(labels_list)
result = train_crop_classifier(features, labels, class_names)
print(f"\nOverall Accuracy: {result['OA']:.4f}")
# Feature importance plot
fi = result["feature_importances"].head(8)
fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(fi["feature"], fi["importance"], color="#1f77b4")
ax.set_xlabel("Feature Importance")
ax.set_title("Top 8 Features — Crop Type RF Classifier")
plt.tight_layout()
plt.savefig("feature_importance.png", dpi=150)
return result
if __name__ == "__main__":
example_crop_classification()
Example 3 — Yield Prediction from Phenology Features
defexample_yield_prediction():
"""Predict county-level corn yield from simulated phenology features."""import numpy as np
rng = np.random.default_rng(7)
n = 300# number of fields
peak_ndvi = rng.uniform(0.55, 0.90, n)
sos_doy = rng.integers(100, 140, n).astype(float)
los_days = rng.integers(120, 180, n).astype(float)
amplitude = rng.uniform(0.30, 0.60, n)
# Synthetic yield: positively correlated with peak NDVI and LOS
yield_kgha = 6000 + 4000 * peak_ndvi + 10 * los_days - 8 * sos_doy + rng.normal(0, 300, n)
feat_df = pd.DataFrame({
"peak_NDVI": peak_ndvi,
"SOS_doy": sos_doy,
"LOS_days": los_days,
"amplitude": amplitude,
})
result = yield_prediction_from_phenology(feat_df, pd.Series(yield_kgha))
print(f"\nYield model coefficients: {result['coefficients']}")
return result
if __name__ == "__main__":
example_yield_prediction()