Hi
I’m trying to run a script to perform automated segmentations right after resampling the volume to an isotropic spacing.
The output is the resampled volume, but the segmentation from the original volume, not the resampled. I tried to use time.sleep() and also thread.join() to overcome the issue, but with the former the segmentation gets the original volume and with the latter Slicer crashes.
The code that you posted looks good, it is just incomplete, so I cannot tell you what is missing (setting segmentation node in a segment editor widget, set master volume in the widget, etc.). We can help if you provide a complete example that reproduces the unexpected behavior.
The code is similar to the extract skin example you provide, just adding the resampling step since in my dataset the AIAA prediction performs better on volumes with isotropic spacing.
However, when I run this code, the prediction is done on the volume with the original spacing, not the resampled. Then I tried to add a “pause” right after the resampling using Python time module (adding time.sleep() with a couple of seconds to wait the task being executed before it continues, as in the example below) without success and also thread module (thread.join()) but no success.
Thanks
Caio
import time
[success, VolumeNode] = slicer.util.loadVolume(path, returnNode=True)
# Resample the volume to 0.25mm spacing
parameters = {"outputPixelSpacing":"0.25,0.25,0.25", "InputVolume":VolumeNode,"interpolationType":'linear',"OutputVolume":VolumeNode}
slicer.cli.run(slicer.modules.resamplescalarvolume, None, parameters)
time.sleep(3)
# Create segmentation node with segment
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(VolumeNode)
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment("segment")
# Create segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setVolumeNode(VolumeNode)
# NVIDIA auto segmentation
segmentEditorWidget.setActiveEffectByName("Nvidia AIAA")
effect = segmentEditorWidget.activeEffect()
serverUrl = "http://LINK/v1/models"
effect.self().ui.serverComboBox.currentText = serverUrl
effect.self().onClickFetchModels()
effect.self().ui.segmentationModelSelector.currentText = "model_name"
effect.self().onClickSegmentation()
I don’t think that the segment editor widget has setVolumeNode method. Probably you meant to callsetMasterVolumeNode method instead. You should have seen an error message when you executed this code.
I’m sorry, it was a mistake when I copied the code to the message. Thanks for pointing it out.
Please notice that In the example below the labelmap generated has the original spacing, rather than the isotropic resampled volume.
The segmentation happens before the resampling is completed, that’s what I would like to avoid.
Thanks for your precious time
# 1st : load a CT into the scene (e.g. download CT Chest from sample data)
masterVolumeNode = getNode('vtkMRMLScalarVolumeNode1')
=========================
#resample the volume
parameters = {"outputPixelSpacing":"1,1,1", "InputVolume":masterVolumeNode,"interpolationType":'bspline',"OutputVolume":masterVolumeNode}
slicer.cli.run(slicer.modules.resamplescalarvolume, None, parameters)
========================
# Create segmentation with bone segment
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)
bone = segmentationNode.GetSegmentation().AddEmptySegment("bone")
# Create segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)
# Set bone segment color
segmentationNode.GetSegmentation().GetSegment(bone).SetColor(0.9,1,0.7)
segmentEditorWidget.setCurrentSegmentID(bone)
# Thresholding
segmentEditorWidget.setActiveEffectByName("Threshold")
effect = segmentEditorWidget.activeEffect()
effect.setParameter("MinimumThreshold","200")
effect.setParameter("MaximumThreshold","2000")
effect.self().onApply()
labelmap = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLabelMapVolumeNode')
slicer.modules.segmentations.logic().ExportVisibleSegmentsToLabelmapNode(segmentationNode, labelmap, masterVolumeNode)
==============
Now, I see what the issue is: you do resampling in a background processing thread, therefore you still use the original, non-resampled volume as input for the segmentation. You don’t even notice, because you use the same volume as both input and output of resampling. All you need to do is to change slicer.cli.run to slicer.cli.runSync. See all the examples on this page.