β Data Sorcerers Β· Computer Vision Β· Remote Sensing Β· 2025
PLANT HEALTH
CLASSIFICATION
Automated detection of vegetation health conditions using
DJI multispectral drone imagery β
CNN trained on NDVI, GNDVI & NDRE indices
to classify plants as Healthy, Mildly Damaged, or Severely Damaged.
DJI MULTISPECTRAL Β· ACTIVE
CNN Β· Deep Learning
NDVI Β· GNDVI Β· NDRE
Multispectral Imaging
Patch Classification
TensorFlow Β· Rasterio
DJI P4 Multispectral
marchel@sys:~$
cat ./sensor/spectral_bands.json
530β570nm
Green Β· MS_G
Chlorophyll content, canopy reflectance, GNDVI numerator
650β690nm
Red Β· MS_R
Chlorophyll absorption, NDVI denominator, stress detection
705β745nm
Red Edge Β· MS_RE
Early stress signal, NDRE β most sensitive to plant health change
820β860nm
NIR Β· MS_NIR
High in healthy vegetation, NDVI numerator, biomass estimation
marchel@sys:~$
python calc_indices.py
--ndvi --gndvi --ndre --rvi
VEGETATION INDICES β FORMULAS & THRESHOLDS
Index Formulas
NDVI = (NIR β Red) / (NIR + Red)
GNDVI = (NIR β Green) / (NIR + Green)
NDRE = (NIR β RedEdge) / (NIR + RedEdge)
RVI = NIR / Red
Classification Thresholds (Weighted Score)
NDVI
<0.2
0.2β0.4
>0.4 Healthy
GNDVI
<0.15
0.15β0.3
>0.3 Healthy
NDRE
<0.1
0.1β0.2
>0.2 Healthy
Weighted score = NDVIΓ0.5 + GNDVIΓ0.3 + NDREΓ0.2
β₯ 1.5 β Healthy Β· β₯ 0.7 β Mild Damage Β· < 0.7 β Severe Damage
SAMPLE DRONE IMAGE β DJI_0001 Β· MAY 31 2025
RGB β True Color
NIR Band β False Color
Low NIR β Damage
Mid NIR β Mild
High NIR β Healthy
β Sandy/brown patches = bare soil, severe damage zones (NDVI ~0.08)
β Brownish-green areas = mild stress (NDVI ~0.27 β 0.28)
β Right section = denser canopy, higher NIR reflectance
β 768Γ1024px Β· uint16 Β· DJI_202505311450_003_Create-Area-Route1
marchel@sys:~$
ls ./classes/
--verbose --metrics
β
Class 2 β Healthy
Strong NIR reflectance, high chlorophyll content. NDVI > 0.4, GNDVI > 0.3, NDRE > 0.2. Dense canopy, active photosynthesis.
Precision: 52.17%
Recall: 100.0%
F1-Score: 68.57%
β
Class 1 β Mild Damage
Moderate stress indicators. NDVI 0.2β0.4, GNDVI 0.15β0.3. Early chlorosis, some wilting, possible pest presence.
Precision: 94.1%
Recall: 92.6%
F1-Score: 93.3%
β
Class 0 β Severe Damage
Low vegetation response. NDVI < 0.2, GNDVI < 0.15. Dead tissue, severe disease, drought stress, or bare soil.
Precision: 91.2%
Recall: 90.5%
F1-Score: 90.8%
marchel@sys:~$
python build_model.py
--summary --input 64x64x4
CNN ARCHITECTURE β 64Γ64Γ4 INPUT
Input
64 Γ 64 Γ 4 (MS Bands)
4ch
βΌ
Conv2D
32 filters Β· 3Γ3 Β· ReLU + BN + MaxPool + Dropout(0.25)
62Γ62Γ32
βΌ
Conv2D
64 filters Β· 3Γ3 Β· ReLU + BN + MaxPool + Dropout(0.25)
14Γ14Γ64
βΌ
Conv2D
128 filters Β· 3Γ3 Β· ReLU + BN + MaxPool + Dropout(0.25)
5Γ5Γ128
βΌ
Dense
Flatten β 256 Β· ReLU + BN + Dropout(0.5)
256
βΌ
Output
3 classes Β· Softmax
3
β Optimizer: Adam (lr=0.001) Β· Loss: Sparse Categorical Crossentropy
β Callbacks: EarlyStopping (patience=15) Β· ReduceLROnPlateau Β· ModelCheckpoint
β Batch size: 32 Β· Val split: 20% Β· Stratified split Β· 50 epochs max
PROJECT:Plant Health Classification
DRONE:DJI P4 Multispectral
FLIGHT DATE:May 31, 2025
LOCATION:Create-Area-Route1
BANDS:G Β· R Β· RE Β· NIR (4-band MS)
PATCH SIZE:64 Γ 64 pixels
MAX PATCHES:150 per image
TARGET/CLASS:300 samples
FRAMEWORK:TensorFlow 2.x Β· Rasterio
MODEL FILE:vegetation_health_model.h5
DATASET:Google Drive Β· pengenalan_tanaman_dji
π‘Drone
Flight
βΆ
πTIF
Bands
βΆ
β±Patch
Extract
βΆ
βIndex
Calc
βΆ
βCNN
Train
βΆ
πΏHealth
Map
marchel@sys:~$
python eval.py
--report --plots --50epochs
TRAINING HISTORY β ACCURACY & LOSS (50 EPOCHS) β ACTUAL NOTEBOOK OUTPUT
β Overfitting detected β Train acc 97.37% vs Val acc 52.17%.
High val loss (6.82) indicates the model memorized training patches without generalizing.
Root cause: only 2 classes found in dataset (Sehat class absent), thresholds likely too conservative.
CONFUSION MATRIX β TEST SET (115 SAMPLES) β ACTUAL OUTPUT
All 115 predictions collapsed to Rusak Berat β
60/60 correct for that class, 0/55 for Rusak Ringan.
Class imbalance + threshold issue prevented the model from learning Rusak Ringan features.
DETECTION EXAMPLES PER CLASS β ACTUAL OUTPUT
Rusak Berat: NDVIβ0.078 Β·
Rusak Ringan: NDVIβ0.274 Β·
Sehat: 0 samples found β
dataset contains no patches exceeding NDVI threshold 0.4.
SINGLE PATCH MULTI-BAND VISUALIZATION β ACTUAL NOTEBOOK OUTPUT
One 64Γ64 patch visualized across all 4 spectral bands (MS_G, MS_R, MS_RE, MS_NIR),
computed vegetation indices (NDVI, GNDVI, NDRE, RVI), and false-color composites.
From image DJI_20250531151141_0001 β
NDVI range β0.467 to +0.690.
marchel@sys:~$
python report.py
--classification-report --percentages
DETAILED CLASSIFICATION REPORT
FINAL EPOCH METRICS (EPOCH 50)
Train Accuracy:97.37%
Val Accuracy:52.17%
Train Loss:0.1024
Val Loss:6.8209
F1 Macro:34.29%
F1 Weighted:35.78%
Dataset:(571, 64, 64, 4) Β· 35.7 MB
Test set:115 samples (80/20 split)
β Overfitting + Class Collapse β model predicts only Rusak Berat.
β Root cause: Sehat class absent from dataset (NDVI max 0.69 but threshold weighted scoring yields no class-2).
β Fix: lower thresholds, add data augmentation, use class weights in loss.
marchel@sys:~$
ls ./resources/
--links --dataset