def setupOptionsFrame(self): self.methodSelectorComboBox = qt.QComboBox() self.methodSelectorComboBox.addItem("Median", MEDIAN) self.methodSelectorComboBox.addItem("Opening (remove extrusions)", MORPHOLOGICAL_OPENING) self.methodSelectorComboBox.addItem("Closing (fill holes)", MORPHOLOGICAL_CLOSING) self.methodSelectorComboBox.addItem("Gaussian", GAUSSIAN) self.methodSelectorComboBox.setToolTip( '<html>Smoothing methods:<ul style="margin: 0"><li><b>Median:</b> removes small details while keeps smooth contours mostly unchanged.</li><li><b>Opening:</b> removes extrusions smaller than the specified kernel size.</li><li><b>Closing:</b> fills sharp corners and holes smaller than the specified kernel size.</li><li><b>Gaussian:</b> smoothes all contours, tends to shrink the segment.</li></ul></html>' ) self.scriptedEffect.addLabeledOptionsWidget( "Smoothing method:", self.methodSelectorComboBox) self.kernelSizeMmSpinBox = slicer.qMRMLSpinBox() self.kernelSizeMmSpinBox.setMRMLScene(slicer.mrmlScene) self.kernelSizeMmSpinBox.setToolTip( "Diameter of the neighborhood that will be considered around each voxel. Higher value makes smoothing stronger (more details are suppressed)." ) self.kernelSizeMmSpinBox.quantity = "length" self.kernelSizeMmSpinBox.unitAwareProperties &= ~slicer.qMRMLSpinBox.MinimumValue # disable setting deafult minimum value (it would be a large negative value) self.kernelSizeMmSpinBox.minimum = 0.0 self.kernelSizeMmSpinBox.value = 3.0 self.kernelSizeMmSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip( "Diameter of the neighborhood in pixels. Computed from the segment's spacing and the specified kernel size." ) kernelSizeFrame = qt.QHBoxLayout() kernelSizeFrame.addWidget(self.kernelSizePixel) kernelSizeFrame.addWidget(self.kernelSizeMmSpinBox) self.kernelSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget( "Kernel size:", kernelSizeFrame) self.gaussianStandardDeviationMmSpinBox = slicer.qMRMLSpinBox() self.gaussianStandardDeviationMmSpinBox.setMRMLScene(slicer.mrmlScene) self.gaussianStandardDeviationMmSpinBox.setToolTip( "Standard deviation of the Gaussian smoothing filter coefficients. Higher value makes smoothing stronger (more details are suppressed)." ) self.gaussianStandardDeviationMmSpinBox.quantity = "length" self.gaussianStandardDeviationMmSpinBox.value = 3.0 self.gaussianStandardDeviationMmSpinBox.singleStep = 1.0 self.gaussianStandardDeviationMmLabel = self.scriptedEffect.addLabeledOptionsWidget( "Standard deviation:", self.gaussianStandardDeviationMmSpinBox) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Apply smoothing to selected segment") self.scriptedEffect.addOptionsWidget(self.applyButton) self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI) self.kernelSizeMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.gaussianStandardDeviationMmSpinBox.connect( "valueChanged(double)", self.updateMRMLFromGUI) self.applyButton.connect('clicked()', self.onApply)
def setupOptionsFrame(self): self.methodSelectorComboBox = qt.QComboBox() self.methodSelectorComboBox.addItem("Median", MEDIAN) self.methodSelectorComboBox.addItem("Opening (remove extrusions)", MORPHOLOGICAL_OPENING) self.methodSelectorComboBox.addItem("Closing (fill holes)", MORPHOLOGICAL_CLOSING) self.methodSelectorComboBox.addItem("Gaussian", GAUSSIAN) self.methodSelectorComboBox.setToolTip( '<html>Smoothing methods:<ul style="margin: 0"><li><b>Median:</b> removes small details while keeps smooth contours mostly unchanged.</li><li><b>Opening:</b> removes extrusions smaller than the specified kernel size.</li><li><b>Closing:</b> fills sharp corners and holes smaller than the specified kernel size.</li><li><b>Gaussian:</b> smoothes all contours, tends to shrink the segment.</li></ul></html>' ) self.scriptedEffect.addLabeledOptionsWidget("Smoothing method:", self.methodSelectorComboBox) self.kernelSizeMmSpinBox = slicer.qMRMLSpinBox() self.kernelSizeMmSpinBox.setMRMLScene(slicer.mrmlScene) self.kernelSizeMmSpinBox.setToolTip( "Diameter of the neighborhood that will be considered around each voxel. Higher value makes smoothing stronger (more details are suppressed)." ) self.kernelSizeMmSpinBox.quantity = "length" self.kernelSizeMmSpinBox.unitAwareProperties &= ( ~slicer.qMRMLSpinBox.MinimumValue ) # disable setting deafult minimum value (it would be a large negative value) self.kernelSizeMmSpinBox.minimum = 0.0 self.kernelSizeMmSpinBox.value = 3.0 self.kernelSizeMmSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip( "Diameter of the neighborhood in pixels. Computed from the segment's spacing and the specified kernel size." ) kernelSizeFrame = qt.QHBoxLayout() kernelSizeFrame.addWidget(self.kernelSizePixel) kernelSizeFrame.addWidget(self.kernelSizeMmSpinBox) self.kernelSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget("Kernel size:", kernelSizeFrame) self.gaussianStandardDeviationMmSpinBox = slicer.qMRMLSpinBox() self.gaussianStandardDeviationMmSpinBox.setMRMLScene(slicer.mrmlScene) self.gaussianStandardDeviationMmSpinBox.setToolTip( "Standard deviation of the Gaussian smoothing filter coefficients. Higher value makes smoothing stronger (more details are suppressed)." ) self.gaussianStandardDeviationMmSpinBox.quantity = "length" self.gaussianStandardDeviationMmSpinBox.value = 3.0 self.gaussianStandardDeviationMmSpinBox.singleStep = 1.0 self.gaussianStandardDeviationMmLabel = self.scriptedEffect.addLabeledOptionsWidget( "Standard deviation:", self.gaussianStandardDeviationMmSpinBox ) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + "Apply" self.applyButton.setToolTip("Apply smoothing to selected segment") self.scriptedEffect.addOptionsWidget(self.applyButton) self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI) self.kernelSizeMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.gaussianStandardDeviationMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.applyButton.connect("clicked()", self.onApply)
def setupOptionsFrame(self): self.methodSelectorComboBox = qt.QComboBox() self.methodSelectorComboBox.addItem("Median", MEDIAN) self.methodSelectorComboBox.addItem("Opening (remove extrusions)", MORPHOLOGICAL_OPENING) self.methodSelectorComboBox.addItem("Closing (fill holes)", MORPHOLOGICAL_CLOSING) self.methodSelectorComboBox.addItem("Gaussian", GAUSSIAN) self.methodSelectorComboBox.addItem("Joint smoothing", JOINT_TAUBIN) self.scriptedEffect.addLabeledOptionsWidget("Smoothing method:", self.methodSelectorComboBox) self.kernelSizeMmSpinBox = slicer.qMRMLSpinBox() self.kernelSizeMmSpinBox.setMRMLScene(slicer.mrmlScene) self.kernelSizeMmSpinBox.setToolTip("Diameter of the neighborhood that will be considered around each voxel. Higher value makes smoothing stronger (more details are suppressed).") self.kernelSizeMmSpinBox.quantity = "length" self.kernelSizeMmSpinBox.minimum = 0.0 self.kernelSizeMmSpinBox.value = 3.0 self.kernelSizeMmSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip("Diameter of the neighborhood in pixels. Computed from the segment's spacing and the specified kernel size.") kernelSizeFrame = qt.QHBoxLayout() kernelSizeFrame.addWidget(self.kernelSizeMmSpinBox) kernelSizeFrame.addWidget(self.kernelSizePixel) self.kernelSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget("Kernel size:", kernelSizeFrame) self.gaussianStandardDeviationMmSpinBox = slicer.qMRMLSpinBox() self.gaussianStandardDeviationMmSpinBox.setMRMLScene(slicer.mrmlScene) self.gaussianStandardDeviationMmSpinBox.setToolTip("Standard deviation of the Gaussian smoothing filter coefficients. Higher value makes smoothing stronger (more details are suppressed).") self.gaussianStandardDeviationMmSpinBox.quantity = "length" self.gaussianStandardDeviationMmSpinBox.value = 3.0 self.gaussianStandardDeviationMmSpinBox.singleStep = 1.0 self.gaussianStandardDeviationMmLabel = self.scriptedEffect.addLabeledOptionsWidget("Standard deviation:", self.gaussianStandardDeviationMmSpinBox) self.jointTaubinSmoothingFactorSlider = ctk.ctkSliderWidget() self.jointTaubinSmoothingFactorSlider.setToolTip("Higher value means stronger smoothing.") self.jointTaubinSmoothingFactorSlider.minimum = 0.01 self.jointTaubinSmoothingFactorSlider.maximum = 1.0 self.jointTaubinSmoothingFactorSlider.value = 0.5 self.jointTaubinSmoothingFactorSlider.singleStep = 0.01 self.jointTaubinSmoothingFactorSlider.pageStep = 0.1 self.jointTaubinSmoothingFactorLabel = self.scriptedEffect.addLabeledOptionsWidget("Smoothing factor:", self.jointTaubinSmoothingFactorSlider) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Apply smoothing to selected segment") self.scriptedEffect.addOptionsWidget(self.applyButton) self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI) self.kernelSizeMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.gaussianStandardDeviationMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.jointTaubinSmoothingFactorSlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.applyButton.connect('clicked()', self.onApply)
def setupOptionsFrame(self): SegmentEditorThresholdEffect.setupOptionsFrame(self) # Hide threshold options self.applyButton.setHidden(True) self.useForPaintButton.setHidden(True) # Add diameter selector self.minimumDiameterSpinBox = slicer.qMRMLSpinBox() self.minimumDiameterSpinBox.setMRMLScene(slicer.mrmlScene) self.minimumDiameterSpinBox.quantity = "length" self.minimumDiameterSpinBox.value = 3.0 self.minimumDiameterSpinBox.singleStep = 0.5 self.minimumDiameterSpinBox.setToolTip("Minimum diameter of the structure. Regions that are connected to the selected point by a bridge" " that this is thinner than this size will be excluded to prevent unwanted leaks through small holes.") self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip("Minimum diameter of the structure in pixels. Computed from the segment's spacing and the specified feature size.") minimumDiameterFrame = qt.QHBoxLayout() minimumDiameterFrame.addWidget(self.minimumDiameterSpinBox) minimumDiameterFrame.addWidget(self.kernelSizePixel) self.minimumDiameterMmLabel = self.scriptedEffect.addLabeledOptionsWidget("Minimum diameter:", minimumDiameterFrame) self.scriptedEffect.addOptionsWidget(minimumDiameterFrame) # Add algorithm options self.segmentationAlgorithmSelector = qt.QComboBox() self.segmentationAlgorithmSelector.addItem(SEGMENTATION_ALGORITHM_MASKING) self.segmentationAlgorithmSelector.addItem(SEGMENTATION_ALGORITHM_GROWCUT) self.segmentationAlgorithmSelector.addItem(SEGMENTATION_ALGORITHM_WATERSHED) self.scriptedEffect.addLabeledOptionsWidget("Segmentation algorithm: ", self.segmentationAlgorithmSelector) # Add feature size selector self.featureSizeSpinBox = slicer.qMRMLSpinBox() self.featureSizeSpinBox.setMRMLScene(slicer.mrmlScene) self.featureSizeSpinBox.quantity = "length" self.featureSizeSpinBox.value = 3.0 self.featureSizeSpinBox.singleStep = 0.5 self.featureSizeSpinBox.setToolTip("Spatial smoothness constraint used for WaterShed. Larger values result in smoother extracted surface.") self.scriptedEffect.addLabeledOptionsWidget("Feature size: ", self.featureSizeSpinBox) # Add ROI options self.roiSelector = slicer.qMRMLNodeComboBox() self.roiSelector.nodeTypes = ['vtkMRMLMarkupsROINode', 'vtkMRMLAnnotationROINode'] self.roiSelector.noneEnabled = True self.roiSelector.setMRMLScene(slicer.mrmlScene) self.scriptedEffect.addLabeledOptionsWidget("ROI: ", self.roiSelector) # Connections self.minimumDiameterSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.featureSizeSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.segmentationAlgorithmSelector.connect("currentIndexChanged(int)", self.updateMRMLFromGUI)
def setupOptionsFrame(self): self.marginSizeMmSpinBox = slicer.qMRMLSpinBox() self.marginSizeMmSpinBox.setMRMLScene(slicer.mrmlScene) self.marginSizeMmSpinBox.setToolTip( "Segment boundaries will be shifted by this distance. Positive value means the segments will grow, negative value means segment will shrink." ) self.marginSizeMmSpinBox.quantity = "length" self.marginSizeMmSpinBox.value = 3.0 self.marginSizeMmSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip( "Size change in pixels. Computed from the segment's spacing and the specified margin size." ) marginSizeFrame = qt.QHBoxLayout() marginSizeFrame.addWidget(self.kernelSizePixel) marginSizeFrame.addWidget(self.marginSizeMmSpinBox) self.marginSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget( "Margin size:", marginSizeFrame) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip( "Grows or shrinks selected segment by the specified margin.") self.scriptedEffect.addOptionsWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApply) self.marginSizeMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI)
def setupOptionsFrame(self): operationLayout = qt.QVBoxLayout() self.shrinkOptionRadioButton = qt.QRadioButton("Shrink") self.growOptionRadioButton = qt.QRadioButton("Grow") operationLayout.addWidget(self.shrinkOptionRadioButton) operationLayout.addWidget(self.growOptionRadioButton) self.growOptionRadioButton.setChecked(True) self.scriptedEffect.addLabeledOptionsWidget("Operation:", operationLayout) self.marginSizeMMSpinBox = slicer.qMRMLSpinBox() self.marginSizeMMSpinBox.setMRMLScene(slicer.mrmlScene) self.marginSizeMMSpinBox.setToolTip( "Segment boundaries will be shifted by this distance. Positive value means the segments will grow, negative value means segment will shrink." ) self.marginSizeMMSpinBox.quantity = "length" self.marginSizeMMSpinBox.value = 3.0 self.marginSizeMMSpinBox.singleStep = 1.0 self.marginSizeLabel = qt.QLabel() self.marginSizeLabel.setToolTip( "Size change in pixel. Computed from the segment's spacing and the specified margin size." ) marginSizeFrame = qt.QHBoxLayout() marginSizeFrame.addWidget(self.marginSizeMMSpinBox) self.marginSizeMMLabel = self.scriptedEffect.addLabeledOptionsWidget( "Margin size:", marginSizeFrame) self.scriptedEffect.addLabeledOptionsWidget("", self.marginSizeLabel) self.applyToAllVisibleSegmentsCheckBox = qt.QCheckBox() self.applyToAllVisibleSegmentsCheckBox.setToolTip( "Grow or shrink all visible segments in this segmentation node. \ This operation may take a while." ) self.applyToAllVisibleSegmentsCheckBox.objectName = self.__class__.__name__ + 'ApplyToAllVisibleSegments' self.applyToAllVisibleSegmentsLabel = self.scriptedEffect.addLabeledOptionsWidget( "Apply to all segments:", self.applyToAllVisibleSegmentsCheckBox) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip( "Grows or shrinks selected segment /default) or all segments (checkbox) by the specified margin." ) self.scriptedEffect.addOptionsWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApply) self.marginSizeMMSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.growOptionRadioButton.connect("toggled(bool)", self.growOperationToggled) self.shrinkOptionRadioButton.connect("toggled(bool)", self.shrinkOperationToggled) self.applyToAllVisibleSegmentsCheckBox.connect("stateChanged(int)", self.updateMRMLFromGUI)
def create(self): super(InterpolateROIsEffectOptions,self).create() self.minimumSigma = 0.01 self.maximumSigma = 1.5 self.sigmaFrame = qt.QFrame(self.frame) self.sigmaFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.sigmaFrame) self.widgets.append(self.sigmaFrame) self.sigmaLabel = qt.QLabel("Sigma:", self.sigmaFrame) self.sigmaLabel.setToolTip("Set the sigma of the gaussian filter") self.sigmaFrame.layout().addWidget(self.sigmaLabel) self.widgets.append(self.sigmaLabel) self.sigmaSpinBox = slicer.qMRMLSpinBox(self.sigmaFrame) self.sigmaSpinBox.objectName = 'SpinBox_Sigma' self.sigmaSpinBox.setToolTip("Set the sigma of the gaussian filter") #self.sigmaSpinBox.quantity = "length" # QFlags not wrapped in python. Equivalent to Prefix | Suffix # See qMRMLSpinBox for more details. self.sigmaSpinBox.unitAwareProperties = 0x01 | 0x02 self.sigmaSpinBox.decimals = 2 self.sigmaSpinBox.minimum = self.minimumSigma self.sigmaSpinBox.maximum = self.maximumSigma self.sigmaSpinBox.singleStep = self.minimumSigma self.sigmaSpinBox.setMRMLScene(slicer.mrmlScene) self.sigmaFrame.layout().addWidget(self.sigmaSpinBox) self.widgets.append(self.sigmaSpinBox) self.sigma = ctk.ctkDoubleSlider(self.frame) self.sigma.objectName = 'DoubleSlider_Sigma' self.sigma.minimum = self.minimumSigma self.sigma.maximum = self.maximumSigma self.sigma.orientation = 1 self.sigma.singleStep = self.minimumSigma self.frame.layout().addWidget(self.sigma) self.widgets.append(self.sigma) self.apply = qt.QPushButton("Apply", self.frame) self.apply.objectName = self.__class__.__name__ + 'Apply' self.apply.setToolTip("Interpolate current label") self.frame.layout().addWidget(self.apply) self.widgets.append(self.apply) EditorLib.HelpButton(self.frame, "Use this tool to remove pixels from the boundary of the current label.") self.connections.append( (self.sigma, 'valueChanged(double)', self.onSigmaValueChanged) ) self.connections.append( (self.sigmaSpinBox, 'valueChanged(double)', self.onSigmaSpinBoxChanged) ) self.connections.append( (self.apply, 'clicked()', self.onApply) ) # Add vertical spacer self.frame.layout().addStretch(1) self.parameterNode.SetParameter("MorphologyEffect,neighborMode","8") self.parameterNode.SetParameter("InterpolateROIsEffect,sigma","1.0")
def setupOptionsFrame(self): operationLayout = qt.QVBoxLayout() self.insideSurfaceOptionRadioButton = qt.QRadioButton("inside surface") self.medialSurfaceOptionRadioButton = qt.QRadioButton("medial surface") self.outsideSurfaceOptionRadioButton = qt.QRadioButton( "outside surface") operationLayout.addWidget(self.insideSurfaceOptionRadioButton) operationLayout.addWidget(self.medialSurfaceOptionRadioButton) operationLayout.addWidget(self.outsideSurfaceOptionRadioButton) self.insideSurfaceOptionRadioButton.setChecked(True) self.scriptedEffect.addLabeledOptionsWidget("Use current segment as:", operationLayout) self.shellThicknessMMSpinBox = slicer.qMRMLSpinBox() self.shellThicknessMMSpinBox.setMRMLScene(slicer.mrmlScene) self.shellThicknessMMSpinBox.setToolTip( "Thickness of the hollow shell.") self.shellThicknessMMSpinBox.quantity = "length" self.shellThicknessMMSpinBox.minimum = 0.0 self.shellThicknessMMSpinBox.value = 3.0 self.shellThicknessMMSpinBox.singleStep = 1.0 self.shellThicknessLabel = qt.QLabel() self.shellThicknessLabel.setToolTip( "Closest achievable thickness. Constrained by the segmentation's binary labelmap representation spacing." ) shellThicknessFrame = qt.QHBoxLayout() shellThicknessFrame.addWidget(self.shellThicknessMMSpinBox) self.shellThicknessMMLabel = self.scriptedEffect.addLabeledOptionsWidget( "Shell thickness:", shellThicknessFrame) self.scriptedEffect.addLabeledOptionsWidget("", self.shellThicknessLabel) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip( "Makes the segment hollow by replacing it with a thick shell at the segment boundary." ) self.scriptedEffect.addOptionsWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApply) self.shellThicknessMMSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.insideSurfaceOptionRadioButton.connect( "toggled(bool)", self.insideSurfaceModeToggled) self.medialSurfaceOptionRadioButton.connect( "toggled(bool)", self.medialSurfaceModeToggled) self.outsideSurfaceOptionRadioButton.connect( "toggled(bool)", self.outsideSurfaceModeToggled)
def setupOptionsFrame(self): SegmentEditorThresholdEffect.setupOptionsFrame(self) # Hide threshold options self.applyButton.setHidden(True) self.useForPaintButton.setHidden(True) # Add feature options self.minimumMinimumFeatureSize = slicer.qMRMLSpinBox() self.minimumMinimumFeatureSize.setMRMLScene(slicer.mrmlScene) self.minimumMinimumFeatureSize.quantity = "length" self.minimumMinimumFeatureSize.value = 3.0 self.minimumMinimumFeatureSize.singleStep = 0.5 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip( "Minimum size of features in pixels. Computed from the segment's spacing and the specified feature size." ) featureSizeFrame = qt.QHBoxLayout() featureSizeFrame.addWidget(self.minimumMinimumFeatureSize) featureSizeFrame.addWidget(self.kernelSizePixel) self.featureSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget( "Feature size:", featureSizeFrame) self.scriptedEffect.addOptionsWidget(featureSizeFrame) # Add algorithm options self.segmentationAlgorithmSelector = qt.QComboBox() self.segmentationAlgorithmSelector.addItem( SEGMENTATION_ALGORITHM_MASKING) self.segmentationAlgorithmSelector.addItem( SEGMENTATION_ALGORITHM_GROWCUT) self.segmentationAlgorithmSelector.addItem( SEGMENTATION_ALGORITHM_WATERSHED) self.scriptedEffect.addLabeledOptionsWidget( "Segmentation algorithm: ", self.segmentationAlgorithmSelector) # Add ROI options self.roiSelector = slicer.qMRMLNodeComboBox() self.roiSelector.nodeTypes = ['vtkMRMLAnnotationROINode'] self.roiSelector.noneEnabled = True self.roiSelector.setMRMLScene(slicer.mrmlScene) self.scriptedEffect.addLabeledOptionsWidget("ROI: ", self.roiSelector) # Connections self.minimumMinimumFeatureSize.connect("valueChanged(double)", self.updateMRMLFromGUI) self.segmentationAlgorithmSelector.connect("currentIndexChanged(int)", self.updateMRMLFromGUI)
def setupOptionsFrame(self): operationLayout = qt.QVBoxLayout() self.insideSurfaceOptionRadioButton = qt.QRadioButton("inside surface") self.medialSurfaceOptionRadioButton = qt.QRadioButton("medial surface") self.outsideSurfaceOptionRadioButton = qt.QRadioButton("outside surface") operationLayout.addWidget(self.insideSurfaceOptionRadioButton) operationLayout.addWidget(self.medialSurfaceOptionRadioButton) operationLayout.addWidget(self.outsideSurfaceOptionRadioButton) self.insideSurfaceOptionRadioButton.setChecked(True) self.scriptedEffect.addLabeledOptionsWidget("Use current segment as:", operationLayout) self.shellThicknessMmSpinBox = slicer.qMRMLSpinBox() self.shellThicknessMmSpinBox.setMRMLScene(slicer.mrmlScene) self.shellThicknessMmSpinBox.setToolTip("Thickness of the hollow shell.") self.shellThicknessMmSpinBox.quantity = "length" self.shellThicknessMmSpinBox.minimum = 0.0 self.shellThicknessMmSpinBox.value = 3.0 self.shellThicknessMmSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip("Thickness in pixels. Computed from the segment's spacing and the specified margin size.") shellThicknessFrame = qt.QHBoxLayout() shellThicknessFrame.addWidget(self.shellThicknessMmSpinBox) shellThicknessFrame.addWidget(self.kernelSizePixel) self.shellThicknessMmLabel = self.scriptedEffect.addLabeledOptionsWidget("Shell thickness:", shellThicknessFrame) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Makes the segment hollow by replacing it with a thick shell at the segment boundary.") self.scriptedEffect.addOptionsWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApply) self.shellThicknessMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI) self.insideSurfaceOptionRadioButton.connect("toggled(bool)", self.insideSurfaceModeToggled) self.medialSurfaceOptionRadioButton.connect("toggled(bool)", self.medialSurfaceModeToggled) self.outsideSurfaceOptionRadioButton.connect("toggled(bool)", self.outsideSurfaceModeToggled)
def setupOptionsFrame(self): self.marginSizeMmSpinBox = slicer.qMRMLSpinBox() self.marginSizeMmSpinBox.setMRMLScene(slicer.mrmlScene) self.marginSizeMmSpinBox.setToolTip("Segment boundaries will be shifted by this distance. Positive value means the segments will grow, negative value means segment will shrink.") self.marginSizeMmSpinBox.quantity = "length" self.marginSizeMmSpinBox.value = 3.0 self.marginSizeMmSpinBox.singleStep = 1.0 self.kernelSizePixel = qt.QLabel() self.kernelSizePixel.setToolTip("Size change in pixels. Computed from the segment's spacing and the specified margin size.") marginSizeFrame = qt.QHBoxLayout() marginSizeFrame.addWidget(self.kernelSizePixel) marginSizeFrame.addWidget(self.marginSizeMmSpinBox) self.marginSizeMmLabel = self.scriptedEffect.addLabeledOptionsWidget("Margin size:", marginSizeFrame) self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Grows or shrinks selected segment by the specified margin.") self.scriptedEffect.addOptionsWidget(self.applyButton) self.applyButton.connect('clicked()', self.onApply) self.marginSizeMmSpinBox.connect("valueChanged(double)", self.updateMRMLFromGUI)
def setupOptionsFrame(self): self.interpolationRadioButtons = [] # Fiducial Placement widget self.fiducialPlacementToggle = slicer.qSlicerMarkupsPlaceWidget() self.fiducialPlacementToggle.setMRMLScene(slicer.mrmlScene) self.fiducialPlacementToggle.placeMultipleMarkups = self.fiducialPlacementToggle.ForcePlaceMultipleMarkups self.fiducialPlacementToggle.buttonsVisible = False self.fiducialPlacementToggle.show() self.fiducialPlacementToggle.placeButton().show() self.fiducialPlacementToggle.deleteButton().show() # Edit surface button self.editButton = qt.QPushButton("Edit") self.editButton.objectName = self.__class__.__name__ + 'Edit' self.editButton.setToolTip( "Edit the previously placed group of fiducials.") fiducialActionLayout = qt.QHBoxLayout() fiducialActionLayout.addWidget(self.fiducialPlacementToggle) fiducialActionLayout.addWidget(self.editButton) self.scriptedEffect.addLabeledOptionsWidget("Fiducial Placement: ", fiducialActionLayout) # Radius spinbox self.radiusSpinBox = slicer.qMRMLSpinBox() self.radiusSpinBox.value = self.logic.radius self.radiusSpinBox.quantity = 'length' self.radiusSpinBox.unitAwareProperties = slicer.qMRMLSpinBox.MaximumValue | slicer.qMRMLSpinBox.Precision | slicer.qMRMLSpinBox.Prefix | slicer.qMRMLSpinBox.Suffix self.scriptedEffect.addLabeledOptionsWidget("Radius: ", self.radiusSpinBox) # Interpolation buttons self.piecewiseLinearButton = qt.QRadioButton("Piecewise linear") self.interpolationRadioButtons.append(self.piecewiseLinearButton) self.buttonToInterpolationTypeMap[ self.piecewiseLinearButton] = "LINEAR" self.cardinalSplineButton = qt.QRadioButton("Cardinal spline") self.interpolationRadioButtons.append(self.cardinalSplineButton) self.buttonToInterpolationTypeMap[ self.cardinalSplineButton] = "CARDINAL_SPLINE" self.kochanekSplineButton = qt.QRadioButton("Kochanek spline") self.interpolationRadioButtons.append(self.kochanekSplineButton) self.buttonToInterpolationTypeMap[ self.kochanekSplineButton] = "KOCHANEK_SPLINE" self.globalPolynomialButton = qt.QRadioButton("Global polynomial") self.interpolationRadioButtons.append(self.globalPolynomialButton) self.buttonToInterpolationTypeMap[ self.globalPolynomialButton] = "GLOBAL_POLYNOMIAL" self.movingPolynomialButton = qt.QRadioButton("Moving polynomial") self.interpolationRadioButtons.append(self.movingPolynomialButton) self.buttonToInterpolationTypeMap[ self.movingPolynomialButton] = "MOVING_POLYNOMIAL" # Interpolation buttons layout interpolationLayout = qt.QGridLayout() interpolationLayout.addWidget(self.piecewiseLinearButton, 0, 0) interpolationLayout.addWidget(self.cardinalSplineButton, 1, 0) interpolationLayout.addWidget(self.kochanekSplineButton, 0, 1) interpolationLayout.addWidget(self.globalPolynomialButton, 1, 1) interpolationLayout.addWidget(self.movingPolynomialButton, 0, 2) self.scriptedEffect.addLabeledOptionsWidget("Interpolation:", interpolationLayout) # Apply button self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Generate tube from markup fiducials.") self.scriptedEffect.addOptionsWidget(self.applyButton) # Cancel button self.cancelButton = qt.QPushButton("Cancel") self.cancelButton.objectName = self.__class__.__name__ + 'Cancel' self.cancelButton.setToolTip("Clear fiducials and remove from scene.") # Finish action buttons finishAction = qt.QHBoxLayout() finishAction.addWidget(self.cancelButton) finishAction.addWidget(self.applyButton) self.scriptedEffect.addOptionsWidget(finishAction) # Connections for button in self.interpolationRadioButtons: button.connect('toggled(bool)', lambda toggle, widget=self. buttonToInterpolationTypeMap[button]: self. onInterpolationSelectionChanged(widget, toggle)) self.applyButton.connect('clicked()', self.onApply) self.cancelButton.connect('clicked()', self.onCancel) self.editButton.connect('clicked()', self.onEdit) self.fiducialPlacementToggle.placeButton().clicked.connect( self.onFiducialPlacementToggleChanged) self.radiusSpinBox.connect('valueChanged(double)', self.onRadiusChanged)
def create(self): super(PaintEffectOptions, self).create() self.radiusFrame = qt.QFrame(self.frame) self.radiusFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.radiusFrame) self.widgets.append(self.radiusFrame) self.radiusLabel = qt.QLabel("Radius:", self.radiusFrame) self.radiusLabel.setToolTip( "Set the radius of the paint brush in millimeters") self.radiusFrame.layout().addWidget(self.radiusLabel) self.widgets.append(self.radiusLabel) self.radiusSpinBox = slicer.qMRMLSpinBox(self.radiusFrame) self.radiusSpinBox.objectName = 'SpinBox_Radius' self.radiusSpinBox.setToolTip( "Set the radius of the paint brush in millimeters") self.radiusSpinBox.quantity = "length" # QFlags not wrapped in python. Equivalent to Prefix | Suffix # See qMRMLSpinBox for more details. self.radiusSpinBox.unitAwareProperties = 0x01 | 0x02 self.radiusSpinBox.minimum = self.minimumRadius self.radiusSpinBox.maximum = self.maximumRadius self.radiusSpinBox.setMRMLScene(slicer.mrmlScene) from math import log, floor decimals = floor(log(self.minimumRadius, 10)) if decimals < 0: self.radiusSpinBox.decimals = -decimals + 2 self.radiusFrame.layout().addWidget(self.radiusSpinBox) self.widgets.append(self.radiusSpinBox) self.radiusUnitsToggle = qt.QPushButton("px:") self.radiusUnitsToggle.objectName = 'PushButton_RadiusUnitsToggle' self.radiusUnitsToggle.setToolTip( "Toggle radius quick set buttons between mm and label volume pixel size units" ) self.radiusUnitsToggle.setFixedWidth(35) self.radiusFrame.layout().addWidget(self.radiusUnitsToggle) self.radiusUnitsToggle.connect('clicked()', self.onRadiusUnitsToggle) self.radiusQuickies = {} quickies = ((2, self.onQuickie2Clicked), (3, self.onQuickie3Clicked), (4, self.onQuickie4Clicked), (5, self.onQuickie5Clicked), (10, self.onQuickie10Clicked), (20, self.onQuickie20Clicked)) for rad, callback in quickies: self.radiusQuickies[rad] = qt.QPushButton(str(rad)) self.radiusQuickies[ rad].objectName = 'PushButton_QuickRadius_{0}'.format(rad) self.radiusFrame.layout().addWidget(self.radiusQuickies[rad]) self.radiusQuickies[rad].setFixedWidth(25) self.radiusQuickies[rad].connect('clicked()', callback) self.radiusQuickies[rad].setToolTip( "Set radius based on mm or label voxel size units depending on toggle value" ) self.radius = ctk.ctkDoubleSlider(self.frame) self.radius.objectName = 'DoubleSlider_Radius' self.radius.minimum = self.minimumRadius self.radius.maximum = self.maximumRadius self.radius.orientation = 1 self.radius.singleStep = self.minimumRadius self.frame.layout().addWidget(self.radius) self.widgets.append(self.radius) self.sphere = qt.QCheckBox("Sphere", self.frame) self.sphere.objectName = 'CheckBox_Sphere' self.sphere.setToolTip( "Use a 3D spherical brush rather than a 2D circular brush.") self.frame.layout().addWidget(self.sphere) self.widgets.append(self.sphere) self.smudge = qt.QCheckBox("Smudge", self.frame) self.smudge.objectName = 'CheckBox_Smudge' self.smudge.setToolTip( "Set the label number automatically by sampling the pixel location where the brush stroke starts." ) self.frame.layout().addWidget(self.smudge) self.widgets.append(self.smudge) self.pixelMode = qt.QCheckBox("Pixel Mode", self.frame) self.pixelMode.objectName = 'CheckBox_PixelMode' self.pixelMode.setToolTip( "Paint exactly the pixel under the cursor, ignoring the radius, threshold, and paint over." ) self.frame.layout().addWidget(self.pixelMode) self.widgets.append(self.pixelMode) HelpButton( self.frame, "Use this tool to paint with a round brush of the selected radius") self.connections.append( (self.sphere, 'clicked()', self.updateMRMLFromGUI)) self.connections.append( (self.smudge, 'clicked()', self.updateMRMLFromGUI)) self.connections.append( (self.pixelMode, 'clicked()', self.updateMRMLFromGUI)) self.connections.append( (self.radius, 'valueChanged(double)', self.onRadiusValueChanged)) self.connections.append((self.radiusSpinBox, 'valueChanged(double)', self.onRadiusSpinBoxChanged)) # Add vertical spacer self.frame.layout().addStretch(1)
def create(self): super(PaintEffectOptions,self).create() self.radiusFrame = qt.QFrame(self.frame) self.radiusFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.radiusFrame) self.widgets.append(self.radiusFrame) self.radiusLabel = qt.QLabel("Radius:", self.radiusFrame) self.radiusLabel.setToolTip("Set the radius of the paint brush in millimeters") self.radiusFrame.layout().addWidget(self.radiusLabel) self.widgets.append(self.radiusLabel) self.radiusSpinBox = slicer.qMRMLSpinBox(self.radiusFrame) self.radiusSpinBox.objectName = 'SpinBox_Radius' self.radiusSpinBox.setToolTip("Set the radius of the paint brush in millimeters") self.radiusSpinBox.quantity = "length" # QFlags not wrapped in python. Equivalent to Prefix | Suffix # See qMRMLSpinBox for more details. self.radiusSpinBox.unitAwareProperties = 0x01 | 0x02 self.radiusSpinBox.minimum = self.minimumRadius self.radiusSpinBox.maximum = self.maximumRadius self.radiusSpinBox.setMRMLScene(slicer.mrmlScene) from math import log,floor decimals = floor(log(self.minimumRadius,10)) if decimals < 0: self.radiusSpinBox.decimals = -decimals + 2 self.radiusFrame.layout().addWidget(self.radiusSpinBox) self.widgets.append(self.radiusSpinBox) self.radiusUnitsToggle = qt.QPushButton("px:") self.radiusUnitsToggle.objectName = 'PushButton_RadiusUnitsToggle' self.radiusUnitsToggle.setToolTip("Toggle radius quick set buttons between mm and label volume pixel size units") self.radiusUnitsToggle.setFixedWidth(35) self.radiusFrame.layout().addWidget(self.radiusUnitsToggle) self.radiusUnitsToggle.connect('clicked()',self.onRadiusUnitsToggle) self.radiusQuickies = {} quickies = ( (2, self.onQuickie2Clicked), (3,self.onQuickie3Clicked), (4, self.onQuickie4Clicked), (5, self.onQuickie5Clicked), (10, self.onQuickie10Clicked), (20, self.onQuickie20Clicked) ) for rad,callback in quickies: self.radiusQuickies[rad] = qt.QPushButton(str(rad)) self.radiusQuickies[rad].objectName = 'PushButton_QuickRadius_{0}'.format(rad) self.radiusFrame.layout().addWidget(self.radiusQuickies[rad]) self.radiusQuickies[rad].setFixedWidth(25) self.radiusQuickies[rad].connect('clicked()', callback) self.radiusQuickies[rad].setToolTip("Set radius based on mm or label voxel size units depending on toggle value") self.radius = ctk.ctkDoubleSlider(self.frame) self.radius.objectName = 'DoubleSlider_Radius' self.radius.minimum = self.minimumRadius self.radius.maximum = self.maximumRadius self.radius.orientation = 1 self.radius.singleStep = self.minimumRadius self.frame.layout().addWidget(self.radius) self.widgets.append(self.radius) self.sphere = qt.QCheckBox("Sphere", self.frame) self.sphere.objectName = 'CheckBox_Sphere' self.sphere.setToolTip("Use a 3D spherical brush rather than a 2D circular brush.") self.frame.layout().addWidget(self.sphere) self.widgets.append(self.sphere) self.smudge = qt.QCheckBox("Smudge", self.frame) self.smudge.objectName = 'CheckBox_Smudge' self.smudge.setToolTip("Set the label number automatically by sampling the pixel location where the brush stroke starts.") self.frame.layout().addWidget(self.smudge) self.widgets.append(self.smudge) self.pixelMode = qt.QCheckBox("Pixel Mode", self.frame) self.pixelMode.objectName = 'CheckBox_PixelMode' self.pixelMode.setToolTip("Paint exactly the pixel under the cursor, ignoring the radius, threshold, and paint over.") self.frame.layout().addWidget(self.pixelMode) self.widgets.append(self.pixelMode) HelpButton(self.frame, "Use this tool to paint with a round brush of the selected radius") self.connections.append( (self.sphere, 'clicked()', self.updateMRMLFromGUI) ) self.connections.append( (self.smudge, 'clicked()', self.updateMRMLFromGUI) ) self.connections.append( (self.pixelMode, 'clicked()', self.updateMRMLFromGUI) ) self.connections.append( (self.radius, 'valueChanged(double)', self.onRadiusValueChanged) ) self.connections.append( (self.radiusSpinBox, 'valueChanged(double)', self.onRadiusSpinBoxChanged) ) # Add vertical spacer self.frame.layout().addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = CreateMeshLogic() # Inputs inputsCollapsibleButton = ctk.ctkCollapsibleButton() inputsCollapsibleButton.text = 'Inputs' self.layout.addWidget(inputsCollapsibleButton) inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton) # Segmentation selector self.segmentationSelector = slicer.qMRMLNodeComboBox() self.segmentationSelector.nodeTypes = ['vtkMRMLSegmentationNode'] self.segmentationSelector.addEnabled = False self.segmentationSelector.removeEnabled = False self.segmentationSelector.renameEnabled = False self.segmentationSelector.setMRMLScene(slicer.mrmlScene) self.segmentationSelector.setToolTip( 'Pick the segmentation to compute a mesh from') inputsFormLayout.addRow('Segmentation:', self.segmentationSelector) # Fiducials selector self.fiducialsSelector = slicer.qMRMLNodeComboBox() self.fiducialsSelector.nodeTypes = ['vtkMRMLMarkupsFiducialNode'] self.fiducialsSelector.addEnabled = False self.fiducialsSelector.removeEnabled = False self.fiducialsSelector.renameEnabled = False self.fiducialsSelector.setMRMLScene(slicer.mrmlScene) self.fiducialsSelector.setToolTip( 'Select the fiducials that will define the light sources and detectors position' ) inputsFormLayout.addRow('Fiducials:', self.fiducialsSelector) # Outputs outputsCollapsibleButton = ctk.ctkCollapsibleButton() outputsCollapsibleButton.text = 'Outputs' self.layout.addWidget(outputsCollapsibleButton) outputsFormLayout = qt.QFormLayout(outputsCollapsibleButton) # Mesh directory self.meshPathLineEdit = ctk.ctkPathLineEdit() self.meshPathLineEdit.filters = ctk.ctkPathLineEdit.Dirs self.meshPathLineEdit.currentPath = self.cachedPathFor( 'CreateMeshOutputPath') outputsFormLayout.addRow('Mesh directory:', self.meshPathLineEdit) # Mesh name self.meshNameField = qt.QLineEdit() outputsFormLayout.addRow('Mesh name:', self.meshNameField) # Meshing meshingCollapsibleButton = ctk.ctkCollapsibleButton() meshingCollapsibleButton.text = 'Meshing' self.layout.addWidget(meshingCollapsibleButton) meshingFormLayout = qt.QFormLayout(meshingCollapsibleButton) # Mesh type self.meshTypeComboBox = ctk.ctkComboBox() for meshType in self.logic.meshTypes: self.meshTypeComboBox.addItem(meshType) meshingFormLayout.addRow('Mesh type:', self.meshTypeComboBox) # Cell size self.cellSizeSpinBox = slicer.qMRMLSpinBox() self.cellSizeSpinBox.setValue(1.5) self.cellSizeSpinBox.setMRMLScene(slicer.mrmlScene) meshingFormLayout.addRow('Cell size:', self.cellSizeSpinBox) # Cell radius edge self.cellRadiusSpinBox = slicer.qMRMLSpinBox() self.cellRadiusSpinBox.setValue(3.0) self.cellRadiusSpinBox.setMRMLScene(slicer.mrmlScene) meshingFormLayout.addRow('Cell radius edge:', self.cellRadiusSpinBox) # Facet size self.facetSizeSpinBox = slicer.qMRMLSpinBox() self.facetSizeSpinBox.setValue(1.5) self.facetSizeSpinBox.setMRMLScene(slicer.mrmlScene) meshingFormLayout.addRow('Facet size:', self.facetSizeSpinBox) # Facet angle self.facetAngleSpinBox = slicer.qMRMLSpinBox() self.facetAngleSpinBox.setValue(25.0) self.facetAngleSpinBox.setMRMLScene(slicer.mrmlScene) meshingFormLayout.addRow('Facet angle:', self.facetAngleSpinBox) # Facet distance self.facetDistanceSpinBox = slicer.qMRMLSpinBox() self.facetDistanceSpinBox.setValue(3.0) self.facetDistanceSpinBox.setMRMLScene(slicer.mrmlScene) meshingFormLayout.addRow('Facet distance:', self.facetDistanceSpinBox) # Optimize mesh self.optimizeCheckBox = qt.QCheckBox() meshingFormLayout.addRow('Optimize mesh:', self.optimizeCheckBox) # NIRFAST nirfastCollapsibleButton = ctk.ctkCollapsibleButton() nirfastCollapsibleButton.text = 'NIRFAST Matlab' self.layout.addWidget(nirfastCollapsibleButton) nirfastFormLayout = qt.QFormLayout(nirfastCollapsibleButton) # NIRFAST-Matlab self.nirfastMatlabPathLineEdit = ctk.ctkPathLineEdit() self.nirfastMatlabPathLineEdit.filters = ctk.ctkPathLineEdit.Dirs self.nirfastMatlabPathLineEdit.currentPath = self.cachedPathFor( 'NIRFASTMatlabPath') nirfastFormLayout.addRow('NIRFAST Matlab:', self.nirfastMatlabPathLineEdit) # Run self.runButton = qt.QPushButton() self.runButton.setCheckable(True) self.setRunning(False) self.layout.addWidget(self.runButton) # Progress self.progressBar = slicer.qSlicerCLIProgressBar() self.logic.setProgressBar(self.progressBar) self.layout.addWidget(self.progressBar) # Add vertical spacer self.layout.addStretch(1) # Connections self.segmentationSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onSegmentationNodeChanged) self.onSegmentationNodeChanged(self.segmentationSelector.currentNode()) self.meshPathLineEdit.connect('currentPathChanged(QString)', self.logic.cacheOutputMeshDir) self.nirfastMatlabPathLineEdit.connect( 'currentPathChanged(QString)', self.logic.cacheNirfastMatlabDir) self.runButton.connect('clicked()', self.onRun) self.logic.setBusy = self.setRunning self.logic.setError = self.showError