Hello,
For my undergraduate project, I am developing a Slicer extension that opens a volume and a segmentation containing numerous segments.
Since some segments within the segmentation are incorrect, my extension should enable users to remove them individually. This can be done by hovering over the segment with the mouse, pressing a button, and deleting the segment.
So far I implemented a working function that looks like this:
Code
def eraseSegment(self):
def getSegmentNames(segNode,pntListNode):
ras = [0, 0, 0]
sliceViewLabel = "Red" # any slice view where segmentation node is visible works
sliceViewWidget = slicer.app.layoutManager().sliceWidget(sliceViewLabel)
segmentationsDisplayableManager = sliceViewWidget.sliceView().displayableManagerByClassName("vtkMRMLSegmentationsDisplayableManager2D")
pntListNode.GetNthControlPointPositionWorld(0, ras)
segmentIds = vtk.vtkStringArray()
segmentationsDisplayableManager.GetVisibleSegmentsForPosition(ras, segNode.GetDisplayNode(), segmentIds)
for idIndex in range(segmentIds.GetNumberOfValues()):
segment = segNode.GetSegmentation().GetSegment(segmentIds.GetValue(idIndex))
return segment.GetName()
crosshairNode = slicer.util.getNode("Crosshair")
pos = [0, 0, 0]
crosshairNode.GetCursorPositionRAS(pos)
slicer.modules.markups.logic().AddControlPoint(pos[0], pos[1], pos[2])
pointListNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLMarkupsFiducialNode")
volumeNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLVolumeNode")
segmentationNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLSegmentationNode")
try:
pointListNode.AddObserver(slicer.vtkMRMLMarkupsPlaneNode.PointModifiedEvent, getSegmentNames)
segmentId = getSegmentNames(segmentationNode,pointListNode)
segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId, volumeNode)
segmentArray[:] = 0
slicer.util.updateSegmentBinaryLabelmapFromArray(segmentArray, segmentationNode, segmentId, volumeNode) # Every time that this is called and erase a segment, the memory used on the RAM increases
except:
segNode = None
print("No segmentation nodes found")
In summary, when the user calls the function, the mouse position is determined and used to retrieve the segment ID at that location. The segment is then deleted by calling:
segmentArray = slicer.util.arrayFromSegmentBinaryLabelmap(segmentationNode, segmentId, volumeNode)
segmentArray[:] = 0
slicer.util.updateSegmentBinaryLabelmapFromArray(segmentArray, segmentationNode, segmentId, volumeNode)
However, each time that this line is called:
slicer.util.updateSegmentBinaryLabelmapFromArray(segmentArray, segmentationNode, segmentId, volumeNode)
the memory used on the RAM increases a lot (almost by a fourth); which is unelegant and unpractical when a lots of segments need to be removed.
I feel that I am missing something, what is the cause for this and what could be an alternative way to delete a specific segment using its ID?
Cheers,
Ludo