10 from SegmentEditorEffects
import *
14 """ MaringEffect grows or shrinks the segment by a specified margin 18 scriptedEffect.name =
'Margin' 19 AbstractScriptedSegmentEditorEffect.__init__(self, scriptedEffect)
22 import qSlicerSegmentationsEditorEffectsPythonQt
as effects
23 clonedEffect = effects.qSlicerSegmentEditorScriptedEffect(
None)
24 clonedEffect.setPythonSource(__file__.replace(
'\\',
'/'))
28 iconPath = os.path.join(os.path.dirname(__file__),
'Resources/Icons/Margin.png')
29 if os.path.exists(iconPath):
30 return qt.QIcon(iconPath)
34 return "Grow or shrink selected segment by specified margin size." 38 operationLayout = qt.QVBoxLayout()
46 self.scriptedEffect.addLabeledOptionsWidget(
"Operation:", operationLayout)
50 self.
marginSizeMMSpinBox.setToolTip(
"Segment boundaries will be shifted by this distance. Positive value means the segments will grow, negative value means segment will shrink.")
56 self.
marginSizeLabel.setToolTip(
"Size change in pixel. Computed from the segment's spacing and the specified margin size.")
58 marginSizeFrame = qt.QHBoxLayout()
60 self.
marginSizeMMLabel = self.scriptedEffect.addLabeledOptionsWidget(
"Margin size:", marginSizeFrame)
65 This operation may take a while.")
70 self.
applyButton.objectName = self.__class__.__name__ +
'Apply' 71 self.
applyButton.setToolTip(
"Grows or shrinks selected segment /default) or all segments (checkbox) by the specified margin.")
72 self.scriptedEffect.addOptionsWidget(self.
applyButton)
82 return slicer.util.mainWindow().cursor
85 self.scriptedEffect.setParameterDefault(
"ApplyToAllVisibleSegments", 0)
86 self.scriptedEffect.setParameterDefault(
"MarginSizeMm", 3)
89 selectedSegmentLabelmapSpacing = [1.0, 1.0, 1.0]
90 selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()
91 if selectedSegmentLabelmap:
92 selectedSegmentLabelmapSpacing = selectedSegmentLabelmap.GetSpacing()
94 marginSizeMM = abs(self.scriptedEffect.doubleParameter(
"MarginSizeMm"))
95 marginSizePixel = [int(math.floor(marginSizeMM / spacing))
for spacing
in selectedSegmentLabelmapSpacing]
96 return marginSizePixel
99 marginSizeMM = self.scriptedEffect.doubleParameter(
"MarginSizeMm")
112 selectedSegmentLabelmapSpacing = [1.0, 1.0, 1.0]
113 selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()
114 if selectedSegmentLabelmap:
115 selectedSegmentLabelmapSpacing = selectedSegmentLabelmap.GetSpacing()
117 if marginSizePixel[0] < 1
or marginSizePixel[1] < 1
or marginSizePixel[2] < 1:
122 self.
marginSizeLabel.text =
"Actual: {} x {} x {} mm ({}x{}x{} pixel)".format(*marginSizeMM, *marginSizePixel)
127 applyToAllVisibleSegments = qt.Qt.Unchecked
if self.scriptedEffect.integerParameter(
"ApplyToAllVisibleSegments") == 0
else qt.Qt.Checked
132 self.setWidgetMinMaxStepFromImageSpacing(self.
marginSizeMMSpinBox, self.scriptedEffect.selectedSegmentLabelmap())
144 self.scriptedEffect.setParameter(
"MarginSizeMm", marginSizeMM)
146 self.scriptedEffect.setParameter(
"ApplyToAllVisibleSegments", applyToAllVisibleSegments)
149 selectedSegmentLabelmapSpacing = [1.0, 1.0, 1.0]
150 selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()
151 if selectedSegmentLabelmap:
152 selectedSegmentLabelmapSpacing = selectedSegmentLabelmap.GetSpacing()
155 marginSizeMM = [abs((marginSizePixel[i]) * selectedSegmentLabelmapSpacing[i])
for i
in range(3)]
157 if marginSizeMM[i] > 0:
158 marginSizeMM[i] = round(marginSizeMM[i], max(int(-math.floor(math.log10(marginSizeMM[i]))), 1))
162 slicer.util.showStatusMessage(msg, timeoutMsec)
163 slicer.app.processEvents()
167 modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()
168 selectedSegmentLabelmap = self.scriptedEffect.selectedSegmentLabelmap()
170 marginSizeMM = self.scriptedEffect.doubleParameter(
"MarginSizeMm")
175 thresh = vtk.vtkImageThreshold()
176 thresh.SetInputData(selectedSegmentLabelmap)
177 thresh.ThresholdByLower(0)
178 thresh.SetInValue(backgroundValue)
179 thresh.SetOutValue(labelValue)
180 thresh.SetOutputScalarType(selectedSegmentLabelmap.GetScalarType())
181 if (marginSizeMM < 0):
185 thresh.SetInValue(labelValue)
186 thresh.SetOutValue(backgroundValue)
189 margin = vtkITK.vtkITKImageMargin()
190 margin.SetInputConnection(thresh.GetOutputPort())
191 margin.CalculateMarginInMMOn()
192 margin.SetOuterMarginMM(abs(marginSizeMM))
195 if marginSizeMM >= 0:
196 modifierLabelmap.ShallowCopy(margin.GetOutput())
199 thresh = vtk.vtkImageThreshold()
200 thresh.SetInputData(margin.GetOutput())
201 thresh.ThresholdByLower(0)
202 thresh.SetInValue(labelValue)
203 thresh.SetOutValue(backgroundValue)
204 thresh.SetOutputScalarType(selectedSegmentLabelmap.GetScalarType())
206 modifierLabelmap.ShallowCopy(thresh.GetOutput())
209 self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeSet)
213 if not self.scriptedEffect.confirmCurrentSegmentVisible():
218 qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)
219 self.scriptedEffect.saveStateForUndo()
221 applyToAllVisibleSegments = int(self.scriptedEffect.parameter(
"ApplyToAllVisibleSegments")) != 0 \
222 if self.scriptedEffect.parameter(
"ApplyToAllVisibleSegments")
else False 224 if applyToAllVisibleSegments:
226 inputSegmentIDs = vtk.vtkStringArray()
227 segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
228 segmentationNode.GetDisplayNode().GetVisibleSegmentIDs(inputSegmentIDs)
229 segmentEditorWidget = slicer.modules.segmenteditor.widgetRepresentation().self().editor
230 segmentEditorNode = segmentEditorWidget.mrmlSegmentEditorNode()
232 selectedStartSegmentID = segmentEditorNode.GetSelectedSegmentID()
233 if inputSegmentIDs.GetNumberOfValues() == 0:
234 logging.info(
"Margin operation skipped: there are no visible segments.")
237 for index
in range(inputSegmentIDs.GetNumberOfValues()):
238 segmentID = inputSegmentIDs.GetValue(index)
239 self.
showStatusMessage(f
'Processing {segmentationNode.GetSegmentation().GetSegment(segmentID).GetName()}...')
240 segmentEditorNode.SetSelectedSegmentID(segmentID)
243 segmentEditorNode.SetSelectedSegmentID(selectedStartSegmentID)
248 qt.QApplication.restoreOverrideCursor()
def setupOptionsFrame(self)
applyToAllVisibleSegmentsCheckBox
def growOperationToggled(self, toggled)
def createCursor(self, widget)
def __init__(self, scriptedEffect)
def shrinkOperationToggled(self, toggled)
applyToAllVisibleSegmentsLabel
def getMarginSizePixel(self)
def setMRMLDefaults(self)
def showStatusMessage(self, msg, timeoutMsec=500)
def updateMRMLFromGUI(self)
def updateGUIFromMRML(self)
def getMarginSizeMM(self)