Slicer  4.10
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
SegmentEditorThresholdEffect.py
Go to the documentation of this file.
1 import os
2 import vtk, qt, ctk, slicer
3 import logging
4 from SegmentEditorEffects import *
5 
7  """ ThresholdEffect is an Effect implementing the global threshold
8  operation in the segment editor
9 
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.
13  """
14 
15  def __init__(self, scriptedEffect):
16  AbstractScriptedSegmentEditorEffect.__init__(self, scriptedEffect)
17  scriptedEffect.name = 'Threshold'
18 
21  self.previewedSegmentID = None
22 
23  # Effect-specific members
24  import vtkITK
25  self.autoThresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()
26 
27  self.timer = qt.QTimer()
28  self.previewState = 0
29  self.previewStep = 1
30  self.previewSteps = 5
31  self.timer.connect('timeout()', self.preview)
32 
33  self.previewPipelines = {}
34  self.setupPreviewDisplay()
35 
36  def clone(self):
37  import qSlicerSegmentationsEditorEffectsPythonQt as effects
38  clonedEffect = effects.qSlicerSegmentEditorScriptedEffect(None)
39  clonedEffect.setPythonSource(__file__.replace('\\','/'))
40  return clonedEffect
41 
42  def icon(self):
43  iconPath = os.path.join(os.path.dirname(__file__), 'Resources/Icons/Threshold.png')
44  if os.path.exists(iconPath):
45  return qt.QIcon(iconPath)
46  return qt.QIcon()
47 
48  def helpText(self):
49  return """<html>Fill segment based on master volume intensity range<br>. Options:<p>
50 <ul style="margin: 0">
51 <li><b>Use for masking:</b> set the selected intensity range as <dfn>Editable intensity range</dfn> and switch to Paint effect.</li>
52 <li><b>Apply:</b> set the previewed segmentation in the selected segment. Previous contents of the segment is overwritten.</li>
53 </ul><p></html>"""
54 
55  def activate(self):
57 
58  # Update intensity range
60 
61  # Setup and start preview pulse
62  self.setupPreviewDisplay()
63  self.timer.start(200)
64 
65  def deactivate(self):
67 
68  # Clear preview pipeline and stop timer
69  self.clearPreviewDisplay()
70  self.timer.stop()
71 
73  """Save current segment opacity and set it to zero
74  to temporarily hide the segment so that threshold preview
75  can be seen better.
76  It also restores opacity of previously previewed segment.
77  Call restorePreviewedSegmentTransparency() to restore original
78  opacity.
79  """
80  segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
81  if not segmentationNode:
82  return
83  displayNode = segmentationNode.GetDisplayNode()
84  if not displayNode:
85  return
86  segmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
87 
88  if segmentID == self.previewedSegmentID:
89  # already previewing the current segment
90  return
91 
92  # If an other segment was previewed before, restore that.
93  if self.previewedSegmentID:
95 
96  # Make current segment fully transparent
97  if segmentID:
98  self.segment2DFillOpacity = displayNode.GetSegmentOpacity2DFill(segmentID)
99  self.segment2DOutlineOpacity = displayNode.GetSegmentOpacity2DOutline(segmentID)
100  self.previewedSegmentID = segmentID
101  displayNode.SetSegmentOpacity2DFill(segmentID, 0)
102  displayNode.SetSegmentOpacity2DOutline(segmentID, 0)
103 
105  """Restore previewed segment's opacity that was temporarily
106  made transparen by calling setCurrentSegmentTransparent()."""
107  segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
108  if not segmentationNode:
109  return
110  displayNode = segmentationNode.GetDisplayNode()
111  if not displayNode:
112  return
113  if not self.previewedSegmentID:
114  # already previewing the current segment
115  return
116  displayNode.SetSegmentOpacity2DFill(self.previewedSegmentID, self.segment2DFillOpacity)
117  displayNode.SetSegmentOpacity2DOutline(self.previewedSegmentID, self.segment2DOutlineOpacity)
118  self.previewedSegmentID = None
119 
120  def setupOptionsFrame(self):
121  self.thresholdSliderLabel = qt.QLabel("Threshold Range:")
122  self.thresholdSliderLabel.setToolTip("Set the range of the background values that should be labeled.")
123  self.scriptedEffect.addOptionsWidget(self.thresholdSliderLabel)
124 
125  self.thresholdSlider = ctk.ctkRangeWidget()
126  self.thresholdSlider.spinBoxAlignment = qt.Qt.AlignTop
127  self.thresholdSlider.singleStep = 0.01
128  self.scriptedEffect.addOptionsWidget(self.thresholdSlider)
129 
130  self.autoThresholdModeSelectorComboBox = qt.QComboBox()
131  self.autoThresholdModeSelectorComboBox.addItem("auto->maximum", MODE_SET_LOWER_MAX)
132  self.autoThresholdModeSelectorComboBox.addItem("minimum->auto", MODE_SET_MIN_UPPER)
133  self.autoThresholdModeSelectorComboBox.addItem("as lower", MODE_SET_LOWER)
134  self.autoThresholdModeSelectorComboBox.addItem("as upper", MODE_SET_UPPER)
135  self.autoThresholdModeSelectorComboBox.setToolTip("How to set lower and upper threshold values. Current refers to keeping the current value.")
136 
138  self.autoThresholdMethodSelectorComboBox.addItem("Otsu", METHOD_OTSU)
139  self.autoThresholdMethodSelectorComboBox.addItem("Huang", METHOD_HUANG)
140  self.autoThresholdMethodSelectorComboBox.addItem("IsoData", METHOD_ISO_DATA)
141  # Kittler-Illingworth sometimes fails with an exception, but it does not cause any major issue,
142  # it just logs an error message and does not compute a new threshold value
143  self.autoThresholdMethodSelectorComboBox.addItem("Kittler-Illingworth", METHOD_KITTLER_ILLINGWORTH)
144  # Li sometimes crashes (index out of range error in
145  # ITK/Modules/Filtering/Thresholding/include/itkLiThresholdCalculator.hxx#L94)
146  # We can add this method back when issue is fixed in ITK.
147  #self.autoThresholdMethodSelectorComboBox.addItem("Li", METHOD_LI)
148  self.autoThresholdMethodSelectorComboBox.addItem("Maximum entropy", METHOD_MAXIMUM_ENTROPY)
149  self.autoThresholdMethodSelectorComboBox.addItem("Moments", METHOD_MOMENTS)
150  self.autoThresholdMethodSelectorComboBox.addItem("Renyi entropy", METHOD_RENYI_ENTROPY)
151  self.autoThresholdMethodSelectorComboBox.addItem("Shanbhag", METHOD_SHANBHAG)
152  self.autoThresholdMethodSelectorComboBox.addItem("Triangle", METHOD_TRIANGLE)
153  self.autoThresholdMethodSelectorComboBox.addItem("Yen", METHOD_YEN)
154  self.autoThresholdMethodSelectorComboBox.setToolTip("Select method to compute threshold value automatically.")
155 
156  self.selectPreviousAutoThresholdButton = qt.QToolButton()
157  self.selectPreviousAutoThresholdButton.text = "<"
158  self.selectPreviousAutoThresholdButton.setToolTip("Select previous thresholding method and set thresholds."
159  +" Useful for iterating through all available methods.")
160 
161  self.selectNextAutoThresholdButton = qt.QToolButton()
162  self.selectNextAutoThresholdButton.text = ">"
163  self.selectNextAutoThresholdButton.setToolTip("Select next thresholding method and set thresholds."
164  +" Useful for iterating through all available methods.")
165 
166  self.setAutoThresholdButton = qt.QPushButton("Set")
167  self.setAutoThresholdButton.setToolTip("Set threshold using selected method.")
168 
169  # qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
170  # fails on some systems, therefore set the policies using separate method calls
171  qSize = qt.QSizePolicy()
172  qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding)
173  self.setAutoThresholdButton.setSizePolicy(qSize)
174 
175  autoThresholdFrame = qt.QHBoxLayout()
176  autoThresholdFrame.addWidget(self.autoThresholdModeSelectorComboBox)
177  autoThresholdFrame.addWidget(self.autoThresholdMethodSelectorComboBox)
178  autoThresholdFrame.addWidget(self.selectPreviousAutoThresholdButton)
179  autoThresholdFrame.addWidget(self.selectNextAutoThresholdButton)
180  autoThresholdFrame.addWidget(self.setAutoThresholdButton)
181  self.scriptedEffect.addLabeledOptionsWidget("Automatic threshold:", autoThresholdFrame)
182 
183  self.useForPaintButton = qt.QPushButton("Use for masking")
184  self.useForPaintButton.setToolTip("Use specified intensity range for masking and switch to Paint effect.")
185  self.scriptedEffect.addOptionsWidget(self.useForPaintButton)
186 
187  self.applyButton = qt.QPushButton("Apply")
188  self.applyButton.objectName = self.__class__.__name__ + 'Apply'
189  self.applyButton.setToolTip("Fill selected segment in regions that are in the specified intensity range.")
190  self.scriptedEffect.addOptionsWidget(self.applyButton)
191 
192  self.useForPaintButton.connect('clicked()', self.onUseForPaint)
193  self.thresholdSlider.connect('valuesChanged(double,double)', self.onThresholdValuesChanged)
194  self.autoThresholdMethodSelectorComboBox.connect("activated(int)", self.onSelectedAutoThresholdMethod)
195  self.autoThresholdModeSelectorComboBox.connect("activated(int)", self.onSelectedAutoThresholdMethod)
197  self.selectNextAutoThresholdButton.connect('clicked()', self.onSelectNextAutoThresholdMethod)
198  self.setAutoThresholdButton.connect('clicked()', self.onAutoThreshold)
199  self.applyButton.connect('clicked()', self.onApply)
200 
201  def createCursor(self, widget):
202  # Turn off effect-specific cursor for this effect
203  return slicer.util.mainWindow().cursor
204 
206  # Set scalar range of master volume image data to threshold slider
207  import vtkSegmentationCorePython as vtkSegmentationCore
208  masterImageData = self.scriptedEffect.masterVolumeImageData()
209  if masterImageData:
210  lo, hi = masterImageData.GetScalarRange()
211  self.thresholdSlider.setRange(lo, hi)
212  self.thresholdSlider.singleStep = (hi - lo) / 1000.
213  if (self.scriptedEffect.doubleParameter("MinimumThreshold") == self.scriptedEffect.doubleParameter("MaximumThreshold")):
214  # has not been initialized yet
215  self.scriptedEffect.setParameter("MinimumThreshold", lo+(hi-lo)*0.25)
216  self.scriptedEffect.setParameter("MaximumThreshold", hi)
217 
218  def layoutChanged(self):
219  self.setupPreviewDisplay()
220 
221  def processInteractionEvents(self, callerInteractor, eventId, viewWidget):
222  return False # For the sake of example
223 
224  def processViewNodeEvents(self, callerViewNode, eventId, viewWidget):
225  pass # For the sake of example
226 
227  def setMRMLDefaults(self):
228  self.scriptedEffect.setParameterDefault("MinimumThreshold", 0.)
229  self.scriptedEffect.setParameterDefault("MaximumThreshold", 0)
230  self.scriptedEffect.setParameterDefault("AutoThresholdMethod", METHOD_OTSU)
231  self.scriptedEffect.setParameterDefault("AutoThresholdMode", MODE_SET_LOWER_MAX)
232 
233  def updateGUIFromMRML(self):
234  self.thresholdSlider.blockSignals(True)
235  self.thresholdSlider.setMinimumValue(self.scriptedEffect.doubleParameter("MinimumThreshold"))
236  self.thresholdSlider.setMaximumValue(self.scriptedEffect.doubleParameter("MaximumThreshold"))
237  self.thresholdSlider.blockSignals(False)
238 
239  autoThresholdMethod = self.autoThresholdMethodSelectorComboBox.findData(self.scriptedEffect.parameter("AutoThresholdMethod"))
240  wasBlocked = self.autoThresholdMethodSelectorComboBox.blockSignals(True)
241  self.autoThresholdMethodSelectorComboBox.setCurrentIndex(autoThresholdMethod)
242  self.autoThresholdMethodSelectorComboBox.blockSignals(wasBlocked)
243 
244  autoThresholdMode = self.autoThresholdModeSelectorComboBox.findData(self.scriptedEffect.parameter("AutoThresholdMode"))
245  wasBlocked = self.autoThresholdModeSelectorComboBox.blockSignals(True)
246  self.autoThresholdModeSelectorComboBox.setCurrentIndex(autoThresholdMode)
247  self.autoThresholdModeSelectorComboBox.blockSignals(wasBlocked)
248 
249  def updateMRMLFromGUI(self):
250  self.scriptedEffect.setParameter("MinimumThreshold", self.thresholdSlider.minimumValue)
251  self.scriptedEffect.setParameter("MaximumThreshold", self.thresholdSlider.maximumValue)
252 
253  methodIndex = self.autoThresholdMethodSelectorComboBox.currentIndex
254  autoThresholdMethod = self.autoThresholdMethodSelectorComboBox.itemData(methodIndex)
255  self.scriptedEffect.setParameter("AutoThresholdMethod", autoThresholdMethod)
256 
257  modeIndex = self.autoThresholdModeSelectorComboBox.currentIndex
258  autoThresholdMode = self.autoThresholdModeSelectorComboBox.itemData(modeIndex)
259  self.scriptedEffect.setParameter("AutoThresholdMode", autoThresholdMode)
260 
261  #
262  # Effect specific methods (the above ones are the API methods to override)
263  #
264  def onThresholdValuesChanged(self,min,max):
265  self.scriptedEffect.updateMRMLFromGUI()
266 
267  def onUseForPaint(self):
268  parameterSetNode = self.scriptedEffect.parameterSetNode()
269  parameterSetNode.MasterVolumeIntensityMaskOn()
270  parameterSetNode.SetMasterVolumeIntensityMaskRange(self.thresholdSlider.minimumValue, self.thresholdSlider.maximumValue)
271  # Switch to paint effect
272  self.scriptedEffect.selectEffect("Paint")
273 
275  self.autoThresholdMethodSelectorComboBox.currentIndex = (self.autoThresholdMethodSelectorComboBox.currentIndex - 1) \
278 
280  self.autoThresholdMethodSelectorComboBox.currentIndex = (self.autoThresholdMethodSelectorComboBox.currentIndex + 1) \
283 
285  self.updateMRMLFromGUI()
286  self.onAutoThreshold()
287  self.updateGUIFromMRML()
288 
289  def onAutoThreshold(self):
290  autoThresholdMethod = self.scriptedEffect.parameter("AutoThresholdMethod")
291  autoThresholdMode = self.scriptedEffect.parameter("AutoThresholdMode")
292  self.autoThreshold(autoThresholdMethod, autoThresholdMode)
293 
294  def autoThreshold(self, autoThresholdMethod, autoThresholdMode):
295  if autoThresholdMethod == METHOD_HUANG:
296  self.autoThresholdCalculator.SetMethodToHuang()
297  elif autoThresholdMethod == METHOD_INTERMODES:
298  self.autoThresholdCalculator.SetMethodToIntermodes()
299  elif autoThresholdMethod == METHOD_ISO_DATA:
300  self.autoThresholdCalculator.SetMethodToIsoData()
301  elif autoThresholdMethod == METHOD_KITTLER_ILLINGWORTH:
302  self.autoThresholdCalculator.SetMethodToKittlerIllingworth()
303  elif autoThresholdMethod == METHOD_LI:
304  self.autoThresholdCalculator.SetMethodToLi()
305  elif autoThresholdMethod == METHOD_MAXIMUM_ENTROPY:
306  self.autoThresholdCalculator.SetMethodToMaximumEntropy()
307  elif autoThresholdMethod == METHOD_MOMENTS:
308  self.autoThresholdCalculator.SetMethodToMoments()
309  elif autoThresholdMethod == METHOD_OTSU:
310  self.autoThresholdCalculator.SetMethodToOtsu()
311  elif autoThresholdMethod == METHOD_RENYI_ENTROPY:
312  self.autoThresholdCalculator.SetMethodToRenyiEntropy()
313  elif autoThresholdMethod == METHOD_SHANBHAG:
314  self.autoThresholdCalculator.SetMethodToShanbhag()
315  elif autoThresholdMethod == METHOD_TRIANGLE:
316  self.autoThresholdCalculator.SetMethodToTriangle()
317  elif autoThresholdMethod == METHOD_YEN:
318  self.autoThresholdCalculator.SetMethodToYen()
319  else:
320  logging.error("Unknown AutoThresholdMethod {0}".format(autoThresholdMethod))
321 
322  masterImageData = self.scriptedEffect.masterVolumeImageData()
323  self.autoThresholdCalculator.SetInputData(masterImageData)
324 
325  self.autoThresholdCalculator.Update()
326  computedThreshold = self.autoThresholdCalculator.GetThreshold()
327 
328  masterVolumeMin, masterVolumeMax = masterImageData.GetScalarRange()
329 
330  if autoThresholdMode == MODE_SET_UPPER:
331  self.scriptedEffect.setParameter("MaximumThreshold", computedThreshold)
332  elif autoThresholdMode == MODE_SET_LOWER:
333  self.scriptedEffect.setParameter("MinimumThreshold", computedThreshold)
334  elif autoThresholdMode == MODE_SET_MIN_UPPER:
335  self.scriptedEffect.setParameter("MinimumThreshold", masterVolumeMin)
336  self.scriptedEffect.setParameter("MaximumThreshold", computedThreshold)
337  elif autoThresholdMode == MODE_SET_LOWER_MAX:
338  self.scriptedEffect.setParameter("MinimumThreshold", computedThreshold)
339  self.scriptedEffect.setParameter("MaximumThreshold", masterVolumeMax)
340  else:
341  logging.error("Unknown AutoThresholdMode {0}".format(autoThresholdMode))
342 
343  def onApply(self):
344  try:
345  # Get master volume image data
346  import vtkSegmentationCorePython as vtkSegmentationCore
347  masterImageData = self.scriptedEffect.masterVolumeImageData()
348  # Get modifier labelmap
349  modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()
350  originalImageToWorldMatrix = vtk.vtkMatrix4x4()
351  modifierLabelmap.GetImageToWorldMatrix(originalImageToWorldMatrix)
352  # Get parameters
353  min = self.scriptedEffect.doubleParameter("MinimumThreshold")
354  max = self.scriptedEffect.doubleParameter("MaximumThreshold")
355 
356  self.scriptedEffect.saveStateForUndo()
357 
358  # Perform thresholding
359  thresh = vtk.vtkImageThreshold()
360  thresh.SetInputData(masterImageData)
361  thresh.ThresholdBetween(min, max)
362  thresh.SetInValue(1)
363  thresh.SetOutValue(0)
364  thresh.SetOutputScalarType(modifierLabelmap.GetScalarType())
365  thresh.Update()
366  modifierLabelmap.DeepCopy(thresh.GetOutput())
367  except IndexError:
368  logging.error('apply: Failed to threshold master volume!')
369  pass
370 
371  # Apply changes
372  self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet)
373 
374  # De-select effect
375  self.scriptedEffect.selectEffect("")
376 
378  for sliceWidget, pipeline in self.previewPipelines.iteritems():
379  self.scriptedEffect.removeActor2D(sliceWidget, pipeline.actor)
380  self.previewPipelines = {}
381 
383  # Clear previous pipelines before setting up the new ones
384  self.clearPreviewDisplay()
385 
386  layoutManager = slicer.app.layoutManager()
387  if layoutManager is None:
388  return
389 
390  # Add a pipeline for each 2D slice view
391  for sliceViewName in layoutManager.sliceViewNames():
392  sliceWidget = layoutManager.sliceWidget(sliceViewName)
393  if not self.scriptedEffect.segmentationDisplayableInView(sliceWidget.mrmlSliceNode()):
394  continue
395  renderer = self.scriptedEffect.renderer(sliceWidget)
396  if renderer is None:
397  logging.error("setupPreviewDisplay: Failed to get renderer!")
398  continue
399 
400  # Create pipeline
401  pipeline = PreviewPipeline()
402  self.previewPipelines[sliceWidget] = pipeline
403 
404  # Add actor
405  self.scriptedEffect.addActor2D(sliceWidget, pipeline.actor)
406 
407  def preview(self):
408 
409  opacity = 0.5 + self.previewState / (2. * self.previewSteps)
410  min = self.scriptedEffect.doubleParameter("MinimumThreshold")
411  max = self.scriptedEffect.doubleParameter("MaximumThreshold")
412 
413  # Get color of edited segment
414  segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
415  if not segmentationNode:
416  # scene was closed while preview was active
417  return
418  displayNode = segmentationNode.GetDisplayNode()
419  if displayNode is None:
420  logging.error("preview: Invalid segmentation display node!")
421  color = [0.5,0.5,0.5]
422  segmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
423 
424  # Make sure we keep the currently selected segment hidden (the user may have changed selection)
425  if segmentID != self.previewedSegmentID:
427 
428  r,g,b = segmentationNode.GetSegmentation().GetSegment(segmentID).GetColor()
429 
430  # Set values to pipelines
431  for sliceWidget in self.previewPipelines:
432  pipeline = self.previewPipelines[sliceWidget]
433  pipeline.lookupTable.SetTableValue(1, r, g, b, opacity)
434  sliceLogic = sliceWidget.sliceLogic()
435  backgroundLogic = sliceLogic.GetBackgroundLayer()
436  pipeline.thresholdFilter.SetInputConnection(backgroundLogic.GetReslice().GetOutputPort())
437  pipeline.thresholdFilter.ThresholdBetween(min, max)
438  pipeline.actor.VisibilityOn()
439  sliceWidget.sliceView().scheduleRender()
440 
441  self.previewState += self.previewStep
442  if self.previewState >= self.previewSteps:
443  self.previewStep = -1
444  if self.previewState <= 0:
445  self.previewStep = 1
446 
447 #
448 # PreviewPipeline
449 #
451  """ Visualization objects and pipeline for each slice view for threshold preview
452  """
453 
454  def __init__(self):
455  self.lookupTable = vtk.vtkLookupTable()
456  self.lookupTable.SetRampToLinear()
457  self.lookupTable.SetNumberOfTableValues(2)
458  self.lookupTable.SetTableRange(0, 1)
459  self.lookupTable.SetTableValue(0, 0, 0, 0, 0)
460  self.colorMapper = vtk.vtkImageMapToRGBA()
461  self.colorMapper.SetOutputFormatToRGBA()
462  self.colorMapper.SetLookupTable(self.lookupTable)
463  self.thresholdFilter = vtk.vtkImageThreshold()
464  self.thresholdFilter.SetInValue(1)
465  self.thresholdFilter.SetOutValue(0)
466  self.thresholdFilter.SetOutputScalarTypeToUnsignedChar()
467 
468  # Feedback actor
469  self.mapper = vtk.vtkImageMapper()
470  self.dummyImage = vtk.vtkImageData()
471  self.dummyImage.AllocateScalars(vtk.VTK_UNSIGNED_INT, 1)
472  self.mapper.SetInputData(self.dummyImage)
473  self.actor = vtk.vtkActor2D()
474  self.actor.VisibilityOff()
475  self.actor.SetMapper(self.mapper)
476  self.mapper.SetColorWindow(255)
477  self.mapper.SetColorLevel(128)
478 
479  # Setup pipeline
480  self.colorMapper.SetInputConnection(self.thresholdFilter.GetOutputPort())
481  self.mapper.SetInputConnection(self.colorMapper.GetOutputPort())
482 
483 
484 
485 METHOD_HUANG = 'HUANG'
486 METHOD_INTERMODES = 'INTERMODES'
487 METHOD_ISO_DATA = 'ISO_DATA'
488 METHOD_KITTLER_ILLINGWORTH = 'KITTLER_ILLINGWORTH'
489 METHOD_LI = 'LI'
490 METHOD_MAXIMUM_ENTROPY = 'MAXIMUM_ENTROPY'
491 METHOD_MOMENTS = 'MOMENTS'
492 METHOD_OTSU = 'OTSU'
493 METHOD_RENYI_ENTROPY = 'RENYI_ENTROPY'
494 METHOD_SHANBHAG = 'SHANBHAG'
495 METHOD_TRIANGLE = 'TRIANGLE'
496 METHOD_YEN = 'YEN'
497 
498 MODE_SET_UPPER = 'SET_UPPER'
499 MODE_SET_LOWER = 'SET_LOWER'
500 MODE_SET_MIN_UPPER = 'SET_MIN_UPPER'
501 MODE_SET_LOWER_MAX = 'SET_LOWER_MAX'
def processViewNodeEvents(self, callerViewNode, eventId, viewWidget)
def autoThreshold(self, autoThresholdMethod, autoThresholdMode)
def processInteractionEvents(self, callerInteractor, eventId, viewWidget)