Segment Editor - Repetitive function

It would be great if we can determine the number of times the same effect is applied.

For example,

If i want to grow the margin by 5 mm and if my computer processing power is not enough to grow it by 5 mm at the same time but it can grow it by 1 mm at a time, rather than i having to manually do the function 5 times it would be good if we can control how many times it is applied on the segment one after the other.

This will make it possible for lower end computers to do the processing when it comes to large data sets.

Repeating an effect should not be necessary in general. Repeating an effect many times sometimes also results in less accurate results than running the effect once, with modified parameters (e.g., margin effect 5x with 1mm kernel is not as accurate as margin effect 1x 5mm kernel).

If repeating an effect many times is needed for a very particular workflow then it can be scripted as part of that workflow.

If repeating an effect could be useful in many workflows then we would add that as an option to that specific effect’s GUI.

For Margin and Hollow effect performance issue we already have a fast and accurate solution that will be released soon.

1 Like

@manjula as loassan said running the effect lots of times may cause inaccuracies but if you have to do it because of computer power then you could try this script, it worked ok for me. Once the margin effect has run a few times (amount chosen by you) it will print out the total amount that the segment has grown by.

You will need to make some changes to the code for it to work for you including:

  1. Set how much you want the segment to grow per iteration (change growSize variable)
  2. Set how many interations or how many times you want the effect to run (change nOfIterations variable)
  3. Change the volume getNode line to include the title or MRML ID of the volume you are using for the segmentation.
  4. Change the segmentation node getNode line to include the title or MRML ID of the segment node you wish to grow.
  5. Change the getSegment line to the title of the actual segment you wish to grow within that segmentation node.

I have added # comments by the lines which you need to change.

Hopefully this works for you,

growSize = 0.5 # set how much you want to grow the segment per iteration here
nOfIterations = 4 # set how many times you want to run the effect here

volume = getNode('vtkMRMLScalarVolumeNode1') # put the name of the main volume here

# get the segmentation node
segmentationNode = getNode('vtkMRMLSegmentationNode1') # put the name of the segment node here
segmentationNode.CreateDefaultDisplayNodes()
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(volume)
segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName('Segment_1') # put the name of the segment here


# setup temporary segment editor widget
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(volume)
segmentEditorNode.SetSelectedSegmentID(segmentID)

# set active effect to 'Margin' and set margin size
segmentEditorWidget.setActiveEffectByName("Margin")
effect = segmentEditorWidget.activeEffect()
effect.setParameter("MarginSizeMm", str(growSize))

totalGrowth = 0

# run the effect several times using a loop
for i in range(nOfIterations):
  effect.self().onApply()
  totalGrowth += growSize

print('The Segment Has Successfully Grown by ' + str(totalGrowth) + 'mm')

# delete temporary segment editor
segmentEditorWidget = None
slicer.mrmlScene.RemoveNode(segmentEditorNode)
#
2 Likes

Dear @Juicy many many thanks for the script and this is extremley useful and it works as intended for the first segment.

However when i add the next segment and run the script the second segment gets overridden.

If i move the segment two above the segment one then the segment two grows but segment one is altered. I guess this has to do with default masking settings of the margin effect.

So i guess we need to modify the masking settings. Can you please teach me how to modify the masking settings ?
thank you for the help.

@manjula I think I have figured out why it overwrites the other segment. If you change the ‘Modify other segments’ setting to ‘Allow overlap’ in the masking settings area down the bottom of segment editor then the other segment is not overwritten.

It took me a while to figure out how to change this setting in python but I can across this post which describes how to change the masking settings. So I have added the line segmentEditorNode.SetOverwriteMode(2) which I think changes the ‘Modify other segments’ setting to ‘Allow overlap’.

It worked on my computer. Hopefully it is ok for you. Updated code below.

growSize = 0.5 # set how much you want to grow the segment per iteration here
nOfIterations = 4 # set how many times you want to run the effect here

volume = getNode('vtkMRMLScalarVolumeNode1') # put the name of the main volume here

# get the segmentation node
segmentationNode = getNode('vtkMRMLSegmentationNode1') # put the name of the segment node here
segmentationNode.CreateDefaultDisplayNodes()
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(volume)
segmentID = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName('Segment_1') # put the name of the segment here


# setup temporary segment editor widget
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(volume)
segmentEditorNode.SetSelectedSegmentID(segmentID)
segmentEditorNode.SetOverwriteMode(2)

# set active effect to 'Margin' and set margin size
segmentEditorWidget.setActiveEffectByName("Margin")
effect = segmentEditorWidget.activeEffect()
effect.setParameter("MarginSizeMm", str(growSize))

totalGrowth = 0

# run the effect several times using a loop
for i in range(nOfIterations):
  effect.self().onApply()
  totalGrowth += growSize

# delete temporary segment editor
segmentEditorWidget = None
slicer.mrmlScene.RemoveNode(segmentEditorNode)

print('The Segment Has Successfully Grown by ' + str(totalGrowth) + 'mm')
#
1 Like

Thank you once again for taking time on this… yes now it works great and this will solve the problem while we look for a better PC or wait for the pull request as Prof Lasso get materialized. !!!

Integer values are not self-explaining (and they may change in the future), so use these enumerated values instead:

  • segmentEditorNode.SetOverwriteMode(slicer.vtkMRMLSegmentEditorNode.OverwriteAllSegments)
  • segmentEditorNode.SetOverwriteMode(slicer.vtkMRMLSegmentEditorNode.OverwriteVisibleSegments)
  • segmentEditorNode.SetOverwriteMode(slicer.vtkMRMLSegmentEditorNode.OverwriteNone)
3 Likes