Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rust-dicom-station"
version = "0.5.0"
version = "0.6.0"
edition = "2021"
description = "Fast, robust DICOM / RT DICOM viewer in pure Rust (CT/MR volumes, RTSTRUCT, RTDOSE, RTPLAN) with a three-view MPR layout"
license = "MIT"
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ three-view layout, with a second dataset row for comparison, built-in
**image registration** (elastix- and plastimatch-style, rigid, deformable
and landmark-based, with analytics and a deformation vector field),
**structure propagation**, **DRR generation**, **interactive
segmentation**, a live **3D structure view**, **automatic multi-organ
segmentation**, a live **3D structure view**, **automatic body / EXTERNAL
contouring** (the patient outline without the couch, the chair or the
immobilisation, on CT and MR), **automatic multi-organ
segmentation** (a pure-Rust re-implementation of TotalSegmentator, 117
structures, CPU or any GPU), **prompt-driven segmentation** (a
pure-Rust re-implementation of SegVol — point at anything with a box, a
Expand Down Expand Up @@ -78,6 +80,17 @@ holds the registration controls and both dataset trees.*
view, mask → RTSTRUCT conversion, and **DICOM SEG** import and export
(binary and fractional multi-frame masks, read onto their own lattice
and resampled onto whichever image series they belong to).
* **Body contouring** - the EXTERNAL structure, found automatically and
without the couch, the chair or the immobilisation inside it. Equipment
is separated from anatomy by two facts no patient has together: it is
thin, and its footprint repeats slice after slice - so an 8 mm opening
and a persistence test along **all three** axes catch a supine couch top
and an upright chair's seat pan alike, while ears, nose and fingers are
given back afterwards. Works on CT by Hounsfield threshold and on MR
after flattening the coil shading; optionally guided by
TotalSegmentator's openly licensed body network, which is what removes a
mask touching the skin with no gap. Lands as an editable mask and as an
RTSTRUCT `EXTERNAL`.
* **Auto-segmentation** - TotalSegmentator v2 inference rebuilt natively:
official nnU-Net weights downloaded once and converted
without Python, hand-written SIMD CPU engine and a wgpu GPU path
Expand Down Expand Up @@ -169,6 +182,7 @@ ships a real two-phase 4DCT (see
| [docs/propagation.md](docs/propagation.md) | Carrying contours and segmentations across a registration |
| [docs/drr.md](docs/drr.md) | Digitally reconstructed radiographs: the two projectors and the geometry |
| [docs/segmentation.md](docs/segmentation.md) | Brush / eraser / region growing, 3D view, mask → RTSTRUCT |
| [docs/body-contour.md](docs/body-contour.md) | The body / EXTERNAL contour: the classical and model-assisted methods, CT and MR, verification |
| [docs/segvol.md](docs/segvol.md) | Prompt-driven segmentation: box / point / text, the SegVol re-implementation |
| [docs/medsam2.md](docs/medsam2.md) | Propagating a prompt through a stack: the MedSAM2 re-implementation |
| [docs/auto-segmentation.md](docs/auto-segmentation.md) | The pure-Rust TotalSegmentator: models, pipeline, engines, validation, classes, licensing |
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ covers one area in depth.
| [rt-objects.md](rt-objects.md) | RT DICOM objects: RTSTRUCT, RTDOSE, RTPLAN, REG spatial registrations, RT treatment records, and how their reference chains are resolved |
| [registration.md](registration.md) | Rigid and deformable (B-spline) image registration: algorithms, parameters, the fusion overlay, the transform simulator for registration QA, accuracy verification |
| [segmentation.md](segmentation.md) | Interactive segmentation: 2D/3D brush, eraser, geodesic region growing, the live 3D structure view, mask → RTSTRUCT conversion |
| [body-contour.md](body-contour.md) | Automatic body / EXTERNAL contouring: why the couch, the chair and the mask are the hard part, the classical threshold-and-morphology method, the model-assisted method built on TotalSegmentator's body network, CT and MR, verification |
| [auto-segmentation.md](auto-segmentation.md) | Automatic multi-organ segmentation — the pure-Rust TotalSegmentator re-implementation: models, usage, the inference pipeline, CPU/GPU engines, validation, the full 117-class table, licensing |
| [segvol.md](segvol.md) | Prompt-driven segmentation — the pure-Rust SegVol re-implementation: box / point / text prompts, the two-pass pipeline, weights and licensing, validation status |
| [export-and-tools.md](export-and-tools.md) | DICOM export, the interactive anonymizer, the synthetic test-data generator |
Expand Down
48 changes: 36 additions & 12 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ rust-dicom-station
│ active registration; the recovered field written back out as one
├── Segmentation
│ ├── Body / EXTERNAL contour: thresholding by modality (HU, or MR after bias
│ │ flattening), spacing-aware opening, extruded-equipment removal along all
│ │ three axes, component selection by volume, thin-anatomy recovery,
│ │ slice-wise filling — classically, or guided by TotalSegmentator's body
│ │ network (CT 6 / 1.5 mm, MR)
│ ├── Voxel masks: brush / eraser (2D, 3D), geodesic region growing, undo,
│ │ slice overlays, hole filling, mask ▶ RTSTRUCT contours, RTSTRUCT ▶ mask,
│ │ grouped into segmentation series that live in the study and bind to an
Expand Down Expand Up @@ -182,7 +187,8 @@ src/
plumbing (Job::spawn, poll_job, poll_tool_job), per-frame driver
theme.rs theme-dependent colors
chrome.rs menu bar, toolbar, status bar, help
panels.rs side panel and its per-dataset sections
panels.rs left panel: its show / hide, the optional modules and
the per-dataset Data tree sections
views.rs central MPR viewports, interaction, texture caches
d3.rs live 3D structure window
planar.rs floating DX / CR / RTIMAGE viewers
Expand All @@ -197,14 +203,16 @@ src/
auto-segmentation job starts
dialogs.rs auto-segmentation window + results, generator, anonymizer,
export, error dialog
reg_panel.rs the Registration section: method, region, parameters,
reg_panel.rs the Image registration section: method, region, parameters,
landmarks, the run, the analytics, the vector field
models_win.rs the model manager window
propagate_win.rs structure propagation window and worker
drr_win.rs the DRR window: geometry, projectors, comparison
seg.rs interactive segmentation state machine, mask ▶ RTSTRUCT,
landing an auto-segmentation result
seg_engines.rs what the three engine windows share: names and glyphs,
body_win.rs the body-contour window: method choice, the modality's
own threshold row, the classical / model-assisted split
seg_engines.rs what the four tool windows share: names and glyphs,
device / model-folder / licence / progress rows,
result landing, the "still the same dataset" check
prompt_seg.rs prompt segmentation window and worker (SegVol)
Expand Down Expand Up @@ -248,6 +256,15 @@ src/
segmentation.rs voxel masks: brush, geodesic grow, undo, overlays,
label map ▶ segmentations, mask ▶ RTSTRUCT contours and
RTSTRUCT contours ▶ mask Seg
morphology.rs binary-mask geometry, in millimetres: the exact
anisotropic Euclidean distance transform and the
erode / dilate / open / close it powers, 6-connected
components, slice-wise and 3-D hole filling, the
extruded-equipment test, box-blur smoothing Core
bodymask.rs the body / EXTERNAL contour: foreground by modality (HU,
or bias-flattened MR), equipment removal, component
selection, thin-anatomy recovery, filling — classically
or guided by the body network Seg
mesh3d.rs contour / mask ▶ surface meshes (scanline fill,
surface nets, Laplacian smoothing) Seg

Expand All @@ -261,12 +278,15 @@ src/
params.rs shape-checked view of a loaded state dict
half.rs binary16 ↔ binary32 conversion
tensor.rs Mat [rows, cols] and Act [c, d, h, w]; transposed conv
(a hand-tuned 2× and a general kernel = stride form)
linalg.rs gemm-backed linear / matmul, layer norm, softmax,
GELU / ReLU / QuickGELU
attention.rs multi-head attention, optionally causally masked

autoseg/ automatic segmentation (pure-Rust TotalSegmentator) Seg
mod.rs public API: variants, run(), progress phases
mod.rs public API: variants, run(), run_specs() (the engine
minus the question, shared with the body contour),
progress phases
classes.rs 117-class table, sub-model maps, organ colors
config.rs nnU-Net plans.json parsing
weights.rs which models exist, where they are published, the
Expand Down Expand Up @@ -354,14 +374,15 @@ those: a ROI visibility toggle, for instance, is part of the contour key
alone and leaves the dose and fusion textures untouched. Repaints are
demand-driven; while background jobs run, the UI polls at 10 Hz.

### The three engine windows
### The segmentation tool windows

Auto-segmentation, prompt segmentation and slice propagation are different
conversations — a batch run with a result-selection dialog, a one-shot
prompt, an interactive box loop — but they are the same kind of tool, and
`app/seg_engines.rs` makes them look and behave alike:
Body contouring, auto-segmentation, prompt segmentation and slice
propagation are different conversations — a parameterised geometric run, a
batch run with a result-selection dialog, a one-shot prompt, an interactive
box loop — but they are the same kind of tool, and `app/seg_engines.rs`
makes them look and behave alike:

* one `ToolInfo` per engine gives the glyph (🤖 🧠 ⏩), the window title
* one `ToolInfo` per tool gives the glyph (👤 🤖 🧠 ⏩), the window title
(`🤖 Auto-segmentation — dataset A`, the same pattern as
`3D structures — dataset A`), the menu entry (`🤖 Auto-segment dataset A…`)
and the small sidebar button (`🤖 Auto…`);
Expand All @@ -374,8 +395,11 @@ prompt, an interactive box loop — but they are the same kind of tool, and
engine, the tool's own inputs, `Name`, a collapsed **Options** header
holding the engine's settings plus the shared `Compute: Auto / GPU / CPU`
and `Model folder` rows, one small licence line ("… Research / QA use —
not a medical device."), then `▶ Segment` / `▶ Propagate` and `Close`,
and a status line summarising the last result;
not a medical device."), then `▶ Segment` / `▶ Propagate` / `▶ Contour`
and `Close`, and a status line summarising the last result;
* what a tool does not have, it does not show: the body contour's classical
method needs no device, no model and no download, so those rows appear
only when its method is the model-assisted one;
* results land the same way — `add_segmentation` with the next palette
colour — and a run that finishes after the dataset was replaced is
discarded with the same message.
Expand Down
Loading