2 import vtk, qt, ctk, slicer
4 from SegmentEditorEffects
import *
7 """ ThresholdEffect is an Effect implementing the global threshold 8 operation in the segment editor 10 This is also an example for scripted effects, and some methods have no 11 function. The methods that are not needed (i.e. the default implementation in 12 qSlicerSegmentEditorAbstractEffect is satisfactory) can simply be omitted. 16 AbstractScriptedSegmentEditorEffect.__init__(self, scriptedEffect)
17 scriptedEffect.name =
'Threshold' 30 import qSlicerSegmentationsEditorEffectsPythonQt
as effects
31 clonedEffect = effects.qSlicerSegmentEditorScriptedEffect(
None)
32 clonedEffect.setPythonSource(__file__.replace(
'\\',
'/'))
36 iconPath = os.path.join(os.path.dirname(__file__),
'Resources/Icons/Threshold.png')
37 if os.path.exists(iconPath):
38 return qt.QIcon(iconPath)
42 return """<html>Fill segment based on master volume intensity range<br>. Options:<p> 43 <ul style="margin: 0"> 44 <li><b>Use for masking:</b> set the selected intensity range as <dfn>Editable intensity range</dfn> and switch to Paint effect.</li> 45 <li><b>Apply:</b> set the previewed segmentation in the selected segment. Previous contents of the segment is overwritten.</li> 50 segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
51 segmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
52 displayNode = segmentationNode.GetDisplayNode()
53 if displayNode
is not None:
56 displayNode.SetSegmentOpacity2DFill(segmentID, 0)
57 displayNode.SetSegmentOpacity2DOutline(segmentID, 0)
68 segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
69 segmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
70 displayNode = segmentationNode.GetDisplayNode()
71 if (displayNode
is not None)
and (segmentID
is not None):
81 self.
thresholdSliderLabel.setToolTip(
"Set the range of the background values that should be labeled.")
90 self.
useForPaintButton.setToolTip(
"Use specified intensity range for masking and switch to Paint effect.")
94 self.
applyButton.objectName = self.__class__.__name__ +
'Apply' 95 self.
applyButton.setToolTip(
"Fill selected segment in regions that are in the specified intensity range.")
96 self.scriptedEffect.addOptionsWidget(self.
applyButton)
104 return slicer.util.mainWindow().cursor
108 import vtkSegmentationCorePython
as vtkSegmentationCore
109 masterImageData = self.scriptedEffect.masterVolumeImageData()
111 lo, hi = masterImageData.GetScalarRange()
114 if (self.scriptedEffect.doubleParameter(
"MinimumThreshold") == self.scriptedEffect.doubleParameter(
"MaximumThreshold")):
116 self.scriptedEffect.setParameter(
"MinimumThreshold", lo+(hi-lo)*0.25)
117 self.scriptedEffect.setParameter(
"MaximumThreshold", hi)
129 self.scriptedEffect.setParameterDefault(
"MinimumThreshold", 0.)
130 self.scriptedEffect.setParameterDefault(
"MaximumThreshold", 0)
134 self.
thresholdSlider.setMinimumValue(self.scriptedEffect.doubleParameter(
"MinimumThreshold"))
135 self.
thresholdSlider.setMaximumValue(self.scriptedEffect.doubleParameter(
"MaximumThreshold"))
139 self.scriptedEffect.setParameter(
"MinimumThreshold", self.
thresholdSlider.minimumValue)
140 self.scriptedEffect.setParameter(
"MaximumThreshold", self.
thresholdSlider.maximumValue)
149 parameterSetNode = self.scriptedEffect.parameterSetNode()
150 parameterSetNode.MasterVolumeIntensityMaskOn()
153 self.scriptedEffect.selectEffect(
"Paint")
158 import vtkSegmentationCorePython
as vtkSegmentationCore
159 masterImageData = self.scriptedEffect.masterVolumeImageData()
161 modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()
162 originalImageToWorldMatrix = vtk.vtkMatrix4x4()
163 modifierLabelmap.GetImageToWorldMatrix(originalImageToWorldMatrix)
165 min = self.scriptedEffect.doubleParameter(
"MinimumThreshold")
166 max = self.scriptedEffect.doubleParameter(
"MaximumThreshold")
168 self.scriptedEffect.saveStateForUndo()
171 thresh = vtk.vtkImageThreshold()
172 thresh.SetInputData(masterImageData)
173 thresh.ThresholdBetween(min, max)
175 thresh.SetOutValue(0)
176 thresh.SetOutputScalarType(modifierLabelmap.GetScalarType())
178 modifierLabelmap.DeepCopy(thresh.GetOutput())
180 logging.error(
'apply: Failed to threshold master volume!')
184 self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet)
187 self.scriptedEffect.selectEffect(
"")
191 self.scriptedEffect.removeActor2D(sliceWidget, pipeline.actor)
198 layoutManager = slicer.app.layoutManager()
199 if layoutManager
is None:
203 for sliceViewName
in layoutManager.sliceViewNames():
204 sliceWidget = layoutManager.sliceWidget(sliceViewName)
205 if not self.scriptedEffect.segmentationDisplayableInView(sliceWidget.mrmlSliceNode()):
207 renderer = self.scriptedEffect.renderer(sliceWidget)
209 logging.error(
"setupPreviewDisplay: Failed to get renderer!")
217 self.scriptedEffect.addActor2D(sliceWidget, pipeline.actor)
221 min = self.scriptedEffect.doubleParameter(
"MinimumThreshold")
222 max = self.scriptedEffect.doubleParameter(
"MaximumThreshold")
225 segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
226 displayNode = segmentationNode.GetDisplayNode()
227 if displayNode
is None:
228 logging.error(
"preview: Invalid segmentation display node!")
229 color = [0.5,0.5,0.5]
230 segmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
231 r,g,b = segmentationNode.GetSegmentation().GetSegment(segmentID).GetColor()
236 pipeline.lookupTable.SetTableValue(1, r, g, b, opacity)
237 sliceLogic = sliceWidget.sliceLogic()
238 backgroundLogic = sliceLogic.GetBackgroundLayer()
239 pipeline.thresholdFilter.SetInputConnection(backgroundLogic.GetReslice().GetOutputPort())
240 pipeline.thresholdFilter.ThresholdBetween(min, max)
241 pipeline.actor.VisibilityOn()
242 sliceWidget.sliceView().scheduleRender()
254 """ Visualization objects and pipeline for each slice view for threshold preview 274 self.
dummyImage.AllocateScalars(vtk.VTK_UNSIGNED_INT, 1)
277 self.
actor.VisibilityOff()
279 self.
mapper.SetColorWindow(255)
280 self.
mapper.SetColorLevel(128)
def updateMRMLFromGUI(self)
def setMRMLDefaults(self)
def onThresholdValuesChanged(self, min, max)
def processViewNodeEvents(self, callerViewNode, eventId, viewWidget)
def setupOptionsFrame(self)
def clearPreviewDisplay(self)
def setupPreviewDisplay(self)
def __init__(self, scriptedEffect)
def masterVolumeNodeChanged(self)
def updateGUIFromMRML(self)
def createCursor(self, widget)
def processInteractionEvents(self, callerInteractor, eventId, viewWidget)