Writing a nrrd segmentation file in SimpleITK

Thank you so much @zivy, that really helped.

For future reference, I’ll explain what I did:

I needed to save overlapping segmentations with a particular name and color. I first collected the binary masks for each segmentation and then composed them using sitk.Compose. Then, I set the metadata for each segment in the composed mask. Code:

from SimpleITK import sitk


def set_individual_segment_metadata(mask, seg_num, name, color, tags=None):
    # `seg_num` starts from 0, but ID starts from 1
    mask.SetMetaData(f"Segment{seg_num}_ID", str(seg_num + 1))
    # A separate layer per label, allows overlapping segmentations.
    mask.SetMetaData(f"Segment{seg_num}_Layer", str(seg_num))
    # Each label is saved in a separate layer, so we just need to set the foreground of each to 1
    mask.SetMetaData(f"Segment{seg_num}_LabelValue", "1")

    mask.SetMetaData(f"Segment{seg_num}_Name", name)
    mask.SetMetaData(f"Segment{seg_num}_NameAutoGenerated", "0")

    mask.SetMetaData(f"Segment{seg_num}_Color", color)
    mask.SetMetaData(f"Segment{seg_num}_ColorAutoGenerated", "0")

    # Extent, as defined in https://github.com/InsightSoftwareConsortium/SimpleITK-Notebooks/blob/e805f171ef633575486b48377db4e0715d42f63d/Python/05_Results_Visualization.ipynb#L860
    mask.SetMetaData(
        f"Segment{seg_num}_Extent", 
        f"0 {mask.GetWidth()-1} 0 {mask.GetHeight()-1} 0 {mask.GetDepth()-1}"
    )

    if tags is not None:
        mask.SetMetaData(f"Segment{seg_num}_Tags", tags)

    return mask


# Combine all masks
mask = sitk.Compose([
    LA, LV, ...
])

# Set metadata per segment, make sure to apply in the same order as above
mask = set_individual_segment_metadata(mask, 0, "LA", "1.0 0.0 0.0")  # Red
mask = set_individual_segment_metadata(mask, 1, "LV", "0.0 1.0 0.0")  # Green
...

# Common metadata
mask.SetMetaData("Segmentation_MasterRepresentation", "Binary labelmap")
mask.SetMetaData("Segmentation_ReferenceImageExtentOffset", "0 0 0")
mask.SetMetaData("Segmentation_ContainedRepresentationNames", "Binary labelmap|")
3 Likes