Skip to content

Repository files navigation

Stenoz — coronary artery stenosis detection in X-ray angiography

CI

Detects whether a coronary angiography image shows a vessel stenosis (narrowing) and where it is. Two-stage system:

  1. AI detector (primary) — a U-Net trained on the ARCADE stenosis split; detects stenosis directly (heatmap + confidence). Held-out test: image-level sensitivity 95.7%, F1 0.645.
  2. Geometric explanation — vessel U-Net segmentation (test Dice 0.702) → centerline (skeleton) → diameter profile → narrowing percentage. Interpretable: an auditable diameter chart for every detection.

Methodology and full results are written up in the paper: report/Stenoz_Ilmiy_Maqola.pdf (.docx).

Direct stenosis detector output

Why two stages

Nearly 100% of images in ARCADE's stenosis split have at least one annotated lesion — there is effectively no negative (healthy) class at the image level. A plain image-level binary classifier has no contrast to learn from. The project is instead framed as localization: first an interpretable geometric estimator (validated with a synthetic-injection protocol), then a U-Net trained directly on stenosis annotations — the latter provides the main result, the former explains its output. Full discussion and experiments are in the paper.

Results

Model File Test result
Stenosis detector (primary) models/unet_stenosis.pt F1 0.645 · recall 95.7% · image-level sensitivity 95.7%
Vessel segmentation (for explanation) models/unet_vessel.pt Dice 0.702

Both trained from scratch on a Kaggle GPU (NVIDIA Tesla T4) — base architecture in src/unet.py (base=32, 4-stage encoder–decoder).

Install and run

Requires Python 3.12+ (scipy==1.18.0 needs it).

git clone https://github.com/uzbtrust/stenoz.git
cd stenoz
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python scripts/download_models.py   # fetches trained weights from Hugging Face
streamlit run app.py                # http://localhost:8501

The app also works without the model weights — the sidebar then falls back to the classical (Frangi) segmentation method automatically.

GUI

  • X-ray — samples — picks a random image from samples/ (🎲 Random sample); the AI detector finds the stenosis, the green box is the cardiologist-annotated ground truth.
  • MRI — upload image — upload your own image; the geometric method is used (the AI models were trained on X-ray only — see Limitations below).
  • Both modes show a "Geometric explanation" panel with the vessel skeleton and diameter profile.

Dataset

ARCADE (MICCAI 2023) — 1,500 X-ray coronary angiograms with COCO-format polygon annotations (syntax: vessel segmentation, stenosis: lesion localization). Not included in this repo due to size (~475MB) — download it from the link above and place it as dataset/data/{syntax,stenosis}/... (only needed for retraining or evaluation scripts; not required to run app.py, since samples/ already ships example images).

Retraining

kaggle kernels push -p kaggle_train      --accelerator NvidiaTeslaT4   # vessel U-Net
kaggle kernels push -p kaggle_stenosis   --accelerator NvidiaTeslaT4   # stenosis detector

Both kernels live in kaggle_train/train_kernel.py and kaggle_stenosis/train_stenosis_kernel.py — 60 epochs, AdamW + cosine LR schedule, mixed precision (fp16).

Evaluation

python src/eval_stenosis_dl.py --split val --n 100        # AI detector
python src/eval_synthetic.py   --split val --n 200        # geometric, controlled (synthetic injection)
python src/eval_real.py        --split val --n 100 [--dl] # geometric, on real images

Full methodology and results tables: report/HISOBOT.md.

Project layout

app.py                       Streamlit GUI
src/dlstenosis.py            AI stenosis detector (inference)
src/dlseg.py                 vessel U-Net segmentation (inference)
src/unet.py                  U-Net architecture (must match the Kaggle kernels exactly)
src/pipeline.py               geometric detector (centerline + diameter profile)
src/segment.py                Frangi auto-segmentation (fallback when no weights are present)
src/synth.py                  synthetic stenosis generator (for controlled validation)
src/dataio.py                 ARCADE (COCO) loading
src/eval_*.py                 evaluation scripts
src/train_unet.py             local training script
scripts/download_models.py    fetches weights from Hugging Face
kaggle_train/                 vessel U-Net Kaggle kernel
kaggle_stenosis/              stenosis detector Kaggle kernel
models/                       metrics (weights on HF, see above)
samples/                      10 example images + ground-truth annotations
report/                       paper (PDF/DOCX), figures, generation scripts

Limitations

  • Modality: all training/evaluation data is X-ray coronary angiography (XCA). Not validated on MRI/MRA — the geometric method is modality-agnostic given a correct vessel mask, but both trained U-Nets are fit to X-ray contrast statistics.
  • Precision: at the default operating point, roughly half of detected lesions don't overlap a ground-truth annotation (recall is deliberately prioritized — pos_weight=10).
  • This project was built for research/demonstration purposes and is not validated, certified, or intended for clinical diagnosis.

Full analysis: paper, sections 6 and 7.

License

Code — MIT. The ARCADE dataset is distributed under its own original license (see the link above); this license does not apply to it.

About

Koronar arteriya stenozini rentgen angiografiyada aniqlash — geometrik profillash + U-Net detektor (ARCADE, MICCAI 2023)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages