Skip to content

Repository files navigation

EchoStream-3D

EchoStream-3D is a research implementation of quality-aware incremental segmentation for volumetric ultrasound. It interprets a 3D volume as an ordered stream of 2D slices, combines a compact 2.5D U-Net with translation-based mask propagation and a small refinement network, estimates input quality and predictive uncertainty, and selects one of four actions for each slice: full, refine, reuse, or abstain. The repository is entirely local, supports CPU execution and optional CUDA or Apple MPS acceleration, and includes deterministic synthetic data for software validation when no real medical dataset is available.

Research demonstration only. EchoStream-3D is not a medical device, has not been clinically validated, and must not be used for diagnosis, treatment, triage, or patient-care decisions.

Research question

Can an ordered ultrasound slice stream avoid unnecessary full-model evaluations while retaining useful segmentation accuracy, temporal consistency, calibrated uncertainty, and an explicit ability to abstain on unreliable input?

Main contribution

The project provides a reproducible end-to-end test bed for that question rather than claiming a clinical result. Its central contribution is a transparent adaptive inference path that exposes every quality metric, registration result, threshold comparison, decision reason, and component latency. It evaluates this path against independent 2D, always-full 2.5D, and propagation/reuse baselines under clean and controlled corrupted streams. No performance values are hardcoded; all reported results are measured from the checkpoints and data supplied to an evaluation run.

System architecture

flowchart LR
    A["Volume stream"] --> B["Quality assessment"]
    B --> C["Registration and propagation"]
    C --> D["Adaptive controller"]
    D --> E["full"]
    D --> F["refine"]
    D --> G["reuse"]
    D --> H["abstain"]
    E --> I["Uncertainty"]
    F --> I
    G --> I
    H --> I
    I --> J["Reconstructed 3D output"]
    J --> K["Evaluation and dashboard"]
Loading

At slice z, the segmentation input is the edge-padded window [z-2, z-1, z, z+1, z+2]. When prior state exists, phase cross-correlation estimates inter-slice translation and propagates the previous probability map without wraparound. The controller then chooses:

  • full: execute the complete 2.5D model.
  • refine: correct the propagated probability with the lightweight refiner.
  • reuse: accept the valid propagated probability.
  • abstain: emit an invalid prediction, represented separately from a background mask.

See architecture.md and methodology.md for module contracts and evaluation details.

Why adaptive inference matters

Running a segmentation network on every slice establishes a clear accuracy and latency reference, but it may spend compute on temporally redundant frames. Blind reuse is unsafe when acquisition motion, acoustic shadow, dropout, or registration failure breaks continuity. EchoStream-3D studies the middle ground: reuse only after valid propagation, refine moderate changes, force periodic or uncertainty-triggered full inference, and abstain when inexpensive image-quality measurements indicate that the observed input is unreliable.

Interface screenshots

The screenshots below come from a completed local smoke stream using an actual trained checkpoint and procedurally generated data. They illustrate application behavior only and are not clinical-performance evidence.

EchoStream-3D playback and controller status

Observed slice, segmentation, probability, entropy, and propagation panels

Live latency, quality, uncertainty, and segmentation traces

Requirements and resource envelope

  • Python 3.11 or 3.12.
  • CPU-only operation; CUDA and Apple MPS are optional.
  • No cloud service, paid API, network connection, or ultrasound hardware is required.
  • Default development target: no more than 8 GiB RAM.
  • Generated project storage warning: 35 GiB, leaving margin below a 50 GB environment limit.
  • Projected preprocessing output warning: 20 GiB.
  • Default synthetic data remain far below 2 GB.

The exact runtime and storage footprint depend on case count, depth, checkpoint history, and evaluation settings. Use the resource audit before scaling an experiment.

Installation

Create and activate a virtual environment, then install the package in editable mode:

python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"

PyTorch is declared without a platform-specific wheel pin. If a particular CUDA build is needed, install the matching PyTorch wheel for the local driver before the editable install. The code never assumes that a GPU exists.

Quick start

The smoke profile uses four small 64 x 64 synthetic cases, batch size one, a base width of eight, and one training epoch.

python -m echostream.cli.make_demo_data --config configs/smoke.yaml --output data/raw
python -m echostream.cli.preprocess --config configs/smoke.yaml
python -m echostream.cli.train_segmentation --config configs/smoke.yaml --model unet25d --run-name unet25d_smoke
python -m echostream.cli.train_segmentation --config configs/smoke.yaml --model unet2d --run-name unet2d_smoke
python -m echostream.cli.train_refiner --config configs/smoke.yaml --run-name refiner_smoke

Training is intentionally excluded from continuous integration because even the smoke run is better treated as a local integration exercise.

Synthetic demonstration data

python -m echostream.cli.make_demo_data --config configs/demo.yaml --output data/raw

The deterministic generator uses NumPy and SciPy to create smooth anatomy-like backgrounds, irregular ellipsoids, correlated texture, multiplicative speckle, attenuation, gain variation, blur, shadows, dropout, and slight slice motion with matching binary masks. These volumes are demonstration and software-validation data only. They are not clinical images and cannot establish clinical performance.

Generation writes paired compressed NIfTI files and a finalized patient-level manifest. Existing case outputs are not overwritten silently.

Real NIfTI data

Place paired 3D volumes under one directory per case:

data/raw/
|-- case_0001/
|   |-- image.nii.gz
|   `-- label.nii.gz
`-- case_0002/
    |-- image.nii.gz
    `-- label.nii.gz

Then validate and split them:

python -m echostream.cli.create_manifest --config configs/demo.yaml --raw-dir data/raw

Alternatively provide a CSV with case_id,image_path,label_path,split; optional patient_id and slice_axis columns are supported. Empty splits are assigned deterministically at patient level, while explicit valid splits are preserved. See datasets.md before adapting any real dataset.

Preprocessing

python -m echostream.cli.preprocess --config configs/demo.yaml

Preprocessing operates one case at a time, replaces nonfinite image values, clips configurable percentiles, normalizes into [0, 1], resizes axial slices, preserves label values with nearest-neighbor interpolation, and writes one compressed data/processed/<case_id>.npz archive plus provenance metadata. It does not preload the dataset and reuses an unchanged processed case rather than making duplicates.

Segmentation training

Train the 2.5D model:

python -m echostream.cli.train_segmentation --config configs/demo.yaml --model unet25d --run-name unet25d_demo

Train the independent 2D baseline:

python -m echostream.cli.train_segmentation --config configs/demo.yaml --model unet2d --run-name unet2d_demo

Each run saves configuration, CSV history, best and last checkpoints, a JSON summary, and a bounded set of validation examples under artifacts/runs/<run_name>/. Resume with --resume <checkpoint>.

Refinement training

python -m echostream.cli.train_refiner --config configs/demo.yaml --run-name refiner_demo

The refiner learns to repair controlled mask perturbations derived from training masks. Its input is the current center image plus a propagated probability map; its target is the original center-slice mask.

Streaming demo

Run a clean stream:

python -m echostream.cli.run_stream --config configs/demo.yaml --case-id case_0001 --segmentation-checkpoint artifacts/runs/unet25d_demo/best.pt --refiner-checkpoint artifacts/runs/refiner_demo/best.pt --corruption-profile none

Run the deterministic mixed-corruption profile by changing the final argument to mixed. Session CSV, summary JSON, probability volume, predicted mask, validity mask, and decision timeline are written under artifacts/streams/<session_id>/. A missing refinement checkpoint disables refinement and safely falls back to full inference.

Evaluation and benchmarking

python -m echostream.cli.evaluate --config configs/demo.yaml --segmentation-checkpoint artifacts/runs/unet25d_demo/best.pt --baseline-checkpoint artifacts/runs/unet2d_demo/best.pt --refiner-checkpoint artifacts/runs/refiner_demo/best.pt --name demo_evaluation
python -m echostream.cli.benchmark --config configs/demo.yaml --segmentation-checkpoint artifacts/runs/unet25d_demo/best.pt --refiner-checkpoint artifacts/runs/refiner_demo/best.pt

Evaluation compares four named systems, computes segmentation, surface, temporal, reliability, latency, resource, robustness, bootstrap, and threshold-sweep outputs, and identifies Pareto-efficient settings programmatically. Missing checkpoints or data fail clearly; results are never substituted or invented.

Streamlit research interface

streamlit run app/streamlit_app.py

The dashboard provides slice playback, controller controls, corruption profiles, overlays, uncertainty and session charts, bounded 3D rendering, and local exports. Real inference requires a checkpoint. A deterministic mock mode exists solely for interface testing and is labelled on every relevant view and report. Synthetic cases also carry a visible demonstration-data label. See interface.md.

Resource audit

python -m echostream.cli.resource_audit --config configs/demo.yaml --memory-warning-mb 7168
# installed entry point:
echostream-resource-audit --config configs/demo.yaml

The JSON report includes raw, processed, artifact, checkpoint, estimated preprocessing, process-memory, and checkpoint model-state parameter measurements. It warns above 35 GiB total generated storage, 500 MiB per checkpoint, 20 GiB projected preprocessing output, and the configured peak-memory threshold. On platforms that do not expose a process peak through psutil, the current resident set is reported as the conservative available process measurement.

Docker

The CPU image excludes raw data and generated artifacts. Mount them at runtime:

docker build -t echostream-3d:cpu .
docker run --rm -p 8501:8501 -v "$(pwd)/data:/workspace/data" -v "$(pwd)/artifacts:/workspace/artifacts" echostream-3d:cpu

On Windows PowerShell, replace $(pwd) with ${PWD}. Open http://localhost:8501. The container runs as a non-root user and publishes a Streamlit health check.

Repository structure

echostream-3d/
|-- app/                         # Streamlit entry point
|-- configs/                     # smoke, demo, and research YAML profiles
|-- data/                        # mounted or local raw, processed, manifest data
|-- artifacts/                   # generated runs, streams, evaluations, test temp data
|-- docs/                        # architecture, datasets, method, interface, model card
|-- src/echostream/
|   |-- app/                     # browser-independent dashboard/session helpers
|   |-- cli/                     # command entry points
|   |-- data/                    # generation, validation, splitting, preprocessing, windows
|   |-- evaluation/              # metrics, systems, robustness, sweeps, figures
|   |-- models/                  # segmentation, refinement, inference APIs
|   |-- quality/                 # deterministic quality, corruption, uncertainty
|   |-- streaming/               # simulation, propagation, controller, engine, sessions
|   `-- training/                # losses, loops, checkpoints, visualizations
|-- tests/                       # deterministic CPU/offline test suite
|-- Dockerfile
`-- pyproject.toml

Reproducibility and quality checks

All configurable random behavior derives from the YAML seed. seed_everything covers Python, NumPy, PyTorch CPU/accelerators, deterministic algorithm settings, and DataLoader workers; saved checkpoints retain the seed and configuration. Case assignment is patient-level and deterministic. Corruption schedules and mock mode are seeded independently from session state.

Run the release checks from the repository root:

ruff check .
mypy src/echostream
pytest -q

Tests require neither a GPU nor network access. Mypy runs in strict mode over project source. Its only import-following exclusions are the untyped or partially typed third-party namespaces scipy, skimage, nibabel, plotly, streamlit, and the transitive tifffile; project modules remain fully checked.

Limitations

  • A stored 3D volume is only a proxy for a live ordered acquisition; future context in a centered 2.5D window may not exist in a truly causal scanner feed.
  • Phase correlation models translation, not nonrigid tissue deformation, probe rotation, or out-of-plane motion.
  • Rule-based quality and controller thresholds require external validation and may transfer poorly across scanners, anatomy, operators, and acquisition protocols.
  • Synthetic appearance and corruption models are deliberately lightweight and cannot reproduce the distribution or failure modes of clinical ultrasound.
  • Binary segmentation is the tested path; multiclass losses and model outputs are supported, but streaming policies need task-specific validation.
  • CPU latency is machine-dependent, and Python simulation timing is not scanner integration timing.
  • Abstention identifies a system reliability condition; it is not a clinical recommendation.

Ethics, privacy, and clinical disclaimer

Do not commit identifiable patient data, protected health information, private dataset credentials, or license-restricted volumes. De-identification, governance review, legal basis, secure access, retention policy, and compliance with the source dataset's terms remain the user's responsibility. EchoStream-3D outputs must be reviewed only within appropriately approved research protocols. The software provides no diagnosis, prognosis, treatment guidance, or assurance of safety or efficacy.

Citation

There is no associated peer-reviewed performance claim in this repository. Until a versioned archival release is available, cite the exact repository version or commit used. Suggested software-citation metadata:

@software{echostream3d_2026,
  title  = {EchoStream-3D: Quality-Aware Incremental Analysis of Volumetric Ultrasound},
  author = {{EchoStream-3D Contributors}},
  year   = {2026},
  note   = {Research software; cite the exact version or commit used}
}

License

The source code is available under the MIT License. Dataset files, pretrained weights, and third-party adaptations are not relicensed by this repository; their original licenses and terms continue to apply.

About

Quality-aware adaptive streaming segmentation for volumetric ultrasound research

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages