Export segmentation to labelmap using python

Hi guys,

I am trying to save some clicks and time by wrting a python script for saving my segmentations to files (labelmaps (nii.gz))
I simply do not undestand how to provide the reference image to the function:

slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode()

so my code is:

seg = slicer.util.getNode(‘Segmentation_2’)
lmVN = slicer.mrmlScene.AddNewNodeByClass(‘vtkMRMLLabelMapVolumeNode’)
slicer.modules.segmentations.logic().ExportAllSegmentsToLabelmapNode(seg, lmVN)
saveNode(lmVN, file_name)

if I give the reference image as additional argument, I get following error:

Traceback (most recent call last):

File “”, line 1, in

TypeError: ExportAllSegmentsToLabelmapNode() takes exactly 2 arguments (3 given)

Can anybody help?

Thank you very much!

Cheers,

Dima

1 Like

See code snippet that does what you need in the script repository, and a complete working example here.

1 Like

thank you very much for your reply!

After running this Slicer crashes down:

#load volume
masterVolumeNode = slicer.util.loadVolume('c:/Users/desserdmi/Desktop/data.nii.gz', returnNode=True)

#make vtk object of mastervolume
masterVolumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkmasterVolumeNode")

#  --- Doing some   manual segmentation ----

#make segmentationNode
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")

#set references to masterVolumeNode
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

#make labelvolumenode
labelmapVolumeNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')

#export Segmentation to labelmapNode
slicer.modules.segmentations.logic().ExportVisibleSegmentsToLabelmapNode(segmentationNode, labelmapVolumeNode, masterVolumeNode)

#save labelmap to disk
slicer.util.saveNode(labelmapVolumeNode,"c:/Users/desserdmi/Desktop/data.nii.gz")

I am still doing something wrong… Do you maybe have any idea of what the reason could be?

The original error was caused because that function is static, and the way you called it, it passes the object instance (self) as well.

To the code you recently pasted:

You don’t need this for sure. By the way there is no such class as vtkmasterVolumeNode. So this will return None and the variable won’t contain the loaded nifti file any more.

Thank you very much for your reply!

the reason, why I have tried this is the error message I get:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: SetReferenceImageGeometryParameterFromVolumeNode argument 1: method requires a VTK object

Anyway, is there no simple solution for this issue in 3dSlicer? I mean a simple save segmentation as function like in ITK-SNAP?

I have an amount of data with long names (BIDS) and trying to do some automatisation for segmentation like: load data -> segment it manually -> save segmentation to binary label maps

In general, my advice is that try running the lines within the python interactor one by one, checking the content of variables. The error messages are usually pretty straightforward. For example if the message is that it should be a VTK object and it’s not, then you need to find out what it is instead.

Of course there is:
image
(this is in the Segmentations module)

Pleae check the source code for that if you want to automate it. Also the script repository (see @lassoan’s answer above) contains lots of examples you can directly use. In addition, this forum has topics for mostly every issue you may encounter, so please don’t hesitate to search it. The documentation may also help: Documentation/Nightly/Modules/Segmentations - Slicer Wiki

We are of course aware that some simple segmentation software (that cannot work with arbitrary number of master volumes with varying geometry, overlapping segments, etc.) can save everything in a simple 3D labelmap. However, since Slicer is much more flexible, we need to use a more general file format by default to be able to save all segmentation data without losing information.

If you only use a single master volume and segments don’t overlap then you can export the segmentation into a simple 3D labelmap:

  • Using the application GUI by a few clicks either as Csaba showed above, or even simpler, just by right-clicking on the segmentation node in Data module and selecting “Export visible segments to binary labelmap”
  • Using two lines of Python code AddNewNodeByClass followed by ExportVisibleSegmentsToLabelmapNode (see here).

I’ve added a complete example that exports your segmentation to a simple 3D labelmap if you hit Ctrl+Shift+S - see here. You can add the code snippet to you .slicerrc file to make this feature permanently available.

Thank you so much guys!

editing .slicerrc works perfectly!

This is what I was looking for!

Cheers,

Dima

Hi Guys,

I am trying to automate storing the segmentation Node using 3D Slicer extension.

self.currentSelector = slicer.qMRMLNodeComboBox()
self.currentSelector.nodeTypes = [“vtkMRMLScalarVolumeNode”]

slicer.modules.segmentations.logic().ExportVisibleSegmentsToLabelmapNode(actual_segmentation_node, labelmapVolumeNode,actual_master_node)

Error details
ExportVisibleSegmentsToLabelmapNode argument 1: method requires a VTK object

The problem I am facing is I am unable to get reference to the actual Node name referred by slicer.qMRMLNodeComboBox().

The alternative as given in the website reference is getNode(“name”) or GetFirstNodeByClass(“vtkMRMLSegmentationNode”).This requires either it should be first in the list or know the node name earlier.

I want to get all the names of Segmentation Node which is currently selected by the qMRMLNodeComboBox().

Please share the reference if you have any.

Thank you very much!

You can get the node selected in qMRMLNodeComboBox by calling currentNode() method. See more examples and background information in Slicer programming tutorials.

Thank you @lassoan. This solves my problem.
I was able to get the name using slicer.util.getNode(“currentNodeId value”).GetName()

Thanks for sharing the solution that worked for you. slicer.util.getNode is intended for quick testing and troubleshooting (as it accepts both name and node ID). For a more robust solution to get name of a selected volume, I would recommend to use slicer.mrmlScene.GetNodeByID(myNode.GetID()).GetName() or simply myNodeComboBox.currentNode().GetName().

1 Like

2 posts were split to a new topic: Different segmentation export function produce different results