2 import vtk, qt, ctk, slicer, logging
3 from AbstractScriptedSegmentEditorEffect
import *
5 __all__ = [
'AbstractScriptedSegmentEditorAutoCompleteEffect']
15 """ AutoCompleteEffect is an effect that can create a full segmentation 16 from a partial segmentation (not all slices are segmented or only 17 part of the target structures are painted). 23 scriptedEffect.perSegment =
False 24 AbstractScriptedSegmentEditorEffect.__init__(self, scriptedEffect)
40 autoUpdateDelaySec = 1.0
48 super(SegmentEditorAutoCompleteEffect,self).
__del__()
54 self.
autoUpdateCheckBox.setToolTip(
"Auto-update results preview when input segments change.")
59 self.
previewButton.objectName = self.__class__.__name__ +
'Preview' 60 self.
previewButton.setToolTip(
"Preview complete segmentation")
63 qSize = qt.QSizePolicy()
64 qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding)
67 previewFrame = qt.QHBoxLayout()
70 self.
scriptedEffect.addLabeledOptionsWidget(
"Preview:", previewFrame)
81 displayFrame = qt.QHBoxLayout()
82 displayFrame.addWidget(qt.QLabel(
"inputs"))
84 displayFrame.addWidget(qt.QLabel(
"results"))
85 self.
scriptedEffect.addLabeledOptionsWidget(
"Display:", displayFrame)
88 self.
cancelButton.objectName = self.__class__.__name__ +
'Cancel' 89 self.
cancelButton.setToolTip(
"Clear preview and cancel auto-complete")
92 self.
applyButton.objectName = self.__class__.__name__ +
'Apply' 93 self.
applyButton.setToolTip(
"Replace segments by previewed result")
95 finishFrame = qt.QHBoxLayout()
108 return slicer.util.mainWindow().cursor
118 import vtkSegmentationCorePython
as vtkSegmentationCore
119 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
120 segmentation = segmentationNode.GetSegmentation()
125 segment = segmentation.GetSegment(segmentID)
128 logging.debug(
"Segmentation cancelled because an input segment was deleted")
131 segmentLabelmap = segment.GetRepresentation(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName())
143 logging.debug(
"Segmentation update requested")
149 import vtkSegmentationCorePython
as vtkSegmentationCore
150 segmentation = self.
scriptedEffect.parameterSetNode().GetSegmentationNode().GetSegmentation()
163 if observationEnabled
and segmentation
is not None:
166 vtkSegmentationCore.vtkSegmentation.SegmentAdded,
167 vtkSegmentationCore.vtkSegmentation.SegmentRemoved,
168 vtkSegmentationCore.vtkSegmentation.SegmentModified,
169 vtkSegmentationCore.vtkSegmentation.MasterRepresentationModified ]
170 for eventId
in observedEvents:
174 previewNode = self.
scriptedEffect.parameterSetNode().GetNodeReference(ResultPreviewNodeReferenceRole)
185 self.
applyButton.setEnabled(previewNode
is not None)
201 autoUpdate = qt.Qt.Unchecked
if self.
scriptedEffect.integerParameter(
"AutoUpdate") == 0
else qt.Qt.Checked
207 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
216 slicer.util.showStatusMessage(
"Running {0} auto-complete...".format(self.
scriptedEffect.name), 2000)
219 qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)
222 qt.QApplication.restoreOverrideCursor()
227 previewNode = self.
scriptedEffect.parameterSetNode().GetNodeReference(ResultPreviewNodeReferenceRole)
229 self.
scriptedEffect.parameterSetNode().SetNodeReferenceID(ResultPreviewNodeReferenceRole,
None)
230 slicer.mrmlScene.RemoveNode(previewNode)
231 self.
scriptedEffect.setCommonParameter(
"SegmentationResultPreviewOwnerEffect",
"")
232 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
233 segmentationNode.GetDisplayNode().SetOpacity(1.0)
247 import vtkSegmentationCorePython
as vtkSegmentationCore
248 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
254 segmentIDs = vtk.vtkStringArray()
255 previewNode.GetSegmentation().GetSegmentIDs(segmentIDs)
256 for index
in xrange(segmentIDs.GetNumberOfValues()):
257 segmentID = segmentIDs.GetValue(index)
258 previewSegment = previewNode.GetSegmentation().GetSegment(segmentID)
259 previewSegmentLabelmap = previewSegment.GetRepresentation(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName())
260 slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(previewSegmentLabelmap, segmentationNode, segmentID)
261 previewNode.GetSegmentation().RemoveSegment(segmentID)
266 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
267 segmentationNode.GetDisplayNode().SetOpacity(1.0-opacity)
270 previewNode.GetDisplayNode().SetOpacity(opacity)
279 return previewNode.GetDisplayNode().GetOpacity()
if previewNode
else 0.6
283 import vtkSegmentationCorePython
as vtkSegmentationCore
287 segmentationNode = self.
scriptedEffect.parameterSetNode().GetSegmentationNode()
297 logging.error(
"Auto-complete operation skipped: at least {0} visible segments are required".format(self.
minimumNumberOfSegments))
301 commonGeometryString = segmentationNode.GetSegmentation().DetermineCommonLabelmapGeometry(
302 vtkSegmentationCore.vtkSegmentation.EXTENT_UNION_OF_EFFECTIVE_SEGMENTS, self.
selectedSegmentIds)
303 if not commonGeometryString:
304 logging.info(
"Auto-complete operation skipped: all visible segments are empty")
308 masterImageExtent = masterImageData.GetExtent()
310 margin = [17, 17, 17]
311 labelsExpandedExtent = [
312 max(masterImageExtent[0], labelsEffectiveExtent[0]-margin[0]),
313 min(masterImageExtent[1], labelsEffectiveExtent[1]+margin[0]),
314 max(masterImageExtent[2], labelsEffectiveExtent[2]-margin[1]),
315 min(masterImageExtent[3], labelsEffectiveExtent[3]+margin[1]),
316 max(masterImageExtent[4], labelsEffectiveExtent[4]-margin[2]),
317 min(masterImageExtent[5], labelsEffectiveExtent[5]+margin[2]) ]
320 previewNode = slicer.mrmlScene.CreateNodeByClass(
'vtkMRMLSegmentationNode')
321 previewNode.UnRegister(
None)
322 previewNode = slicer.mrmlScene.AddNode(previewNode)
323 previewNode.CreateDefaultDisplayNodes()
324 previewNode.GetDisplayNode().SetVisibility2DOutline(
False)
325 if segmentationNode.GetParentTransformNode():
326 previewNode.SetAndObserveTransformNodeID(segmentationNode.GetParentTransformNode().GetID())
327 self.
scriptedEffect.parameterSetNode().SetNodeReferenceID(ResultPreviewNodeReferenceRole, previewNode.GetID())
333 masterImageClipper = vtk.vtkImageConstantPad()
334 masterImageClipper.SetInputData(masterImageData)
336 masterImageClipper.Update()
340 previewNode.SetName(segmentationNode.GetName()+
" preview")
342 mergedImage = vtkSegmentationCore.vtkOrientedImageData()
343 segmentationNode.GenerateMergedLabelmapForAllSegments(mergedImage,
346 outputLabelmap = vtkSegmentationCore.vtkOrientedImageData()
348 self.computePreviewLabelmap(mergedImage, outputLabelmap)
353 segment = segmentationNode.GetSegmentation().GetSegment(segmentID)
357 thresh = vtk.vtkImageThreshold()
359 thresh.ReplaceOutOn()
361 thresh.SetOutValue(0)
362 labelValue = index + 1
363 thresh.ThresholdBetween(labelValue, labelValue);
364 thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
365 thresh.SetInputData(outputLabelmap)
369 newSegmentLabelmap = vtkSegmentationCore.vtkOrientedImageData()
370 newSegmentLabelmap.ShallowCopy(thresh.GetOutput())
371 newSegmentLabelmap.CopyDirections(mergedImage)
372 newSegment = previewNode.GetSegmentation().GetSegment(segmentID)
374 newSegment = vtkSegmentationCore.vtkSegment()
375 newSegment.SetName(segment.GetName())
376 color = segmentationNode.GetSegmentation().GetSegment(segmentID).GetColor()
377 newSegment.SetColor(color)
378 previewNode.GetSegmentation().AddSegment(newSegment, segmentID)
379 slicer.vtkSlicerSegmentationsModuleLogic.SetBinaryLabelmapToSegment(newSegmentLabelmap, previewNode, segmentID)
383 ResultPreviewNodeReferenceRole =
"SegmentationResultPreview"
def updateGUIFromMRML(self)
segmentationNodeObserverTags
def getPreviewOpacity(self)
def updateMRMLFromGUI(self)
def __del__(self, scriptedEffect)
def setMRMLDefaults(self)
selectedSegmentModifiedTimes
def observeSegmentation(self, observationEnabled)
def __init__(self, scriptedEffect)
mergedLabelmapGeometryImage
def setupOptionsFrame(self)
clippedMasterImageDataRequired
def createCursor(self, widget)
def setPreviewOpacity(self, opacity)
def onSegmentationModified(self, caller, event)