Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
ErodeEffect.py
Go to the documentation of this file.
00001 import os
00002 from __main__ import vtk
00003 from __main__ import ctk
00004 from __main__ import qt
00005 from __main__ import slicer
00006 from EditOptions import EditOptions
00007 from EditorLib import EditorLib
00008 import Effect
00009 import MorphologyEffect
00010 
00011 
00012 #########################################################
00013 #
00014 # 
00015 comment = """
00016 
00017   ErodeEffect is a subclass of MorphologyEffect
00018   to erode a layer of pixels from a labelmap
00019 
00020 # TODO : 
00021 """
00022 #
00023 #########################################################
00024 
00025 #
00026 # ErodeEffectOptions - see Effect for superclasses
00027 #
00028 
00029 class ErodeEffectOptions(MorphologyEffect.MorphologyEffectOptions):
00030   """ ErodeEffect-specfic gui
00031   """
00032 
00033   def __init__(self, parent=0):
00034     super(ErodeEffectOptions,self).__init__(parent)
00035 
00036   def __del__(self):
00037     super(ErodeEffectOptions,self).__del__()
00038 
00039   def create(self):
00040     super(ErodeEffectOptions,self).create()
00041     self.apply = qt.QPushButton("Apply", self.frame)
00042     self.apply.setToolTip("Erode current label")
00043     self.frame.layout().addWidget(self.apply)
00044     self.widgets.append(self.apply)
00045 
00046     EditorLib.HelpButton(self.frame, "Use this tool to remove pixels from the boundary of the current label.")
00047 
00048     self.connections.append( (self.apply, 'clicked()', self.onApply) )
00049 
00050     # Add vertical spacer
00051     self.frame.layout().addStretch(1)
00052 
00053   def destroy(self):
00054     super(ErodeEffectOptions,self).destroy()
00055 
00056   def onApply(self):
00057     logic = ErodeEffectLogic(self.editUtil.getSliceLogic())
00058     logic.undoRedo = self.undoRedo
00059     fill = int(self.parameterNode.GetParameter('MorphologyEffect,fill'))
00060     neighborMode = self.parameterNode.GetParameter('MorphologyEffect,neighborMode')
00061     iterations = int(self.parameterNode.GetParameter('MorphologyEffect,iterations'))
00062     logic.erode(fill,neighborMode,iterations)
00063 
00064   # note: this method needs to be implemented exactly as-is
00065   # in each leaf subclass so that "self" in the observer
00066   # is of the correct type 
00067   def updateParameterNode(self, caller, event):
00068     node = self.editUtil.getParameterNode()
00069     if node != self.parameterNode:
00070       if self.parameterNode:
00071         node.RemoveObserver(self.parameterNodeTag)
00072       self.parameterNode = node
00073       self.parameterNodeTag = node.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
00074 
00075   def setMRMLDefaults(self):
00076     super(ErodeEffectOptions,self).setMRMLDefaults()
00077 
00078   def updateGUIFromMRML(self,caller,event):
00079     super(ErodeEffectOptions,self).updateGUIFromMRML(caller,event)
00080 
00081   def updateMRMLFromGUI(self):
00082     disableState = self.parameterNode.GetDisableModifiedEvent()
00083     self.parameterNode.SetDisableModifiedEvent(1)
00084     super(ErodeEffectOptions,self).updateMRMLFromGUI()
00085     self.parameterNode.SetDisableModifiedEvent(disableState)
00086     if not disableState:
00087       self.parameterNode.InvokePendingModifiedEvent()
00088 
00089 #
00090 # ErodeEffectTool
00091 #
00092  
00093 class ErodeEffectTool(MorphologyEffect.MorphologyEffectTool):
00094   """
00095   One instance of this will be created per-view when the effect
00096   is selected.  It is responsible for implementing feedback and
00097   label map changes in response to user input.
00098   This class observes the editor parameter node to configure itself
00099   and queries the current view for background and label volume
00100   nodes to operate on.
00101   """
00102 
00103   def __init__(self, sliceWidget):
00104     super(ErodeEffectTool,self).__init__(sliceWidget)
00105 
00106   def cleanup(self):
00107     """
00108     call superclass to clean up actors
00109     """
00110     super(ErodeEffectTool,self).cleanup()
00111 
00112 #
00113 # ErodeEffectLogic
00114 #
00115  
00116 class ErodeEffectLogic(MorphologyEffect.MorphologyEffectLogic):
00117   """
00118   This class contains helper methods for a given effect
00119   type.  It can be instanced as needed by an ErodeEffectTool
00120   or ErodeEffectOptions instance in order to compute intermediate
00121   results (say, for user feedback) or to implement the final 
00122   segmentation editing operation.  This class is split
00123   from the ErodeEffectTool so that the operations can be used
00124   by other code without the need for a view context.
00125   """
00126 
00127   def __init__(self,sliceLogic):
00128     super(ErodeEffectLogic,self).__init__(sliceLogic)
00129 
00130   def erode(self,fill,neighborMode,iterations):
00131 
00132     eroder = slicer.vtkImageErode()
00133     eroder.SetInput( self.getScopedLabelInput() )
00134     eroder.SetOutput( self.getScopedLabelOutput() )
00135 
00136     eroder.SetForeground( self.editUtil.getLabel() )
00137     eroder.SetBackground( fill )
00138 
00139     if neighborMode == '8':
00140       eroder.SetNeighborTo8()
00141     elif neighborMode == '4':
00142       eroder.SetNeighborTo4()
00143     else:
00144       # TODO: error feedback from effect logic?
00145       # bad neighbor mode - silently use default
00146       print('Bad neighborMode: %s' % neighborMode)
00147 
00148     for i in xrange(iterations):
00149       # TODO: $this setProgressFilter eroder "Erode ($i)"
00150       print('updating')
00151       eroder.Update()
00152 
00153     self.applyScopedLabel()
00154     eroder.SetOutput( None )
00155 
00156 
00157 
00158 #
00159 # The ErodeEffect class definition 
00160 #
00161 
00162 class ErodeEffect(MorphologyEffect.MorphologyEffect):
00163   """Organizes the Options, Tool, and Logic classes into a single instance
00164   that can be managed by the EditBox
00165   """
00166 
00167   def __init__(self):
00168     # name is used to define the name of the icon image resource (e.g. ErodeEffect.png)
00169     self.name = "ErodeEffect"
00170     # tool tip is displayed on mouse hover
00171     self.toolTip = "Erode: remove boundary pixel layers for labelmap editing"
00172 
00173     self.options = ErodeEffectOptions
00174     self.tool = ErodeEffectTool
00175     self.logic = ErodeEffectLogic
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines