|
Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
|
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
1.7.4