Skip to content

Segmentations (SEG)

Author and read coded DICOM Segmentation objects — the standard itkimage2segimage / segimage2itkimage capability, in Python.

Write a binary SEG

write_seg takes a source image (for geometry, demographics and references), a uint16 labelmap, and a list of segment terminology dicts:

import numpy as np
import pydcm

labelmap = np.zeros((slices, rows, cols), dtype=np.uint16)
labelmap[mask_liver] = 1
labelmap[mask_tumor] = 2

segments = [
    {"label": "Liver", "labelID": 1, "rgb": (221, 130, 101),
     "category": ("123037004", "SCT", "Anatomical Structure"),
     "type":     ("10200004",  "SCT", "Liver")},
    {"label": "Tumor", "labelID": 2, "rgb": (255, 0, 0),
     "category": ("49755003",  "SCT", "Morphologically Abnormal Structure"),
     "type":     ("4147007",   "SCT", "Mass")},
]

pydcm.write_seg("ct_series/", labelmap, segments, output="seg.dcm")
  • reference is a source-image path or a list of the series' instance paths; the slices of labelmap must be ordered by ascending position to match.
  • Omit output to get Part-10 bytes back instead of writing a file.
  • Each segment dict also accepts anatomic, algorithm_type and algorithm_name.

Write a fractional SEG

For probability or occupancy maps (e.g. a model's softmax output), one float map per segment:

pydcm.write_seg_fractional(
    "ct_series/",
    maps={1: prob_liver, 2: prob_tumor},   # float arrays in [0, 1]
    segments=segments,
    type="probability",                    # or "occupancy"
    output="seg_frac.dcm",
)

Read a SEG back

result = pydcm.read_seg("seg.dcm", masks=True)

With masks=True you get the per-segment masks reconstructed into the reference geometry — the labelmap round-trips. This is the analysis-side mirror into the reference geometry.

From a model prediction

Combined with preprocessing, the full loop is:

vol    = pydcm.load_series("ct_series/")
logits = pydcm.transforms.sliding_window_inference(vol.pixels, (96,)*3, model)
seg    = pydcm.transforms.argmax(logits, vol.affine)
pydcm.write_seg("ct_series/", seg.pixels.astype("uint16"), segments, output="pred.dcm")