Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Contrail Segmentation Demo

ML-based contrail detection and segmentation on sky-camera imagery — a runnable, end-to-end reference app (React → Node BFF → FastAPI → PyTorch U-Net) built as a job-application demo for the EUROCONTROL Contrail Avoidance (COAV) programme.

flowchart LR
    U[Browser] -->|HTTP /api| FE[React + Vite frontend<br/>nginx :8080]
    FE -->|/api proxy| BFF[Node.js + Express BFF<br/>:3000]
    BFF -->|REST + multipart| ML[Python FastAPI<br/>:8000]
    ML -->|forward pass| NN[PyTorch U-Net<br/>128x128 semantic segmentation]
    NN -->|mask + stats| ML
    ML -->|overlay PNG + coverage% + count| BFF
    BFF --> FE
Loading

Pick a sample sky image (or upload your own); the app returns the original image with the predicted contrail mask overlaid, the contrail coverage % of the sky, and the number of distinct contrails detected (connected components).


What this proves

A single coherent project that exercises the full stack named in the JD:

JD requirement Where it lives
React frontend frontend/ — React 18 + Vite + TypeScript, sample gallery, upload, overlay rendering
Node.js bff/ — Express Backend-for-Frontend fronting the ML service
Python / FastAPI / NumPy ml-service/ — FastAPI app, NumPy synthetic-data pipeline
PyTorch + neural-network image segmentation ml-service/ml_service/model.py — hand-written U-Net, BCE+Dice training
Docker per-service Dockerfile + docker-compose.yml (3 services, healthchecks)
CI/CD .github/workflows/ci.yml — pytest + ruff, bff tests, frontend build (matrix)
Technical documentation this README + docs/ARCHITECTURE.md + docs/DECISIONS.md

Domain context — COAV

Aircraft condensation trails (contrails) that persist and spread into cirrus cloud trap outgoing longwave radiation and are a significant share of aviation's non-CO₂ climate impact. EUROCONTROL / MUAC have been pioneering operational contrail avoidance — small, targeted altitude adjustments on the subset of flights crossing ice-supersaturated regions where persistent contrails form. Reliable detection of contrails from ground sky-cameras (and satellites) is a building block for validating and closing the loop on such measures.


Demo-grade model — honest scope

This model is trained on synthetic data generated procedurally on the fly (blue→white gradient skies + smoothed-noise clouds + thin anti-aliased bright streaks with matching masks). The synthetic task is deliberately easy, so the U-Net reaches high validation IoU/Dice in ~1–2 minutes of CPU training. The point is a clean, runnable end-to-end system, not production accuracy.

These are not production metrics and the model has not seen real sky-camera imagery. A high synthetic IoU says the plumbing, training loop, loss, metrics, and inference path are correct — nothing about real-world contrail detection performance.

How I'd scale this to production

  • Real data: train/fine-tune on GVCCS and real Sky Cam Vision / Sky InSight ground-camera imagery; weak-label bootstrap from satellite-detected contrail flags, then human-in-the-loop correction.
  • Cross-sensor: correlate ground-camera detections with satellite contrail products and flight trajectories (ADS-B) for spatio-temporal validation.
  • Better task framing: move from semantic to instance segmentation + tracking (per-contrail across a camera sequence), which is what GVCCS targets.
  • Stronger models: larger encoders (e.g. pretrained backbones), test-time augmentation, calibrated thresholds per sky condition; quantify uncertainty.
  • MLOps: experiment tracking + model registry with MLflow / Databricks, reproducible data versioning, scheduled retraining, drift monitoring.
  • Serving: containerised inference deployed on OpenShift (EUROCONTROL's platform), autoscaled, with the BFF/API gateway pattern shown here unchanged.

Quick start

Option A — Docker (one command)

docker compose up --build
# open http://localhost:8080

Frontend (nginx :8080) proxies /api to the BFF (:3000), which forwards to the FastAPI ML service (:8000). Compose waits on healthchecks between tiers.

Option B — local dev (no Docker)

make install        # python venv + npm installs for all three services
make train          # (optional) retrain the U-Net; a checkpoint is committed
make test           # pytest (ml) + node tests (bff) + frontend build
make dev            # prints the 3 commands to run each service in its own terminal

make dev runs:

# terminal 1 — ML service
cd ml-service && .venv/bin/uvicorn app:app --port 8000
# terminal 2 — BFF
cd bff && MLSERVICE_URL=http://localhost:8000 npm start
# terminal 3 — frontend (open http://localhost:5173)
cd frontend && npm run dev

The trained checkpoint ml-service/ml_service/checkpoints/unet.pt is committed, so the app works without running make train first.


API (ML service)

Method Path Description
GET /health liveness + whether the checkpoint loaded
GET /samples list of sample sky image ids
GET /samples/{id} a sample sky PNG
POST /segment multipart image upload → JSON: base64 overlay PNG, coverage_pct, contrail_count

The BFF mirrors these under /api/*.


Screenshots

Screenshots placeholder — run docker compose up --build and open http://localhost:8080, then pick a sample sky or upload one to see the original image, the contrail overlay, and the coverage/count stats.


Repo layout

ml-service/   FastAPI + PyTorch U-Net (model, synthetic data, train, inference, tests)
bff/          Node.js + Express BFF (forwards to the ML service)
frontend/     React + Vite + TS (gallery, upload, overlay UI; nginx Dockerfile)
docs/         ARCHITECTURE.md, DECISIONS.md
.github/      CI workflow

About

Neural-network contrail image segmentation — React + Node BFF + FastAPI + PyTorch U-Net. Built as a demo for a EUROCONTROL Contrail Avoidance (COAV) application.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages