Programatically save Overlapping Segments

Hi, I am using Slicer as part of a workflow that includes segmentation of overlapping regions. The segmentation needs to be saved programmatically.

When I save as a .nrrd file with slicer.modules.segmentations.logic().ExportSegmentsBinaryLabelmapRepresentationToFiles(segmentationNode, labelmapVolumeNode, referenceVolumeNode) the overlapping segments get flatten. However, when I save the whole scene by clicking on the save icon, the segmentation gets exported as a .seg.nrrd 4D non overlapping volumes. What is the command to save the segmentation as a 4D volume?

Thanks in advance

What is the difference between the .seg.nrrd and the 4D volume you need? The .seg.nrrd file is basically a 4D nrrd with some extra metadata in the header.

Thanks for your prompt reply.

The seg.nrrd file is what I need, but I need a way to generate it programmatically. When I save the segmentation with the command above, I get only a 3D array, but I need the 4D volume you get by saving the file manually.

Ah, I see. Here’s how I’d do it:

s = getNode('vtkMRMLSegmentationNode1')
ss = s.GetStorageNode()
ss.SetFileName(r'd:/segmentation.seg.nrrd')
ss.WriteData(s)

(I found the corresponding example in the script repository, it says the same thing)

You can also use the saveNode convenience function (from the script repository, too):

success = slicer.util.saveNode(node, filename)
1 Like

This solved my problem.

Thanks for the help

Here is the code I use

def exportLabelmap():

    filepath = outputPath + "/label.seg.nrrd"
    segmentationNode = getNode('vtkMRMLSegmentationNode1')
    storageNode = segmentationNode.CreateDefaultStorageNode()
    storageNode.SetFileName(filepath)
    storageNode.WriteData(segmentationNode)

    slicer.util.delayDisplay("Segmentation saved to " + filepath)

shortcut = qt.QShortcut(slicer.util.mainWindow())
shortcut.setKey(qt.QKeySequence("Ctrl+Shift+s"))
shortcut.connect( "activated()", exportLabelmap)

Thanks for sharing the code that worked for you.

Hardcoding an automatically generated ID would be fragile (e.g., you may create a second segmentation and delete the first one; then you will not find any node by the ID vtkMRMLSegmentationNode1). Instead, you can get the first segmentation node from the scene like this (from the script repository):

segmentationNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLSegmentationNode")