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|")