Get label map node from segmentation node

Hello!

Is there a way to create a label map node from a segmentation node? I know I can go the other way (from a label map to a segmentation), but I can’t seem to find a way to do the opposite. If this is not possible is there a way to at least get the array underlying the segmentation node? I know I can get an oriented image data, but if I do slicer.util.array on the oriented image data, nothing is returned.

Thanks!

Answered in

You can also reach this function (i.e. Segmentations module import/export) from the Data module (right-click the segmentation), and in Segment Editor as an option for the Segmentations button.

Awesome! Do you know how I might do this through the python code?

Found it:

slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode()

Do you know what the inputs for this function is or where the documentation is for the segments?

slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode()

These are the available signatures

A few examples of usage

1 Like

Are there examples in python?

You can always use help() function in Python to get documentation, for example:
help(slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode)

Example where it is used: https://github.com/Slicer/Slicer/blob/master/Utilities/Templates/Modules/ScriptedSegmentEditorEffect/SegmentEditorTemplateKeyLib/SegmentEditorEffect.py#L97

To create a custom Segment Editor effect, use ExtensionWizard module and choose ScriptedSegmentEditorEffect module template. It creates a fully functional effect that uses SimpleITK and you just have to replace the core of it to do what you need.

1 Like

@snvl The first two results in the search that was the second link in my post above are python examples.

@cpinter Would you please help explain this to me?
inside here:
slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(segmentationNode, segs, tmpLabelmapNode, masterVolumeNode)
where segs has to be an vtk.vtkStringArray() and the segs may be obtained by:

segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
segs = vtk.vtkStringArray()
segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(segs)

But while I try to get the selected segment-ID through:

segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
selectedSegmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
where I just got a simple string for selectedSegmentID

How can I get a vtk.vtkStringArray for this selectedSegmentID or any easy conversion?

Thanks a lot.

sa = vtk.vtkStringArray()
sa.InsertNextValue(selectedSegmentID)

FYI the documentation tells you everything
https://vtk.org/doc/nightly/html/classvtkStringArray.html

@cpinter Thank you so much for the quick reply. Sorry I am kind of new to vtk.
:+1:
Best,
Aiden

@lassoan @cpinter is it possible to get the reference volume?

I searched, but could not find the answer. I was confused by the comment for the method below, it just returns a constant string.

The constant string is the name of the node reference role. You can get the reference volume node like this: segmentationNode.GetNodeReference(slicer.vtkMRMLSegmentationNode.GetReferenceImageGeometryReferenceRole())

1 Like

Thank you Andras, this resolved the latest issue I had!

1 Like

Related to this issue, I wanted to mention that I used this approach without reading documentation (my usual mode of operation :roll_eyes:) as follows:

segmentLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
slicer.mrmlScene.AddNode(segmentLabelmapNode)
segmentIDs = vtk.vtkStringArray()
segmentIDs.InsertNextValue(0)
referenceNode = segmentationNode.GetNodeReference(slicer.vtkMRMLSegmentationNode.GetReferenceImageGeometryReferenceRole())
slicer.modules.segmentations.logic().ExportSegmentsToLabelmapNode(segmentationNode, segmentIDs, segmentLabelmapNode, referenceNode)

Somehow this code works in the nightly, but when I do this in 4.10.2 I get error (InsertNextValue expects a string). If I do pass 0 as a string, I get a crash. The correct way to initialize that array, as I understand it, is the following:

segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)

Just in case this can help someone else.