Assigning thresholded regions to different segments

segmentation
extensions

(Ishan Saxena) #1

Operating system: Windows 7
Slicer version: 4.10
Expected behavior: Different thresholded regions get assigned to respective segments
Actual behavior: Both regions getting assigned to the first threshold segment

Hi everyone,
I am working on an extension to 3D Slicer. The final aim of the extension is to segment the CT scan images to 2 base segments based on the thresholding values. For doing this, I am applying the Thresholding operation on 2 cloned segmentation and volume nodes. After this, I can’t determine how to assign the thresholded regions to a specific segment?

# Add segments

segmentName = "Threshold-A-B"
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(segmentName)
segment = segmentationNode.GetSegmentation().GetSegment(addedSegmentID)
segment.SetColor(216./256,101./256,79./256)

segmentName = "Threshold-B-MAX"
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(segmentName)
segment = segmentationNode.GetSegmentation().GetSegment(addedSegmentID)
segment.SetColor(200./256,200./256,235./256)	

#Cloning segmentationNode and masterVolumeNode
#Copied from Slicer website, get clonedNode and clonedVolumeNode from here

# 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)

# Thresholding (From A to B)
segmentEditorWidget.setActiveEffectByName("Threshold")
effect = segmentEditorWidget.activeEffect()
effect.setParameter("MinimumThreshold","A")
effect.setParameter("MaximumThreshold","B") 
effect.self().onApply()

displayNode = segmentationNode.GetDisplayNode()
displayNode.SetSliceIntersectionThickness(2)
#Missing: Assign this to segment 'Threshold-A-B'	

#Creating a  second segment editor to apply second thresholding to cloned volume
segmentEditorWidget2 = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget2.setMRMLScene(slicer.mrmlScene)
segmentEditorNode2 = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget2.setMRMLSegmentEditorNode(segmentEditorNode2)
segmentEditorWidget2.setSegmentationNode(clonedNode)
segmentEditorWidget2.setMasterVolumeNode(clonedVolumeNode)	

# Thresholding 2 (From B to MAX)
segmentEditorWidget2.setActiveEffectByName("Threshold")
effect2 = segmentEditorWidget2.activeEffect()
effect2.setParameter("MinimumThreshold","B")
effect2.self().onApply()

displayNode2 = clonedNode.GetDisplayNode()
displayNode2.SetSliceIntersectionThickness(2)
#Missing: Assign this to the segment 'Threshold-B-MAX' 

(Andras Lasso) #2

There is no need to create a second segment editor widget. You can combine segments using Logical operators effect.


(Ishan Saxena) #3

Thanks for the help. I found this great example for using the Logical Operators effect, which could be useful for others too: https://gist.github.com/hherhold/ec3f74d20ca63866555f3e66d1f3621c

I just had a basic question regarding the above file, Is there a way to clear the scene, once the script has run for one image. I have like 50 images that need I want to segment but every time I run this code in Slicer, the segmentation for each next image just appears on top of each other in the scene views.

I tried using the below code at the end

    segmentEditorWidget = None
    slicer.mrmlScene.RemoveNode(segmentationNode)
    slicer.mrmlScene.RemoveNode(masterVolumeNode)

But this just throws an error

Traceback (most recent call last):
File “D:/Users/ishan.saxena/TokExData/SlicerScripts/Segmentation_postop.py”, line 72, in onSegmentationButtonClicked
self.addSegmentation(dir_path, filename)
File “D:/Users/ishan.saxena/TokExData/SlicerScripts/Segmentation_postop.py”, line 172, in addSegmentation
effect.setParameter(“Operation”, “COPY”)
AttributeError: ‘NoneType’ object has no attribute ‘setParameter’

If I comment these removeNode commands, the code starts working perfectly only the scenes don’t get cleared. Any tips?


(Steve Pieper) #4

This should work:

slicer.mrmlScene.Clear(0)

(Andras Lasso) #5

Also, it should be enough to clear the scene and no need to delete segmentEditorWidget when you switch between data sets.


(Ishan Saxena) #6

Thanks for the responses, however the error remains the same even after adding slicer.mrmlScene.Clear(0) at the end of the script and deleting segmentEditorWidget=None and the other RemoveNode commands.

I am guessing there is something wrong with the way I define the Segmentation nodes and volume nodes under addSegmentation which doesn’t match with the Logical Operators effect script I used from the link above.
My current definitions are:

slicer.app.processEvents()
masterVolumeNode = slicer.util.loadVolume(file_complete, returnNode = True)[1]
# Create segmentation
segmentationNode_name = filename + "_" + welcheOP + "_segmentation"
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode", segmentationNode_name)
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

(Andras Lasso) #7

The error is in your script. Value of effect variable is None. I would recommend to use a Python debugger and execute your code step by step to see where it does something different than you would expect.


(Ishan Saxena) #8

I made some observations from the debugging process. Since I am using the SegmentEditor module in a loop in my script, it sets the ActiveEffect to None after the first iteration through the loop, and then during the next iteration, I am unable to set the ActiveEffect using

segmentEditorWidget.setActiveEffectByName(“Logical operators”)

Any ideas, why I am unable to do that?


(James Butler) #9

Without seeing your code and since you say it works for the first time through the loop, I’m going to guess you haven’t set SementationNode or MasterVolumeNode correctly at the time of setting active effect to logical operators. This might be because you are removing the nodes from the scene after the first iteration?

You might want to consider interacting with the segment editor widget within Slicer and using the python interactor as a way of debugging. Then you could see looking at the GUI what might be going wrong following specific commands.


(Ishan Saxena) #10

I have uploaded my code here: https://gist.github.com/ishansaxena45/2ef0ec665e371a0ff8b91c866129f722

I am sorry I could not really identify the problem while debugging it manually.


(Ishan Saxena) #11

Hi again,

the problem with clearing the scene still remains. I have uploaded my script here and am also sharing some test data here. Can someone please help?


(Andras Lasso) #12

A few weeks ago I’ve implemented an example script that creates segments from a CT based on predefined intensity ranges. You may use this as is, or as a starting point.


(Ishan Saxena) #13

Thanks so much for your code. The problem is now solved. I was wrong in the definitions of the SegmentEditorWidget and not using SegmentEditorNode. Now everything works as expected.