Hi!
How can I save my connected components to a nrrd segmentation file that I can visualize in Slicer?
Thanks,
Diego
Hi!
How can I save my connected components to a nrrd segmentation file that I can visualize in Slicer?
Thanks,
Diego
Hello Diego,
What have you tried and what problems did you run into? Do you have a minimal example to reproduce your problematic situation?
Thanks.
What you probably need is show advanced options when loading data in Slicer and select “Label map”. That option is on by default if the file name ends in -label
(e.g. out-label.nrrd
), so you can just drag-drop it into Slicer.
I have connected components in my image after:
cc = sitk.ConnectedComponentsImageFilter()
results = cc.Execute(im_input)
I want to save results as a nrrd segmentation file that I can visualize in Slicer.
Hello @Diego_C ,
Just save the results as an image:
sitk.WriteImage(results, 'cc_results.mha')
Then you just load this image and overlay onto the original (I usually use ITK-SNAP for quick visualizations as it loads faster than Slicer. When I need more functionality I go with Slicer).
Thanks @zivy I need to show the results in Slicer though. I was thinking of writing the segmentation metadata myself but I was wondering if there was a simpler way of doing it with SimpleITK?
Hi @Diego_C ,
Not sure what you mean by “segmentation metadata”. If you write the segmentation to disk you just open the saved file in Slicer.
If you want to programmatically open Slicer and display the image with overlay you will have to:
If you want to save segment name, color, standard DICOM terminology, etc. in the nrrd file then you can do that by adding metadata fields using itk::MetaDataDictionary
and pass it on to the reader using SetMetaDataDictionary
. Definition of seg.nrrd file custom metadata fields is available here.
Hey @zivy the nrrd files need to have a particular set of metadata headers so you can use them with the Segmentation Module in Slicer. I was wondering if there was a way to get this without having to coding it myself.
Hello Andras Lasso,
I want to save a segment label with its name, but I can not see how I do this using SimpleITK. The code to save my segment is:
writer = sitk.ImageFileWriter()
writer.Execute(label, segment.seg.nrrd’, True,0)
I need some help.
@lassoan this was pretty insightful, thank you!
Is there any nice example somewhere of assigning these correctly to a LabelMap with multiple labels? Especially when there are many labels and when SegmentN_Layer
and SegmentN_LabelValue
should be used.
Hello @ibro45,
Not exactly what you are looking for but closely related, an example of three labels saved to seg.nrrd format is available in the results visualization notebook, visual_comparison_of_segmentation
function.
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|")