Skip to content
Open
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
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,43 @@ size, emptiness; exactly 24 components), the collapsed L1 is restored from
23.3 to 62.9 cm3 at detected disc planes, and every spinous process is
re-attached to its own vertebra on the fused case.

# Iterative Vertebrae Engine (ShapeKit-Iterative)

In addition to the default and Pro vertebrae engines, ShapeKit now offers a
**VerSe-inspired iterative refinement** module that runs an anatomic
consistency cycle on the predicted vertebrae masks alone (no CT required):

- **residual reassignment** — recovers unassigned spine voxels and
reassigns them to the nearest vertebra by 3D centroid distance;
- **gap detection & filling** — detects anomalously large Z-axis gaps
between consecutive vertebrae and assigns residual components to the
missing level;
- **fishing for boundary vertebrae** — extrapolates beyond the detected
inferior/superior boundaries to recover L5 or C1 when missing;
- **duplicate removal** — merges overlapping detections via IoU thresholding;
- **anatomical size consistency** — validates vertebrae sizes against
region-group medians (lumbar > thoracic > cervical) and removes outliers;
- **iterative convergence** — repeats the full clean → reassign → fill →
reallocate loop until the change rate drops below 1% or max iterations
(3) are reached.

This module is adapted from Meng et al., "Vertebrae localization,
segmentation and identification using a graph optimization and an
anatomic consistency cycle" (2022,
[https://gitlab.inria.fr/spine/vertebrae_segmentation](https://gitlab.inria.fr/spine/vertebrae_segmentation)).

Enable it in `config.yaml`:

```yaml
vertebrae_engine: shapekit_iterative # default: shapekit (existing module)
```

No CT image is needed — the module works from prediction masks alone.
Output is compatible with the existing 26-based label scheme
(26 = L5 … 49 = C1). Verified to produce identical results to the
SuPreM standalone postprocessing pipeline on the AbdomenAtlasDemo
benchmark cases.

# Key Functions
In addition to these general utilities, anatomical-structures-specific correction functions are available in [organs_postprocessing.py](organs_postprocessing.py).

Expand Down
5 changes: 3 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ affine_reference_file_name: liver.nii.gz
if_save_combined_label: True

# vertebrae engine:
# shapekit - default mask-based module (no CT needed)
# shapekit_pro - evidence-gated repair against the case CT: recolors
# shapekit - default mask-based module (no CT needed)
# shapekit_iterative - VerSe-inspired iterative refinement loop (no CT needed)
# shapekit_pro - evidence-gated repair against the case CT: recolors
# label errors inside the prediction envelope instead of
# deleting bone; every risky stage self-reverts unless it
# can prove improvement. Needs the case CT (see below);
Expand Down
7 changes: 7 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from multiprocessing import cpu_count
from utils.organs_postprocessing import *
from utils.vertebrae_postprocessing import postprocessing_vertebrae
from utils.vertebrae_iterative import postprocessing_vertebrae as postprocessing_vertebrae_iterative
from utils.vertebrae_pro import postprocessing_vertebrae_pro
import logging
import yaml
Expand Down Expand Up @@ -203,6 +204,12 @@ def process_organs(segmentation_dict: dict, reference_img, combined_seg: np.arra
ct_path,
logger=logger,
)
elif vertebrae_engine == 'shapekit_iterative':
segmentation_dict = postprocessing_vertebrae_iterative(
patient_id,
segmentation_dict,
logger=logger,
)
else:
segmentation_dict = postprocessing_vertebrae(
patient_id,
Expand Down
Loading