Threshold scalar volume to labelmap

I am trying to use the python interface to load a (float) scalar volume in the form of a signed distance field want to apply thresholdscalarvolume to generate a label map with everything below 0.0. It doesn’t seem to be working in terms of creating the label map and running the cli interface.

here is a brief attempt with the code:

level_set = value['level_set']

[success, volumeNode] = slicer.util.loadVolume(level_set, returnNode=True)
volumeNode.SetName("case4" + "level_set")

tempLabel = slicer.vtkMRMLLabelMapVolumeNode() 
slicer.mrmlScene.AddNode(tempLabel) 
tempLabel.SetName("case4" + "thingy") 
temp_stuff = slicer.vtkSlicerVolumesLogic().CreateLabelVolumeFromVolume(slicer.mrmlScene, tempLabel, volumeNode)

# Compute the thresholded output volume using the Threshold Scalar Volume CLI module
cliParams = {'InputVolume': volumeNode.GetID(), 'OutputVolume': tempLabel.GetID(), 'ThresholdValue' : 0.0, 'ThresholdType' : 'Below', 'OutsideValue' : 1.0}
cliNode = slicer.cli.runSync(slicer.modules.thresholdscalarvolume, None, cliParams, wait_for_completion=True)

You can do it much simpler way:

voxelArray = slicer.util.arrayFromVolume(volumeNode)
voxelArray[voxelArray < thresholdValue] = 0
slicer.util.arrayFromVolumeModified(volumeNode)

Next steps depend on what you would like to do. Would you like to convert this to a segmentation node?

I figured out two things. runSync forces the command to wait until completed whereas run immediately returns and has to be checked.

the second thing was checking cliNode.GetErrorText() is empty the problem is that I used lower case “below” rather than “Below”.

now the line executes but doesn’t show anything on the screen.

That is much simpler. thank you.

yes that is it exactly, I saw the another post where there are commands to import the the label map to a segmentation mode, but hadn’t gotten that far yet.

You can create a segmentation from thresholded input volumeNode like this:

volumeNode = ...
thresholdValue = 80

# Create temporary labelmap
labelVolumeNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLabelMapVolumeNode")
slicer.vtkSlicerVolumesLogic().CreateLabelVolumeFromVolume(slicer.mrmlScene, labelVolumeNode, volumeNode)

# Fill temporary labelmap by thresholding input volumeNode
voxelArray = slicer.util.arrayFromVolume(volumeNode)
labelVoxelArray = slicer.util.arrayFromVolume(labelVolumeNode)
labelVoxelArray[voxelArray >= thresholdValue] = 100
labelVoxelArray[voxelArray < thresholdValue] = 0
slicer.util.arrayFromVolumeModified(labelVolumeNode)

# Import labelmap to segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentationNode')
slicer.modules.segmentations.logic().ImportLabelmapToSegmentationNode(labelVolumeNode, segmentationNode)
segmentationNode.CreateClosedSurfaceRepresentation()

# Delete temporary labelmap
slicer.mrmlScene.RemoveNode(labelVolumeNode)
1 Like

is it possible to set the master volume in the editor? can I do from the segmentationNode?

and also is it possible to select the slice views orientation button via as well?

Yes, good point, you can easily create segments directly from a grayscale volume by choosing the volume as master volume and using Threshold effect. See full examples in the script repository.

Thanks,
what I am doing is a little more complicated. I am pre segmenting with vmtk and want to edit that segmentation with slicer.

I used the command segmentEditorWidget.setMasterVolumeNode(volumeNode) to set the master volume but it didn’t change the gui view like it did when changed the name of the segmentation.

also whats the command to do the alignment? I wish I had a better way to figure out how buttons are linked to the commands to be used in as script.

You can change view by using slicer.util.setSliceViewerLayers method.

I’m not sure what alignment you are referring to.

When I need to find how GUI actions mapped to code, the most direct way is to download Slicer source code and search in full text of all files. Most cases GUI strings are defined in Qt .ui files. In the .ui file you can find widget’s name that shows that string. Once you have the widget name, search full text of Slicer source code for widget name and you’ll find code that runs when the widget is manipulated.

You might find Slicer API documentation and you can always ask on this forum.

Whats the python command to do the alignment of the image volume and segmentation?
figure

found it: segmentEditorWidget.rotateSliceViewsToSegmentation()

when I try to execute the following I get an error:

segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

segmentEditorWidget.setMRMLScene(slicer.mrmlScene) gives an error:

Python console user input: segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
void qMRMLSegmentEditorWidget::onSegmentSelectionChanged(const QItemSelection&, const QItemSelection&) : Invalid segment editor parameter set node
void qMRMLSegmentEditorWidget::onSegmentationNodeChanged(vtkMRMLNode*) : Invalid segment editor parameter set node
void qMRMLSegmentEditorWidget::onSegmentSelectionChanged(const QItemSelection&, const QItemSelection&) : Invalid segment editor parameter set node
void qMRMLSegmentEditorWidget::onSegmentationNodeChanged(vtkMRMLNode*) : Invalid segment editor parameter set node
void qMRMLSegmentEditorWidget::onMasterVolumeNodeChanged(vtkMRMLNode*) : Invalid segment editor parameter set node
void qMRMLSegmentEditorWidget::onMasterVolumeNodeChanged(vtkMRMLNode*) : Invalid segment editor parameter set node
void qMRMLSegmentEditorWidget::onMasterVolumeNodeChanged(vtkMRMLNode*) : Invalid segment editor parameter set node
virtual void qMRMLSegmentEditorWidget::updateWidgetFromMRML() : Invalid segment editor parameter set node

These errors are logged because the widget attempts to update itself but segment editor parameter node is not set yet (using setMRMLSegmentEditorNode). You can ignore these errors and we’ll update the widget to not log these errors.

1 Like