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)
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())
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))
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)
230 selectedStartSegmentID = self.scriptedEffect.parameterSetNode().GetSelectedSegmentID()
231 if inputSegmentIDs.GetNumberOfValues() == 0:
232 logging.info(
"Margin operation skipped: there are no visible segments.")
235 for index
in range(inputSegmentIDs.GetNumberOfValues()):
236 segmentID = inputSegmentIDs.GetValue(index)
237 self.
showStatusMessage(f
'Processing {segmentationNode.GetSegmentation().GetSegment(segmentID).GetName()}...')
238 self.scriptedEffect.parameterSetNode().SetSelectedSegmentID(segmentID)
241 self.scriptedEffect.parameterSetNode().SetSelectedSegmentID(selectedStartSegmentID)
246 qt.QApplication.restoreOverrideCursor()