Segmentation Developer Guide
Segmentation classes convert CT images into anatomy-group masks used by workflows.
Current Segmentation Contract
import itk
from physiomotion4d import SegmentChestTotalSegmentator
image = itk.imread("chest_ct.nrrd")
segmenter = SegmentChestTotalSegmentator()
masks = segmenter.segment(image, contrast_enhanced_study=True)
labelmap = masks["labelmap"]
if "heart" in masks:
heart = masks["heart"]
Segmentation outputs are dictionaries of ITK images. Access masks by key,
not by positional unpacking. The exact key set depends on the segmenter’s
physiomotion4d.AnatomyTaxonomy — see Segmentation Base Class
for the per-segmenter key sets and the general contract.
Implemented Segmenters
Adding a New Segmenter
A new segmenter subclass declares which anatomy groups and organ labels it
produces by populating self.taxonomy. The base class owns the
AnatomyTaxonomy instance and contributes two default placeholders
(contrast at id 135, soft_tissue at id 133).
import logging
from physiomotion4d import SegmentAnatomyBase
class SegmentMySite(SegmentAnatomyBase):
def __init__(self, log_level=logging.INFO):
super().__init__(log_level=log_level)
self.target_spacing = 1.5
# Register organ labels under group names. New group names
# can be introduced freely; downstream renderers fall back
# to render_params["other"] for unregistered groups.
for group_name, organs in (
("heart", {51: "heart", 61: "atrial_appendage_left"}),
("lung", {10: "lung_upper_lobe_left"}),
):
for label_id, organ_name in organs.items():
self.taxonomy.add_organ(group_name, label_id, organ_name)
# Fill in 'other' for any unclaimed ids in the [1, 256) range.
self._finalize_other_group()
def segmentation_method(self, preprocessed_image):
# Run the actual model here; must return an itk.Image labelmap.
...
The base class then provides the shared pre/post-processing, contrast-agent
fusion, and create_anatomy_group_masks() that walks the taxonomy and
emits one mask per registered group plus "other".
Custom Anatomy Looks
If the new segmenter introduces groups beyond the default chest set
(heart, lung, bone, major_vessels, contrast,
soft_tissue, other), register a matching OmniSurface look so the
USD renderer doesn’t fall back to the generic "other" material:
from physiomotion4d.usd_anatomy_tools import DEFAULT_RENDER_PARAMS
DEFAULT_RENDER_PARAMS["brain"] = {
"name": "Brain",
"diffuse_reflection_color": (0.85, 0.75, 0.7),
# ... see existing entries for the full parameter list ...
}
See USD Generation for the renderer-side contract.
Development Notes
Use
log_info()andlog_debug()inside runtime classes; neverprint.Document the key set the segmenter produces; downstream callers should check membership rather than assume a fixed schema.
Keep tests synthetic unless real model/data behavior is being validated.
Mark real-data tests with
requires_data.
See Also
Segmentation Base Class — full AnatomyTaxonomy reference
USD Generation — how the taxonomy drives USD output