def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = ScreenCaptureLogic() self.logic.logCallback = self.addLog self.viewNodeType = None self.animationMode = None self.createdOutputFile = None self.snapshotIndex = 0 # this counter is used for determining file names for single-image snapshots self.snapshotOutputDir = None self.snapshotFileNamePattern = None # Instantiate and connect widgets ... # # Input area # self.inputCollapsibleButton = ctk.ctkCollapsibleButton() self.inputCollapsibleButton.text = "Input" self.layout.addWidget(self.inputCollapsibleButton) inputFormLayout = qt.QFormLayout(self.inputCollapsibleButton) # Input view selector self.viewNodeSelector = slicer.qMRMLNodeComboBox() self.viewNodeSelector.nodeTypes = ["vtkMRMLSliceNode", "vtkMRMLViewNode"] self.viewNodeSelector.addEnabled = False self.viewNodeSelector.removeEnabled = False self.viewNodeSelector.noneEnabled = False self.viewNodeSelector.showHidden = False self.viewNodeSelector.showChildNodeTypes = False self.viewNodeSelector.setMRMLScene( slicer.mrmlScene ) self.viewNodeSelector.setToolTip("This slice or 3D view will be updated during capture." "Only this view will be captured unless 'Capture of all views' option in output section is enabled." ) inputFormLayout.addRow("Master view: ", self.viewNodeSelector) # Mode self.animationModeWidget = qt.QComboBox() self.animationModeWidget.setToolTip("Select the property that will be adjusted") inputFormLayout.addRow("Animation mode:", self.animationModeWidget) # Slice start offset position self.sliceStartOffsetSliderLabel = qt.QLabel("Start sweep offset:") self.sliceStartOffsetSliderWidget = ctk.ctkSliderWidget() self.sliceStartOffsetSliderWidget.singleStep = 30 self.sliceStartOffsetSliderWidget.minimum = -100 self.sliceStartOffsetSliderWidget.maximum = 100 self.sliceStartOffsetSliderWidget.value = 0 self.sliceStartOffsetSliderWidget.setToolTip("Start slice sweep offset.") inputFormLayout.addRow(self.sliceStartOffsetSliderLabel, self.sliceStartOffsetSliderWidget) # Slice end offset position self.sliceEndOffsetSliderLabel = qt.QLabel("End sweep offset:") self.sliceEndOffsetSliderWidget = ctk.ctkSliderWidget() self.sliceEndOffsetSliderWidget.singleStep = 5 self.sliceEndOffsetSliderWidget.minimum = -100 self.sliceEndOffsetSliderWidget.maximum = 100 self.sliceEndOffsetSliderWidget.value = 0 self.sliceEndOffsetSliderWidget.setToolTip("End slice sweep offset.") inputFormLayout.addRow(self.sliceEndOffsetSliderLabel, self.sliceEndOffsetSliderWidget) # 3D rotation range self.rotationSliderLabel = qt.QLabel("Rotation range:") self.rotationSliderWidget = ctk.ctkRangeWidget() self.rotationSliderWidget.singleStep = 5 self.rotationSliderWidget.minimum = -180 self.rotationSliderWidget.maximum = 180 self.rotationSliderWidget.minimumValue = -180 self.rotationSliderWidget.maximumValue = 180 self.rotationSliderWidget.setToolTip("View rotation range, relative to current view orientation.") inputFormLayout.addRow(self.rotationSliderLabel, self.rotationSliderWidget) # 3D rotation axis self.rotationAxisLabel = qt.QLabel("Rotation axis:") self.rotationAxisWidget = ctk.ctkRangeWidget() self.rotationAxisWidget = qt.QComboBox() self.rotationAxisWidget.addItem("Yaw", AXIS_YAW) self.rotationAxisWidget.addItem("Pitch", AXIS_PITCH) inputFormLayout.addRow(self.rotationAxisLabel, self.rotationAxisWidget) # Sequence browser node selector self.sequenceBrowserNodeSelectorLabel = qt.QLabel("Sequence:") self.sequenceBrowserNodeSelectorWidget = slicer.qMRMLNodeComboBox() self.sequenceBrowserNodeSelectorWidget.nodeTypes = ["vtkMRMLSequenceBrowserNode"] self.sequenceBrowserNodeSelectorWidget.addEnabled = False self.sequenceBrowserNodeSelectorWidget.removeEnabled = False self.sequenceBrowserNodeSelectorWidget.noneEnabled = False self.sequenceBrowserNodeSelectorWidget.showHidden = False self.sequenceBrowserNodeSelectorWidget.setMRMLScene( slicer.mrmlScene ) self.sequenceBrowserNodeSelectorWidget.setToolTip( "Items defined by this sequence browser will be replayed." ) inputFormLayout.addRow(self.sequenceBrowserNodeSelectorLabel, self.sequenceBrowserNodeSelectorWidget) # Sequence start index self.sequenceStartItemIndexLabel = qt.QLabel("Start index:") self.sequenceStartItemIndexWidget = ctk.ctkSliderWidget() self.sequenceStartItemIndexWidget.minimum = 0 self.sequenceStartItemIndexWidget.decimals = 0 self.sequenceStartItemIndexWidget.setToolTip("First item in the sequence to capture.") inputFormLayout.addRow(self.sequenceStartItemIndexLabel, self.sequenceStartItemIndexWidget) # Sequence end index self.sequenceEndItemIndexLabel = qt.QLabel("End index:") self.sequenceEndItemIndexWidget = ctk.ctkSliderWidget() self.sequenceEndItemIndexWidget.minimum = 0 self.sequenceEndItemIndexWidget.decimals = 0 self.sequenceEndItemIndexWidget.setToolTip("Last item in the sequence to capture.") inputFormLayout.addRow(self.sequenceEndItemIndexLabel, self.sequenceEndItemIndexWidget) # # Output area # self.outputCollapsibleButton = ctk.ctkCollapsibleButton() self.outputCollapsibleButton.text = "Output" self.layout.addWidget(self.outputCollapsibleButton) outputFormLayout = qt.QFormLayout(self.outputCollapsibleButton) # Number of steps value self.numberOfStepsSliderWidget = ctk.ctkSliderWidget() self.numberOfStepsSliderWidget.singleStep = 10 self.numberOfStepsSliderWidget.minimum = 1 self.numberOfStepsSliderWidget.maximum = 600 self.numberOfStepsSliderWidget.value = 31 self.numberOfStepsSliderWidget.decimals = 0 self.numberOfStepsSliderWidget.setToolTip("Number of images extracted between start and stop positions.") # Single step toggle button self.singleStepButton = qt.QToolButton() self.singleStepButton.setText("single") self.singleStepButton.setCheckable(True) self.singleStepButton.toolTip = "Capture a single image of current state only.\n" + \ "New filename is generated for each captured image (no files are overwritten)." hbox = qt.QHBoxLayout() hbox.addWidget(self.singleStepButton) hbox.addWidget(self.numberOfStepsSliderWidget) outputFormLayout.addRow("Number of images:", hbox) # Output directory selector self.outputDirSelector = ctk.ctkPathLineEdit() self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.outputDirSelector.settingKey = 'ScreenCaptureOutputDir' outputFormLayout.addRow("Output directory:", self.outputDirSelector) if not self.outputDirSelector.currentPath: defaultOutputPath = os.path.abspath(os.path.join(slicer.app.defaultScenePath,'SlicerCapture')) self.outputDirSelector.setCurrentPath(defaultOutputPath) self.captureAllViewsCheckBox = qt.QCheckBox(" ") self.captureAllViewsCheckBox.checked = False self.captureAllViewsCheckBox.setToolTip("If checked, all views will be captured. If unchecked then only the selected view will be captured.") outputFormLayout.addRow("Capture all views:", self.captureAllViewsCheckBox) self.videoExportCheckBox = qt.QCheckBox(" ") self.videoExportCheckBox.checked = False self.videoExportCheckBox.setToolTip("If checked, exported images will be written as a video file." " Requires setting of ffmpeg executable path in Advanced section.") self.videoFormatWidget = qt.QComboBox() self.videoFormatWidget.enabled = False self.videoFormatWidget.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Preferred) for videoFormatPreset in self.logic.videoFormatPresets: self.videoFormatWidget.addItem(videoFormatPreset["name"]) hbox = qt.QHBoxLayout() hbox.addWidget(self.videoExportCheckBox) hbox.addWidget(self.videoFormatWidget) outputFormLayout.addRow("Video export:", hbox) self.videoFileNameWidget = qt.QLineEdit() self.videoFileNameWidget.setToolTip("String that defines file name and type.") self.videoFileNameWidget.text = "SlicerCapture.avi" self.videoFileNameWidget.setEnabled(False) outputFormLayout.addRow("Video file name:", self.videoFileNameWidget) self.videoLengthSliderWidget = ctk.ctkSliderWidget() self.videoLengthSliderWidget.singleStep = 0.1 self.videoLengthSliderWidget.minimum = 0.1 self.videoLengthSliderWidget.maximum = 30 self.videoLengthSliderWidget.value = 5 self.videoLengthSliderWidget.suffix = "s" self.videoLengthSliderWidget.decimals = 1 self.videoLengthSliderWidget.setToolTip("Length of the exported video in seconds (without backward steps and repeating).") self.videoLengthSliderWidget.setEnabled(False) outputFormLayout.addRow("Video length:", self.videoLengthSliderWidget) # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = True outputFormLayout.addRow(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) self.forwardBackwardCheckBox = qt.QCheckBox(" ") self.forwardBackwardCheckBox.checked = False self.forwardBackwardCheckBox.setToolTip("If checked, image series will be generated playing forward and then backward.") advancedFormLayout.addRow("Forward-backward:", self.forwardBackwardCheckBox) self.repeatSliderWidget = ctk.ctkSliderWidget() self.repeatSliderWidget.decimals = 0 self.repeatSliderWidget.singleStep = 1 self.repeatSliderWidget.minimum = 1 self.repeatSliderWidget.maximum = 50 self.repeatSliderWidget.value = 1 self.repeatSliderWidget.setToolTip("Number of times image series are repeated. Useful for making short videos longer for playback in software" " that does not support looped playback.") advancedFormLayout.addRow("Repeat:", self.repeatSliderWidget) ffmpegPath = self.logic.getFfmpegPath() self.ffmpegPathSelector = ctk.ctkPathLineEdit() self.ffmpegPathSelector.setCurrentPath(ffmpegPath) self.ffmpegPathSelector.nameFilters = [self.logic.getFfmpegExecutableFilename()] self.ffmpegPathSelector.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Preferred) self.ffmpegPathSelector.setToolTip("Set the path to ffmpeg executable. Download from: https://www.ffmpeg.org/") advancedFormLayout.addRow("ffmpeg executable:", self.ffmpegPathSelector) self.videoExportFfmpegWarning = qt.QLabel('<qt><b><font color="red">Set valid ffmpeg executable path! '+ '<a href="http://wiki.slicer.org/slicerWiki/index.php/Documentation/Nightly/Modules/ScreenCapture#Setting_up_ffmpeg">Help...</a></font></b></qt>') self.videoExportFfmpegWarning.connect('linkActivated(QString)', self.openURL) self.videoExportFfmpegWarning.setVisible(False) advancedFormLayout.addRow("", self.videoExportFfmpegWarning) self.extraVideoOptionsWidget = qt.QLineEdit() self.extraVideoOptionsWidget.setToolTip('Additional video conversion options passed to ffmpeg. Parameters -i (input files), -y' +'(overwrite without asking), -r (frame rate), -start_number are specified by the module and therefore' +'should not be included in this list.') advancedFormLayout.addRow("Video extra options:", self.extraVideoOptionsWidget) self.fileNamePatternWidget = qt.QLineEdit() self.fileNamePatternWidget.setToolTip( "String that defines file name, type, and numbering scheme. Default: image%05d.png.") self.fileNamePatternWidget.text = "image_%05d.png" advancedFormLayout.addRow("Image file name pattern:", self.fileNamePatternWidget) self.maxFramesWidget = qt.QSpinBox() self.maxFramesWidget.setRange(1, 9999) self.maxFramesWidget.setValue(600) self.maxFramesWidget.setToolTip( "Maximum number of images to be captured (without backward steps and repeating).") advancedFormLayout.addRow("Maximum number of images:", self.maxFramesWidget) # Capture button self.captureButtonLabelCapture = "Capture" self.captureButtonLabelCancel = "Cancel" self.captureButton = qt.QPushButton(self.captureButtonLabelCapture) self.captureButton.toolTip = "Capture slice sweep to image sequence." self.showCreatedOutputFileButton = qt.QPushButton() self.showCreatedOutputFileButton.setIcon(qt.QIcon(':Icons/Go.png')) self.showCreatedOutputFileButton.setMaximumWidth(60) self.showCreatedOutputFileButton.enabled = False self.showCreatedOutputFileButton.toolTip = "Show created output file." hbox = qt.QHBoxLayout() hbox.addWidget(self.captureButton) hbox.addWidget(self.showCreatedOutputFileButton) self.layout.addLayout(hbox) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) self.statusLabel.setCenterOnScroll(True) self.layout.addWidget(self.statusLabel) # # Add vertical spacer # self.layout.addStretch(1) # connections self.captureButton.connect('clicked(bool)', self.onCaptureButton) self.showCreatedOutputFileButton.connect('clicked(bool)', self.onShowCreatedOutputFile) self.viewNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions) self.animationModeWidget.connect("currentIndexChanged(int)", self.updateViewOptions) self.sliceStartOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset) self.sliceEndOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset) self.sequenceBrowserNodeSelectorWidget.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions) self.sequenceStartItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex) self.sequenceEndItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex) self.videoExportCheckBox.connect('toggled(bool)', self.fileNamePatternWidget, 'setDisabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.videoFileNameWidget, 'setEnabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.videoLengthSliderWidget, 'setEnabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.videoFormatWidget, 'setEnabled(bool)') self.videoFormatWidget.connect("currentIndexChanged(int)", self.updateVideoFormat) self.singleStepButton.connect('toggled(bool)', self.numberOfStepsSliderWidget, 'setDisabled(bool)') self.maxFramesWidget.connect('valueChanged(int)', self.maxFramesChanged) self.updateVideoFormat(0) self.updateViewOptions()
def setupOptionsFrame(self): self.intensityToleranceSlider = ctk.ctkSliderWidget() self.intensityToleranceSlider.setToolTip("Tolerance.") self.intensityToleranceSlider.minimum = 0.01 self.intensityToleranceSlider.maximum = 1000.0 self.intensityToleranceSlider.value = 10 self.intensityToleranceSlider.singleStep = 1.0 self.intensityToleranceSlider.pageStep = 5.0 self.intensityToleranceLabel = self.scriptedEffect.addLabeledOptionsWidget( "Intensity tolerance:", self.intensityToleranceSlider) self.neighborhoodSizeMmSlider = ctk.ctkSliderWidget() self.neighborhoodSizeMmSlider.setToolTip( "Regions are added only if all voxels in the neighborhood have similar intensities." "Use higher values prevent leakage. Use lower values to allow capturing finer details." ) self.neighborhoodSizeMmSlider.minimum = 0.01 self.neighborhoodSizeMmSlider.maximum = 30.0 self.neighborhoodSizeMmSlider.value = 1.0 self.neighborhoodSizeMmSlider.singleStep = 0.01 self.neighborhoodSizeMmSlider.pageStep = 0.5 self.neighborhoodSizeLabel = self.scriptedEffect.addLabeledOptionsWidget( "Neighborhood size:", self.neighborhoodSizeMmSlider) self.neighborhoodSizeMmSlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.intensityToleranceSlider.connect("valueChanged(double)", self.updateMRMLFromGUI)
def __init__(self): toolTip = 'Smooth the warp field. Click and hold to preview, double-click to aply. Save current state to enable.' WarpAbstractEffect.__init__(self, 'Smooth', toolTip) # sigma self.sigmaSlider = ctk.ctkSliderWidget() self.sigmaSlider.singleStep = 1 self.sigmaSlider.minimum = 0 self.sigmaSlider.maximum = 30 self.sigmaSlider.decimals = 0 self.sigmaSlider.value = float( self.parameterNode.GetParameter("SmoothSigma")) self.sigmaSlider.setToolTip('Smoothing sigma') self.parametersFrame.layout().addRow("Sigma (mm):", self.sigmaSlider) # use radius / hole image self.useRadiusCheckbox = qt.QCheckBox() self.useRadiusCheckbox.setChecked( int(self.parameterNode.GetParameter("SmoothUseRadius"))) self.useRadiusCheckbox.setToolTip( 'Use radius to focus editable area. Otherwise the hole warp will be modified.' ) self.parametersFrame.layout().addRow("Use Radius:", self.useRadiusCheckbox) # radius self.radiusSlider = ctk.ctkSliderWidget() self.radiusSlider.singleStep = 0.1 self.radiusSlider.minimum = 5 self.radiusSlider.maximum = float( self.parameterNode.GetParameter("maxRadius")) self.radiusSlider.decimals = 1 self.radiusSlider.value = float( self.parameterNode.GetParameter("SmoothRadius")) self.radiusSlider.setToolTip('Radius') self.parametersFrame.layout().addRow("Radius (mm):", self.radiusSlider) # hardness self.hardnessSlider = ctk.ctkSliderWidget() self.hardnessSlider.singleStep = 1 self.hardnessSlider.minimum = 0 self.hardnessSlider.maximum = 100 self.hardnessSlider.decimals = 0 self.hardnessSlider.value = float( self.parameterNode.GetParameter("SmoothHardness")) self.hardnessSlider.setToolTip('Hardness') self.parametersFrame.layout().addRow("Hardness (%):", self.hardnessSlider) self.radiusSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.hardnessSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.sigmaSlider.connect('valueChanged(double)', self.updateMRMLFromGUI) self.useRadiusCheckbox.connect('toggled(bool)', self.updateMRMLFromGUI)
def create(self): super(FastMarchingEffectOptions, self).create() self.defaultMaxPercent = 30 self.percentLabel = qt.QLabel( 'Expected structure volume as % of image volume:', self.frame) self.percentLabel.setToolTip( 'Segmentation will grow from the seed label until this value is reached' ) self.frame.layout().addWidget(self.percentLabel) self.widgets.append(self.percentLabel) self.percentMax = ctk.ctkSliderWidget(self.frame) self.percentMax.minimum = 0 self.percentMax.maximum = 100 self.percentMax.singleStep = 1 self.percentMax.value = self.defaultMaxPercent self.percentMax.setToolTip( 'Approximate volume of the structure to be segmented relative to the total volume of the image' ) self.frame.layout().addWidget(self.percentMax) self.widgets.append(self.percentMax) self.percentMax.connect('valueChanged(double)', self.percentMaxChanged) self.march = qt.QPushButton("March", self.frame) self.march.setToolTip( "Perform the Marching operation into the current label map") self.frame.layout().addWidget(self.march) self.widgets.append(self.march) self.percentVolume = qt.QLabel('Maximum volume of the structure: ') self.percentVolume.setToolTip('Total maximum volume') self.frame.layout().addWidget(self.percentVolume) self.widgets.append(self.percentVolume) self.marcher = ctk.ctkSliderWidget(self.frame) self.marcher.minimum = 0 self.marcher.maximum = 1 self.marcher.singleStep = 0.01 self.marcher.enabled = False self.frame.layout().addWidget(self.marcher) self.widgets.append(self.marcher) self.marcher.connect('valueChanged(double)', self.onMarcherChanged) HelpButton( self.frame, "To use FastMarching effect, first mark the areas that belong to the structure of interest to initialize the algorithm. Define the expected volume of the structure you are trying to segment, and hit March.\nAfter computation is complete, use the Marcher slider to go over the segmentation history." ) self.march.connect('clicked()', self.onMarch) # Add vertical spacer self.frame.layout().addStretch(1) self.percentMaxChanged(self.percentMax.value)
def create(self): super(FastMarchingEffectOptions, self).create() self.defaultMaxPercent = 30 self.percentLabel = qt.QLabel("Expected structure volume as % of image volume:", self.frame) self.percentLabel.setToolTip("Segmentation will grow from the seed label until this value is reached") self.frame.layout().addWidget(self.percentLabel) self.widgets.append(self.percentLabel) self.percentMax = ctk.ctkSliderWidget(self.frame) self.percentMax.minimum = 0 self.percentMax.maximum = 100 self.percentMax.singleStep = 1 self.percentMax.value = self.defaultMaxPercent self.percentMax.setToolTip( "Approximate volume of the structure to be segmented relative to the total volume of the image" ) self.frame.layout().addWidget(self.percentMax) self.widgets.append(self.percentMax) self.percentMax.connect("valueChanged(double)", self.percentMaxChanged) self.march = qt.QPushButton("March", self.frame) self.march.setToolTip("Perform the Marching operation into the current label map") self.frame.layout().addWidget(self.march) self.widgets.append(self.march) self.percentVolume = qt.QLabel("Maximum volume of the structure: ") self.percentVolume.setToolTip("Total maximum volume") self.frame.layout().addWidget(self.percentVolume) self.widgets.append(self.percentVolume) self.marcher = ctk.ctkSliderWidget(self.frame) self.marcher.minimum = 0 self.marcher.maximum = 1 self.marcher.singleStep = 0.01 self.marcher.enabled = False self.frame.layout().addWidget(self.marcher) self.widgets.append(self.marcher) self.marcher.connect("valueChanged(double)", self.onMarcherChanged) HelpButton( self.frame, "To use FastMarching effect, first mark the areas that belong to the structure of interest to initialize the algorithm. Define the expected volume of the structure you are trying to segment, and hit March.\nAfter computation is complete, use the Marcher slider to go over the segmentation history.", ) self.march.connect("clicked()", self.onMarch) # Add vertical spacer self.frame.layout().addStretch(1) self.percentMaxChanged(self.percentMax.value)
def nucleus_segmentation_parameters(self): """ Nucleus segmentation parameters (Yi Gao's algorithm) :return: """ nucleusSegCollapsibleButton = ctk.ctkCollapsibleButton() nucleusSegCollapsibleButton.text = "Nucleus Segmentation Parameters (Yi Gao)" nucleusSegCollapsibleButton.collapsed = True self.frame.layout().addWidget(nucleusSegCollapsibleButton) # Layout within the parameter button nucleusSegFormLayout = qt.QFormLayout(nucleusSegCollapsibleButton) frameOtsuSlider = ctk.ctkSliderWidget() frameOtsuSlider.connect('valueChanged(double)', self.OtsuSliderValueChanged) frameOtsuSlider.decimals = 0 frameOtsuSlider.minimum = 0 frameOtsuSlider.maximum = 10 frameOtsuSlider.value = 1.0 nucleusSegFormLayout.addRow("Otsu Threshold:", frameOtsuSlider) frameCurvatureWeightSlider = ctk.ctkSliderWidget() frameCurvatureWeightSlider.connect('valueChanged(double)', self.CurvatureWeightSliderValueChanged) frameCurvatureWeightSlider.decimals = 0 frameCurvatureWeightSlider.minimum = 0 frameCurvatureWeightSlider.maximum = 10 frameCurvatureWeightSlider.value = 8 nucleusSegFormLayout.addRow("Curvature Weight:", frameCurvatureWeightSlider) frameSizeThldSlider = ctk.ctkSliderWidget() frameSizeThldSlider.connect('valueChanged(double)', self.SizeThldSliderValueChanged) frameSizeThldSlider.decimals = 0 frameSizeThldSlider.minimum = 1 frameSizeThldSlider.maximum = 100 frameSizeThldSlider.value = 3 nucleusSegFormLayout.addRow("Size Threshold:", frameSizeThldSlider) frameSizeUpperThldSlider = ctk.ctkSliderWidget() frameSizeUpperThldSlider.connect('valueChanged(double)', self.SizeUpperThldSliderValueChanged) frameSizeUpperThldSlider.decimals = 0 frameSizeUpperThldSlider.minimum = 100 frameSizeUpperThldSlider.maximum = 500 frameSizeUpperThldSlider.value = 300 nucleusSegFormLayout.addRow("Size Upper Threshold:", frameSizeUpperThldSlider) frameMPPSlider = ctk.ctkSliderWidget() frameMPPSlider.connect('valueChanged(double)', self.MPPSliderValueChanged) frameMPPSlider.decimals = 0 frameMPPSlider.minimum = 0 frameMPPSlider.maximum = 100 frameMPPSlider.value = 25 nucleusSegFormLayout.addRow("Size Upper Threshold:", frameMPPSlider)
def setupOptionsFrame(self): self.percentMax = ctk.ctkSliderWidget() self.percentMax.minimum = 0 self.percentMax.maximum = 100 self.percentMax.singleStep = 1 self.percentMax.value = 10 self.percentMax.suffix = '%' self.percentMax.setToolTip( 'Approximate volume of the structure to be segmented as percentage of total volume of the master image.' ' Segmentation will grow from the seed label until this value is reached' ) self.percentMax.connect('valueChanged(double)', self.percentMaxChanged) self.scriptedEffect.addLabeledOptionsWidget("Maximum volume:", self.percentMax) self.march = qt.QPushButton("Initialize") self.march.setToolTip( "Perform the Marching operation into the current label map") self.scriptedEffect.addOptionsWidget(self.march) self.march.connect('clicked()', self.onMarch) self.marcher = ctk.ctkSliderWidget() self.marcher.minimum = 0 self.marcher.maximum = 100 self.marcher.singleStep = 0.1 self.marcher.pageStep = 5 self.marcher.suffix = '%' self.marcher.enabled = False self.marcher.connect('valueChanged(double)', self.onMarcherChanged) self.percentVolume = self.scriptedEffect.addLabeledOptionsWidget( "Segment volume:", self.marcher) self.cancelButton = qt.QPushButton("Cancel") self.cancelButton.objectName = self.__class__.__name__ + 'Cancel' self.cancelButton.setToolTip("Clear preview and cancel") self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Replace segment by previewed result") finishFrame = qt.QHBoxLayout() finishFrame.addWidget(self.cancelButton) finishFrame.addWidget(self.applyButton) self.scriptedEffect.addOptionsWidget(finishFrame) self.cancelButton.connect('clicked()', self.onCancel) self.applyButton.connect('clicked()', self.onApply)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Transparency" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Set Model # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLModelNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Set model: ", self.inputSelector) # # Set transparency # self.opacitySliderWidget = ctk.ctkSliderWidget() self.opacitySliderWidget.singleStep = 0.1 self.opacitySliderWidget.minimum = 0 self.opacitySliderWidget.maximum = 100 self.opacitySliderWidget.value = 50 self.opacitySliderWidget.setToolTip("Set transparency") parametersFormLayout.addRow("Transparency", self.opacitySliderWidget) # # Button # self.applyButton = qt.QPushButton("Show|Hide") self.applyButton.toolTip = "Show or hide model." parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.opacitySliderWidget.connect('valueChanged(double)', self.onSlideChange) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setupOptionsFrame(self): self.autoUpdateCheckBox = qt.QCheckBox("Auto-update") self.autoUpdateCheckBox.setToolTip("Auto-update results preview when input segments change.") self.autoUpdateCheckBox.setChecked(True) self.autoUpdateCheckBox.setEnabled(False) self.previewButton = qt.QPushButton("Initialize") self.previewButton.objectName = self.__class__.__name__ + 'Preview' self.previewButton.setToolTip("Preview complete segmentation") # qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # fails on some systems, therefore set the policies using separate method calls qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) self.previewButton.setSizePolicy(qSize) previewFrame = qt.QHBoxLayout() previewFrame.addWidget(self.autoUpdateCheckBox) previewFrame.addWidget(self.previewButton) self.scriptedEffect.addLabeledOptionsWidget("Preview:", previewFrame) self.previewOpacitySlider = ctk.ctkSliderWidget() self.previewOpacitySlider.setToolTip("Adjust visibility of results preview.") self.previewOpacitySlider.minimum = 0 self.previewOpacitySlider.maximum = 1.0 self.previewOpacitySlider.value = 0.0 self.previewOpacitySlider.singleStep = 0.05 self.previewOpacitySlider.pageStep = 0.1 self.previewOpacitySlider.spinBoxVisible = False self.previewShow3DButton = qt.QPushButton("Show 3D") self.previewShow3DButton.setToolTip("Preview results in 3D.") self.previewShow3DButton.setCheckable(True) displayFrame = qt.QHBoxLayout() displayFrame.addWidget(qt.QLabel("inputs")) displayFrame.addWidget(self.previewOpacitySlider) displayFrame.addWidget(qt.QLabel("results")) displayFrame.addWidget(self.previewShow3DButton) self.scriptedEffect.addLabeledOptionsWidget("Display:", displayFrame) self.cancelButton = qt.QPushButton("Cancel") self.cancelButton.objectName = self.__class__.__name__ + 'Cancel' self.cancelButton.setToolTip("Clear preview and cancel auto-complete") self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Replace segments by previewed result") finishFrame = qt.QHBoxLayout() finishFrame.addWidget(self.cancelButton) finishFrame.addWidget(self.applyButton) self.scriptedEffect.addOptionsWidget(finishFrame) self.previewButton.connect('clicked()', self.onPreview) self.cancelButton.connect('clicked()', self.onCancel) self.applyButton.connect('clicked()', self.onApply) self.previewOpacitySlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.previewShow3DButton.connect("toggled(bool)", self.updateMRMLFromGUI) self.autoUpdateCheckBox.connect("stateChanged(int)", self.updateMRMLFromGUI)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # Collapsible button testsCollapsibleButton = ctk.ctkCollapsibleButton() testsCollapsibleButton.text = "Tests" self.layout.addWidget(testsCollapsibleButton) # Layout within the collapsible button formLayout = qt.QFormLayout(testsCollapsibleButton) # test buttons tests = ( ("Part 1: DICOM", self.onPart1DICOM), ("Part 2: Head", self.onPart2Head), ("Part 3: Liver", self.onPart3Liver), ("Part 4: Lung", self.onPart4Lung), ) for text, slot in tests: testButton = qt.QPushButton(text) testButton.toolTip = "Run the test." formLayout.addWidget(testButton) testButton.connect('clicked(bool)', slot) # A collapsible button to hide screen shot options screenShotsCollapsibleButton = ctk.ctkCollapsibleButton() screenShotsCollapsibleButton.text = "Screen shot options" self.layout.addWidget(screenShotsCollapsibleButton) # layout within the collapsible button screenShotsFormLayout = qt.QFormLayout(screenShotsCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) screenShotsFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip( "Set scale factor for the screen shots.") screenShotsFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # # Parameters # modelSelector = ctk.ctkCollapsibleButton() modelSelector.text = "Models Selector" self.layout.addWidget(modelSelector) # Layout within the dummy collapsible button modelsFormLayout = qt.QFormLayout(modelSelector) # Input model self.modelsSelector = slicer.qMRMLNodeComboBox() self.modelsSelector.nodeTypes = ["vtkMRMLModelNode"] self.modelsSelector.selectNodeUponCreation = True self.modelsSelector.addEnabled = False self.modelsSelector.removeEnabled = True self.modelsSelector.noneEnabled = True self.modelsSelector.showHidden = False self.modelsSelector.showChildNodeTypes = False self.modelsSelector.setMRMLScene(slicer.mrmlScene) self.modelsSelector.setToolTip("Input model selection") modelsFormLayout.addRow("Input model: ", self.modelsSelector) # Opacity self.opacitySlider = ctk.ctkSliderWidget() self.opacitySlider.singleStep = 1 self.opacitySlider.minimum = 0 self.opacitySlider.maximum = 100 self.opacitySlider.value = 50 self.opacitySlider.setToolTip("Opacity selection") modelsFormLayout.addRow("Set opacity:", self.opacitySlider) # Show / Hide self.showHideButton = qt.QPushButton("Show / Hide") self.showHideButton.toolTip = "Show or hide the model" self.showHideButton.enabled = True modelsFormLayout.addRow(self.showHideButton) # Add vertical spacer self.layout.addStretch(5) # # connections # self.showHideButton.connect('clicked(bool)', self.onShowHideButton) self.opacitySlider.connect('valueChanged(double)', self.onSliderValueChanged)
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): self.intensityToleranceSlider = ctk.ctkSliderWidget() self.intensityToleranceSlider.setToolTip("Tolerance.") self.intensityToleranceSlider.minimum = 0.01 self.intensityToleranceSlider.maximum = 1000.0 self.intensityToleranceSlider.value = 10 self.intensityToleranceSlider.singleStep = 1.0 self.intensityToleranceSlider.pageStep = 5.0 self.intensityToleranceLabel = self.scriptedEffect.addLabeledOptionsWidget( "Intensity tolerance:", self.intensityToleranceSlider) self.neighborhoodSizeMmSlider = ctk.ctkSliderWidget() self.neighborhoodSizeMmSlider.setToolTip( "Regions are added only if all voxels in the neighborhood have similar intensities." "Use higher values prevent leakage. Use lower values to allow capturing finer details." ) self.neighborhoodSizeMmSlider.minimum = 0.0 self.neighborhoodSizeMmSlider.maximum = 30.0 self.neighborhoodSizeMmSlider.value = 1.0 self.neighborhoodSizeMmSlider.singleStep = 0.01 self.neighborhoodSizeMmSlider.pageStep = 0.5 self.neighborhoodSizeLabel = self.scriptedEffect.addLabeledOptionsWidget( "Neighborhood size:", self.neighborhoodSizeMmSlider) self.neighborhoodSizeMmSlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.intensityToleranceSlider.connect("valueChanged(double)", self.updateMRMLFromGUI) # 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) self.roiSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateMRMLFromGUI)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 1 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip( "Set scale factor for the screen shots.") parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Rozwijana lista Area # listCollapsibleButton = ctk.ctkCollapsibleButton() listCollapsibleButton.text = "Rozwijana lista" self.layout.addWidget(listCollapsibleButton) # Layout within the dummy collapsible button listFormLayout = qt.QFormLayout(listCollapsibleButton) # # input hide selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLModelNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene( slicer.mrmlScene ) self.inputSelector.setToolTip( "Wybieranie modelu do wczytania." ) listFormLayout.addRow("Wybierz model: ", self.inputSelector) # # opacity value # self.imageOpacitySliderWidget = ctk.ctkSliderWidget() self.imageOpacitySliderWidget.singleStep = 1 self.imageOpacitySliderWidget.minimum = 0 self.imageOpacitySliderWidget.maximum = 100 self.imageOpacitySliderWidget.value = 0 self.imageOpacitySliderWidget.setToolTip("Ustaw przezroczystosc modelu 3D.") listFormLayout.addRow("Przezroczystosc (widocznosc)", self.imageOpacitySliderWidget) # # Show/hide Button # self.showHideButton = qt.QPushButton("Pokaz/Ukryj") self.showHideButton.toolTip = "Ukryj lub pokaz model" self.showHideButton.enabled = True listFormLayout.addRow(self.showHideButton) # connections self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.showHideButton.connect('clicked(bool)', self.onShowHideButton) self.imageOpacitySliderWidget.connect('valueChanged(double)', self.onOpacityChange)
def addSlider(attributes, layout, valueChangedCallback): sliderWidget = ctk.ctkSliderWidget() sliderWidget.singleStep = attributes["singleStep"] sliderWidget.pageStep = attributes["pageStep"] sliderWidget.minimum = attributes["minimum"] sliderWidget.maximum = attributes["maximum"] sliderWidget.value = attributes["value"] sliderWidget.suffix = attributes["unit"] sliderWidget.decimals = attributes["decimals"] sliderWidget.setToolTip(attributes["info"]) sliderWidget.tracking = True sliderWidget.connect('valueChanged(double)', lambda val: valueChangedCallback()) layout.addRow(attributes["name"], sliderWidget) return sliderWidget
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # Collapsible button testsCollapsibleButton = ctk.ctkCollapsibleButton() testsCollapsibleButton.text = "Tests" self.layout.addWidget(testsCollapsibleButton) # Layout within the collapsible button formLayout = qt.QFormLayout(testsCollapsibleButton) # test buttons tests = ( ("Part 1 : Ruler", self.onPart1Ruler),("Part 2: ChangeTracker", self.onPart2ChangeTracker),("Part 3 : PETCT", self.onPart3PETCT) ) for text,slot in tests: testButton = qt.QPushButton(text) testButton.toolTip = "Run the test." formLayout.addWidget(testButton) testButton.connect('clicked(bool)', slot) # A collapsible button to hide screen shot options screenShotsCollapsibleButton = ctk.ctkCollapsibleButton() screenShotsCollapsibleButton.text = "Screen shot options" self.layout.addWidget(screenShotsCollapsibleButton) # layout within the collapsible button screenShotsFormLayout = qt.QFormLayout(screenShotsCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") screenShotsFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.") screenShotsFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # Add vertical spacer self.layout.addStretch(1)
def default_angle_component(self): """ Create and initialize angle widget Returns: ctk.ctkSliderWidget(): Initalized angle widget """ angle_widget = ctk.ctkSliderWidget() angle_widget.singleStep = 0.1 angle_widget.minimum = 0 angle_widget.maximum = 180 angle_widget.value = 90 angle_widget.setToolTip("Set Arc angle of approach.") return angle_widget
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # number of fiducials to add # self.numToAddSliderWidget = ctk.ctkSliderWidget() self.numToAddSliderWidget.singleStep = 1.0 self.numToAddSliderWidget.minimum = 0.0 self.numToAddSliderWidget.maximum = 10000.0 self.numToAddSliderWidget.value = 500.0 self.numToAddSliderWidget.toolTip = "Set the number of fiducials to add." parametersFormLayout.addRow("Number of Fiducials to Add", self.numToAddSliderWidget) # # check box to trigger fewer modify events, adding all the new points # is wrapped inside of a StartModify/EndModify block # self.fewerModifyFlagCheckBox = qt.QCheckBox() self.fewerModifyFlagCheckBox.checked = 0 self.fewerModifyFlagCheckBox.toolTip = 'If checked, wrap adding points inside of a StartModify - EndModify block' parametersFormLayout.addRow("Fewer Modify Events", self.fewerModifyFlagCheckBox) # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 1 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.") parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): self.logic = HerniaAnnotationModuleLogic() ScriptedLoadableModuleWidget.setup(self) self.detectionOn = False self.updateTimer = qt.QTimer() self.updateTimer.setInterval(100) self.updateTimer.setSingleShot(True) self.updateTimer.connect('timeout()', self.onUpdateTimer) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLStreamingVolumeNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Volume: ", self.inputSelector) self.toolOneSelector = slicer.qMRMLNodeComboBox() self.toolOneSelector.nodeTypes = ["vtkMRMLLinearTransformNode"] self.toolOneSelector.selectNodeUponCreation = True self.toolOneSelector.addEnabled = False self.toolOneSelector.removeEnabled = False self.toolOneSelector.noneEnabled = False self.toolOneSelector.showHidden = False self.toolOneSelector.showChildNodeTypes = False self.toolOneSelector.setMRMLScene(slicer.mrmlScene) self.toolOneSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Tool One: ", self.toolOneSelector) self.toolTwoSelector = slicer.qMRMLNodeComboBox() self.toolTwoSelector.nodeTypes = ["vtkMRMLLinearTransformNode"] self.toolTwoSelector.selectNodeUponCreation = True self.toolTwoSelector.addEnabled = False self.toolTwoSelector.removeEnabled = False self.toolTwoSelector.noneEnabled = False self.toolTwoSelector.showHidden = False self.toolTwoSelector.showChildNodeTypes = False self.toolTwoSelector.setMRMLScene(slicer.mrmlScene) self.toolTwoSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Tool Two: ", self.toolTwoSelector) self.modelPathEdit = ctk.ctkPathLineEdit() parametersFormLayout.addRow("Keras model: ", self.modelPathEdit) # # threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 0.05 self.imageThresholdSliderWidget.minimum = 0 self.imageThresholdSliderWidget.maximum = 1.0 self.imageThresholdSliderWidget.value = 0.5 self.imageThresholdSliderWidget.setToolTip( "Set threshold value for class probability.") parametersFormLayout.addRow("Prediction threshold", self.imageThresholdSliderWidget) # # Apply Button # self.applyButton = qt.QPushButton("Start detection") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) self.toolLabel = qt.QLabel("0") toolFont = self.toolLabel.font toolFont.setPointSize(32) self.toolLabel.setFont(toolFont) parametersFormLayout.addRow("Tool: ", self.toolLabel) self.classLabel = qt.QLabel("0") classFont = self.classLabel.font classFont.setPointSize(32) self.classLabel.setFont(classFont) parametersFormLayout.addRow("Tissue: ", self.classLabel) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Path collapsible button pathCollapsibleButton = ctk.ctkCollapsibleButton() pathCollapsibleButton.text = "Path" self.layout.addWidget(pathCollapsibleButton) # Layout within the path collapsible button self.pathFormLayout = qt.QFormLayout(pathCollapsibleButton) # Input volume node selector inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' inputVolumeNodeSelector.toolTip = "Select a fiducial list to define control points for the path." inputVolumeNodeSelector.nodeTypes = ['vtkMRMLVolumeNode'] inputVolumeNodeSelector.noneEnabled = True inputVolumeNodeSelector.addEnabled = False inputVolumeNodeSelector.removeEnabled = False #inputFiducialsNodeSelector.connect('currentNodeChanged(bool)', self.enableOrDisableCreateButton) self.pathFormLayout.addRow("Input Volume:", inputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') btn_select_volume = qt.QPushButton("Select Volume") btn_select_volume.toolTip = "Select working volume." btn_select_volume.enabled = True self.pathFormLayout.addRow(btn_select_volume) btn_select_volume.connect('clicked()', self.onbtn_select_volumeClicked) # Input fiducials node selector inputFiducialsNodeSelector = slicer.qMRMLNodeComboBox() inputFiducialsNodeSelector.objectName = 'inputFiducialsNodeSelector' inputFiducialsNodeSelector.toolTip = "Select a fiducial list to define control points for the path." inputFiducialsNodeSelector.nodeTypes = ['vtkMRMLMarkupsCurveNode'] inputFiducialsNodeSelector.noneEnabled = True inputFiducialsNodeSelector.addEnabled = True inputFiducialsNodeSelector.removeEnabled = True #inputFiducialsNodeSelector.connect('currentNodeChanged(bool)', self.enableOrDisableCreateButton) self.pathFormLayout.addRow("Input Curve:", inputFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # Initialize button - essentially building the path projection model InitializeButton = qt.QPushButton("Select/Update Curve") InitializeButton.toolTip = "Select new or update existing curve." InitializeButton.enabled = True self.pathFormLayout.addRow(InitializeButton) InitializeButton.connect('clicked()', self.onInitializeButtonClicked) # Flythrough collapsible button flythroughCollapsibleButton = ctk.ctkCollapsibleButton() flythroughCollapsibleButton.text = "Slice Controls" flythroughCollapsibleButton.enabled = True #originally FALSE self.layout.addWidget(flythroughCollapsibleButton) # Layout within the Flythrough collapsible button flythroughFormLayout = qt.QFormLayout(flythroughCollapsibleButton) # Frame slider frameSlider = ctk.ctkSliderWidget() frameSlider.connect('valueChanged(double)', self.frameSliderValueChanged) frameSlider.decimals = 0 flythroughFormLayout.addRow("Transverse:", frameSlider) # Slice rotate slider rotateView = ctk.ctkSliderWidget() rotateView.connect('valueChanged(double)', self.rotateViewValueChanged) rotateView.decimals = 0 rotateView.maximum = 360 flythroughFormLayout.addRow("Tangential:", rotateView) # Flythrough collapsible button flythroughCollapsibleButton = ctk.ctkCollapsibleButton() flythroughCollapsibleButton.text = "Free View Controls" flythroughCollapsibleButton.enabled = True #originally FALSE self.layout.addWidget(flythroughCollapsibleButton) # Layout within the Flythrough collapsible button freeviewFormLayout = qt.QFormLayout(flythroughCollapsibleButton) # Frame slider fv_tan_slider = ctk.ctkSliderWidget() fv_tan_slider.connect('valueChanged(double)', self.freeViewValueChanged) fv_tan_slider.decimals = 0 fv_tan_slider.maximum = 360 freeviewFormLayout.addRow("Tangential Angle:", fv_tan_slider) # Slice rotate slider fv_ax_slider = ctk.ctkSliderWidget() fv_ax_slider.connect('valueChanged(double)', self.freeViewValueChanged) fv_ax_slider.decimals = 0 fv_ax_slider.maximum = 360 freeviewFormLayout.addRow("Axial Angle:", fv_ax_slider) """ #Models list addModelButton = qt.QPushButton("Add Model to Pantomograph") addModelButton.toolTip = "Build a list of models to add to the pantomographic reconstruction." flythroughFormLayout.addRow(addModelButton) addModelButton.connect('clicked()', self.onaddModelButtonToggled) # Build Pantomograph button PantomographButton = qt.QPushButton("Build Pantomograph") PantomographButton.toolTip = "Build pantomograph from fiducial path model." flythroughFormLayout.addRow(PantomographButton) PantomographButton.connect('clicked()', self.onPantomographButtonToggled) # Show slice view button sliceViewButton = qt.QPushButton("Show Slice") sliceViewButton.toolTip = "Toggles the slice view as cross-sectioned by the curve path." flythroughFormLayout.addRow(sliceViewButton) sliceViewButton.connect('clicked()', self.onsliceViewButtonToggled) # Show composite view button compositeViewButton = qt.QPushButton("Show Composite") compositeViewButton.toolTip = "Toggles the composite view of averages as cross-sectioned by the curve path." flythroughFormLayout.addRow(compositeViewButton) compositeViewButton.connect('clicked()', self.oncompositeViewButtonToggled) # Flip pantomographs vertical button flipVPanButton = qt.QPushButton("Vertical Flip") flipVPanButton.toolTip = "Flips slice and composite pantomographs vertically." flythroughFormLayout.addRow(flipVPanButton) flipVPanButton.connect('clicked()', self.onflipVPanButtonToggled) """ # Add vertical spacer self.layout.addStretch(1) # Set local var as instance attribute self.inputVolumeNodeSelector = inputVolumeNodeSelector self.inputFiducialsNodeSelector = inputFiducialsNodeSelector self.InitializeButton = InitializeButton self.flythroughCollapsibleButton = flythroughCollapsibleButton self.frameSlider = frameSlider self.rotateView = rotateView self.fv_tan_slider = fv_tan_slider self.fv_ax_slider = fv_ax_slider #self.PantomographButton = PantomographButton #self.selectedModelsList = [] #self.maskedVolumeNode = None #self.frameSlider.maximum = self.curvePoints.GetNumberOfPoints()-2 inputFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) ######################################################################################## XML_layout = """ <layout type="vertical" split="true"> <item splitSize="3"> <layout type="horizontal" split="true"> <item> <view class="vtkMRMLSliceNode" singletontag="Transverse"> <property name="orientation" action="default">Reformat</property> <property name="viewlabel" action="default">TR</property> <property name="viewcolor" action="default">#000000</property> </view> </item> <item> <view class="vtkMRMLSliceNode" singletontag="Red"> <property name="orientation" action="default">Axial</property> <property name="viewlabel" action="default">R</property> <property name="viewcolor" action="default">#F34A33</property> </view> </item> <item> <view class="vtkMRMLSliceNode" singletontag="Yellow"> <property name="orientation" action="default">Sagittal</property> <property name="viewlabel" action="default">Y</property> <property name="viewcolor" action="default">#EDD54C</property> </view> </item> </layout> </item> <item splitSize="2"> <layout type="horizontal" split="true"> <item> <view class="vtkMRMLViewNode" singletontag="1"> <property name="viewlabel" action="default">1</property> </view> </item> <item> <view class="vtkMRMLSliceNode" singletontag="Green"> <property name="orientation" action="default">Coronal</property> <property name="viewlabel" action="default">G</property> <property name="viewcolor" action="default">#6EB04B</property> </view> </item> </layout> </item> </layout> """ # Built-in layout IDs are all below 100, so you can choose any large random number # for your custom layout ID. customLayoutId = 501 #volumeNode = slicer.util.getNode('1*') """ #Creating a dummy slice node for computing # Create slice node (this automatically creates a slice widget) sliceNodeCompute = slicer.mrmlScene.CreateNodeByClass('vtkMRMLSliceNode') sliceNodeCompute.SetName("PanoCompute") sliceNodeCompute.SetLayoutName("PanoCompute") sliceNodeCompute.SetLayoutLabel("PC") sliceNodeCompute.SetOrientation("Sagittal") sliceNodeCompute = slicer.mrmlScene.AddNode(sliceNodeCompute) # Select background volume sliceLogic = slicer.app.applicationLogic().GetSliceLogic(sliceNodeCompute) sliceLogic.GetSliceCompositeNode().SetBackgroundVolumeID(volumeNode.GetID()) """ # Get the automatically created slice widget lm = slicer.app.layoutManager() #sliceWidget=lm.viewWidget(sliceNodeCompute) #controller = lm.sliceWidget("PanoCompute").sliceController() #controller.setSliceVisible(False) #sliceWidget.setParent(None) # Show slice widget lm.layoutLogic().GetLayoutNode().AddLayoutDescription( customLayoutId, XML_layout) # Switch to the new custom layout lm.setLayout(customLayoutId) #Re-load primary volume across all slice nodes #slicer.util.setSliceViewerLayers(background=volumeNode) #enables all slices' views in 3D view #layoutManager = slicer.app.layoutManager() #for sliceViewName in layoutManager.sliceViewNames(): # controller = layoutManager.sliceWidget(sliceViewName).sliceController() # controller.setSliceVisible(True) #enable Transverse & Yellow slice view in 3D viewer transSliceNode = lm.sliceWidget("Transverse").sliceController() transSliceNode.setSliceVisible(True) yellowSliceNode = lm.sliceWidget("Yellow").sliceController() yellowSliceNode.setSliceVisible(True) lm.sliceWidget("Green").sliceController().setSliceVisible(True)
def setup(self): # Instantiate and connect widgets ... # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "RSNAQuantTutorial Reload" self.layout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # reload and test button # (use this during development, but remove it when delivering # your module to users) self.reloadAndTestButton = qt.QPushButton("Reload and Test") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." self.layout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # Collapsible button testsCollapsibleButton = ctk.ctkCollapsibleButton() testsCollapsibleButton.text = "Tests" self.layout.addWidget(testsCollapsibleButton) # Layout within the collapsible button formLayout = qt.QFormLayout(testsCollapsibleButton) # test buttons tests = ( ("Part 1 : Ruler", self.onPart1Ruler),("Part 2: ChangeTracker", self.onPart2ChangeTracker),("Part 3 : PETCT", self.onPart3PETCT) ) for text,slot in tests: testButton = qt.QPushButton(text) testButton.toolTip = "Run the test." formLayout.addWidget(testButton) testButton.connect('clicked(bool)', slot) # A collapsible button to hide screen shot options screenShotsCollapsibleButton = ctk.ctkCollapsibleButton() screenShotsCollapsibleButton.text = "Screen shot options" self.layout.addWidget(screenShotsCollapsibleButton) # layout within the collapsible button screenShotsFormLayout = qt.QFormLayout(screenShotsCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") screenShotsFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.") screenShotsFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # Add vertical spacer self.layout.addStretch(1)
def setup(self): # Instantiate and connect widgets ... # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "FiducialLayoutSwitchBug1914 Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # reload and test button # (use this during development, but remove it when delivering # your module to users) self.reloadAndTestButton = qt.QPushButton("Reload and Test") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 1 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.") parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLModelNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene( slicer.mrmlScene ) self.inputSelector.setToolTip( "Pick the input to the algorithm." ) parametersFormLayout.addRow("Input Model: ", self.inputSelector) # # input texture selector # self.inputTextureSelector = slicer.qMRMLNodeComboBox() self.inputTextureSelector.nodeTypes = ( ("vtkMRMLVectorVolumeNode"), "" ) self.inputTextureSelector.selectNodeUponCreation = True self.inputTextureSelector.addEnabled = False self.inputTextureSelector.removeEnabled = False self.inputTextureSelector.noneEnabled = False self.inputTextureSelector.showHidden = False self.inputTextureSelector.showChildNodeTypes = False self.inputTextureSelector.setMRMLScene( slicer.mrmlScene ) self.inputTextureSelector.setToolTip( "Pick the input to the algorithm." ) parametersFormLayout.addRow("Input Texture: ", self.inputTextureSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ( ("vtkMRMLModelNode"), "" ) self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene( slicer.mrmlScene ) self.outputSelector.setToolTip( "Pick the output to the algorithm." ) parametersFormLayout.addRow("Output Volume: ", self.outputSelector) # # Red threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 1 self.imageThresholdSliderWidget.minimum = 0 self.imageThresholdSliderWidget.maximum = 255 self.imageThresholdSliderWidget.value = 0 self.imageThresholdSliderWidget.setToolTip("Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero.") #parametersFormLayout.addRow("Red value", self.imageThresholdSliderWidget) # # Green threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 1 self.imageThresholdSliderWidget.minimum = 0 self.imageThresholdSliderWidget.maximum = 255 self.imageThresholdSliderWidget.value = 0 self.imageThresholdSliderWidget.setToolTip("Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero.") #parametersFormLayout.addRow("Green value", self.imageThresholdSliderWidget) # # Blue threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 1 self.imageThresholdSliderWidget.minimum = 0 self.imageThresholdSliderWidget.maximum = 255 self.imageThresholdSliderWidget.value = 0 self.imageThresholdSliderWidget.setToolTip("Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero.") #parametersFormLayout.addRow("Blue value", self.imageThresholdSliderWidget) # # +/- threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 1 self.imageThresholdSliderWidget.minimum = 0 self.imageThresholdSliderWidget.maximum = 255 self.imageThresholdSliderWidget.value = 0 self.imageThresholdSliderWidget.setToolTip("Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero.") #parametersFormLayout.addRow("+/- Threshold", self.imageThresholdSliderWidget) # # Texture Selection # self.textureSelector = qt.QComboBox() parametersFormLayout.addRow("Texture:", self.textureSelector) self.textureSelector.addItem('Bone') self.textureSelector.addItem('Muscle') self.textureSelector.addItem('Tendon') self.textureSelector.addItem('Cartilage') # # Apply Button # self.applyButton = qt.QPushButton("Apply Texture") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # # Export Triangles Button # self.segmentButton = qt.QPushButton("Export Triangles") self.segmentButton.toolTip = "Export data to be segmented" self.segmentButton.enabled = False parametersFormLayout.addRow(self.segmentButton) # # Import Segmentation Data # self.importButton = qt.QPushButton("Import Segmented Data") self.importButton.toolTip = "Load in segmented data" self.importButton.enabled = False parametersFormLayout.addRow(self.importButton) # # Surface Area Display # self.surfaceAreaDisplay = qt.QLineEdit("Surface Area: ") parametersFormLayout.addRow(self.surfaceAreaDisplay) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.segmentButton.connect('clicked(bool)',self.onSegmentButton) self.importButton.connect('clicked(bool)',self.onImportButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.inputTextureSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.textureSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... #clear scene # slicer.mrmlScene.Clear(0) #Define Widgets layout lm = slicer.app.layoutManager() lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutThreeOverThreeView) lm.sliceWidget('Red').setSliceOrientation('Axial') lm.sliceWidget('Red+').setSliceOrientation('Axial') lm.sliceWidget('Yellow').setSliceOrientation('Axial') lm.sliceWidget('Yellow+').setSliceOrientation('Axial') lm.sliceWidget('Green').setSliceOrientation('Axial') lm.sliceWidget('Green+').setSliceOrientation('Axial') # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") #parametersFormLayout.addRow("Input Volume: ", self.inputSelector) Por ahora no lo mostramos. # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip("Pick the output to the algorithm.") parametersFormLayout.addRow("Volume: ", self.outputSelector) # # Take Working Image Button # self.takeImageButton = qt.QPushButton("Take working image") self.takeImageButton.toolTip = "Take working image" self.takeImageButton.enabled = True parametersFormLayout.addRow(self.takeImageButton) # # Processing selector # self.processingSelector = qt.QComboBox() self.processingSelector.addItem("original") self.processingSelector.addItem("image smoothing") self.processingSelector.addItem("image segmentation") self.processingSelector.addItem("image segmentation + no holes") self.processingSelector.addItem("contouring") parametersFormLayout.addRow("Processing: ", self.processingSelector) # # SpinBoxes : numerical inputs # self.segmentationGroupBox = qt.QGroupBox("Segmentation Data") self.segmentationVBoxLayout = qt.QVBoxLayout() self.tempGroupBox = qt.QGroupBox("Temperature") self.tempHBoxLayout = qt.QHBoxLayout() self.qlabelMin = QLabel('Min:') self.doubleMinTemp = ctk.ctkSliderWidget() self.doubleMinTemp.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.doubleMinTemp.setDecimals(2) self.doubleMinTemp.setValue(27.0) self.tempHBoxLayout.addWidget(self.qlabelMin) self.tempHBoxLayout.addWidget(self.doubleMinTemp) self.labelMax = qt.QLabel("Max: ") self.doubleMaxTemp = ctk.ctkSliderWidget() self.doubleMaxTemp.setValue(35.0) self.tempHBoxLayout.addWidget(self.labelMax) self.tempHBoxLayout.addWidget(self.doubleMaxTemp) self.tempGroupBox.setLayout(self.tempHBoxLayout) self.segmentationVBoxLayout.addWidget(self.tempGroupBox) # # Button to get foot seed # self.seedBoxesGroup = qt.QGroupBox("Seed") frameControlHBox = qt.QVBoxLayout() self.seedCoords = {} # Seed Left selector self.seedLeftFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget( ) self.seedLeftFiducialsNodeSelector.objectName = 'seedLeftFiducialsNodeSelector' self.seedLeftFiducialsNodeSelector.toolTip = "Select a fiducial to use as the origin of the left segments." self.seedLeftFiducialsNodeSelector.setNodeBaseName("Left") self.seedLeftFiducialsNodeSelector.defaultNodeColor = qt.QColor( 0, 255, 0) self.seedLeftFiducialsNodeSelector.tableWidget().hide() self.seedLeftFiducialsNodeSelector.markupsSelectorComboBox( ).noneEnabled = False self.seedLeftFiducialsNodeSelector.markupsPlaceWidget( ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup self.seedLeftFiducialsNodeSelector.markupsPlaceWidget( ).buttonsVisible = False self.seedLeftFiducialsNodeSelector.markupsPlaceWidget().placeButton( ).show() self.seedLeftFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) self.seedFiducialsBox = qt.QHBoxLayout() self.seedLabelWidget = qt.QLabel("Choose left seed node:") self.seedFiducialsBox.addWidget(self.seedLabelWidget) self.seedFiducialsBox.addWidget(self.seedLeftFiducialsNodeSelector) self.leftFiducial = qt.QGroupBox("Left: ") self.leftFiducial.setLayout(self.seedFiducialsBox) # Seed Right selector self.seedRightFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget( ) self.seedRightFiducialsNodeSelector.objectName = 'seedRightFiducialsNodeSelector' self.seedRightFiducialsNodeSelector.toolTip = "Select a fiducial to use as the origin of the left segments." self.seedRightFiducialsNodeSelector.setNodeBaseName("Right") self.seedRightFiducialsNodeSelector.defaultNodeColor = qt.QColor( 0, 255, 0) self.seedRightFiducialsNodeSelector.tableWidget().hide() self.seedRightFiducialsNodeSelector.markupsSelectorComboBox( ).noneEnabled = False self.seedRightFiducialsNodeSelector.markupsPlaceWidget( ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup self.seedRightFiducialsNodeSelector.markupsPlaceWidget( ).buttonsVisible = False self.seedRightFiducialsNodeSelector.markupsPlaceWidget().placeButton( ).show() self.seedRightFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) seedRightFiducialsNodeSelector = self.seedRightFiducialsNodeSelector self.seedRightFiducialsBox = qt.QHBoxLayout() self.seedRightLabelWidget = qt.QLabel("Choose right seed node:") self.seedRightFiducialsBox.addWidget(self.seedRightLabelWidget) self.seedRightFiducialsBox.addWidget( self.seedRightFiducialsNodeSelector) self.rightFiducial = qt.QGroupBox("Right: ") self.rightFiducial.setLayout(self.seedRightFiducialsBox) frameControlHBox.addWidget(self.leftFiducial) frameControlHBox.addWidget(self.rightFiducial) self.seedBoxesGroup.setLayout(frameControlHBox) self.segmentationVBoxLayout.addWidget(self.seedBoxesGroup) # #Set Group self.segmentationGroupBox.setLayout(self.segmentationVBoxLayout) parametersFormLayout.addRow(self.segmentationGroupBox) # # Processing Button # self.extractButton = qt.QPushButton("Apply Segmentation") self.extractButton.toolTip = "Run the algorithm." # self.extractButton.enabled = False parametersFormLayout.addRow(self.extractButton) # connections self.extractButton.connect('clicked(bool)', self.onExtractButton) self.takeImageButton.connect('clicked(bool)', self.onTakeImageButton) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectWorkingImage) self.processingSelector.connect('currentIndexChanged(QString)', self.onProcessing) # self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # Add vertical spacer self.layout.addStretch(1)
def setup(self): # ScriptedLoadableModuleWidget.setup(self) # # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Input Parameters Area # parametersInputCollapsibleButton = ctk.ctkCollapsibleButton() parametersInputCollapsibleButton.text = "Input/Output Parameters" self.layout.addWidget(parametersInputCollapsibleButton) # Layout within the dummy collapsible button parametersInputFormLayout = qt.QFormLayout(parametersInputCollapsibleButton) # TODO pensar em dar um upgrade no algoritmo...colocar um tratamento de imagem similar ao BET, fazendo um histograma cumulativo e retirar os valores menores que 2% e maiores que 98%...assim retira o sinal outlier da imagem que pode dar problema para estimar a curva sigmoidal...caso estranho no dado MICCAI2016 SATH # # input T1 volume selector # self.inputT1Selector = slicer.qMRMLNodeComboBox() self.inputT1Selector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputT1Selector.selectNodeUponCreation = False self.inputT1Selector.addEnabled = False self.inputT1Selector.removeEnabled = True self.inputT1Selector.noneEnabled = False self.inputT1Selector.showHidden = False self.inputT1Selector.showChildNodeTypes = False self.inputT1Selector.setMRMLScene(slicer.mrmlScene) self.inputT1Selector.setToolTip("T1 Volume") parametersInputFormLayout.addRow("T1 Volume ", self.inputT1Selector) # # input FLAIR volume selector # self.inputFLAIRSelector = slicer.qMRMLNodeComboBox() self.inputFLAIRSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputFLAIRSelector.selectNodeUponCreation = False self.inputFLAIRSelector.addEnabled = False self.inputFLAIRSelector.removeEnabled = True self.inputFLAIRSelector.noneEnabled = False self.inputFLAIRSelector.showHidden = False self.inputFLAIRSelector.showChildNodeTypes = False self.inputFLAIRSelector.setMRMLScene(slicer.mrmlScene) self.inputFLAIRSelector.setToolTip("T2-FLAIR Volume") parametersInputFormLayout.addRow("T2-FLAIR Volume ", self.inputFLAIRSelector) # # output label selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.renameEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = False self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip( "Output a global lesion mask.") parametersInputFormLayout.addRow("Lesion Label ", self.outputSelector) # # Is brain extracted? # self.setIsBETWidget = ctk.ctkCheckBox() self.setIsBETWidget.setChecked(False) self.setIsBETWidget.setToolTip( "Is the input data (T1 and T2-FLAIR) already brain extracted?") parametersInputFormLayout.addRow("Is brain extracted?", self.setIsBETWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersInputFormLayout.addRow(self.applyButton) # # Segmentation Parameters Area # parametersSegmentationParametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersSegmentationParametersCollapsibleButton.text = "Segmentation Parameters" self.layout.addWidget(parametersSegmentationParametersCollapsibleButton) # Layout within the dummy collapsible button parametersSegmentationFormLayout = qt.QFormLayout(parametersSegmentationParametersCollapsibleButton) # # Absolute Error Threshold # self.setAbsErrorThresholdWidget = ctk.ctkSliderWidget() self.setAbsErrorThresholdWidget.singleStep = 0.01 self.setAbsErrorThresholdWidget.minimum = 0.01 self.setAbsErrorThresholdWidget.maximum = 0.99 self.setAbsErrorThresholdWidget.value = 0.1 self.setAbsErrorThresholdWidget.setToolTip( "Define the absolute error threshold for gray matter statistics. This measure evaluated the similarity between the MNI152 template " "and the T2-FLAIR gray matter fluctuation estimative. A higher error gives a higher variability in the final lesion segmentation.") parametersSegmentationFormLayout.addRow("Absolute Error Threshold", self.setAbsErrorThresholdWidget) # # Gamma Search Matching # self.setGammaWidget = ctk.ctkSliderWidget() self.setGammaWidget.minimum = 0.1 self.setGammaWidget.maximum = 4.0 self.setGammaWidget.singleStep = 0.1 self.setGammaWidget.value = 2.0 self.setGammaWidget.setToolTip( "Define the outlier detection based on units of standard deviation in the T2-FLAIR gray matter voxel intensity distribution.") parametersSegmentationFormLayout.addRow("Gamma ", self.setGammaWidget) # # White Matter Search Matching # self.setWMMatchWidget = ctk.ctkSliderWidget() self.setWMMatchWidget.minimum = 0.1 self.setWMMatchWidget.maximum = 1.0 self.setWMMatchWidget.singleStep = 0.1 self.setWMMatchWidget.value = 0.6 self.setWMMatchWidget.setToolTip("Set the local neighborhood searching for label refinement step. This metric defines the percentage of white matter" " tissue surrounding the hyperintense lesions. Large values defines a conservative segmentation, i.e. in order to define a true MS lesion" "it must be close to certain percentage of white matter area.") parametersSegmentationFormLayout.addRow("White Matter Matching ", self.setWMMatchWidget) # # Minimum Lesion Size # self.setMinimumLesionWidget = qt.QSpinBox() self.setMinimumLesionWidget.setMinimum(1) self.setMinimumLesionWidget.setMaximum(5000) self.setMinimumLesionWidget.setValue(10) self.setMinimumLesionWidget.setToolTip( "Set the minimum lesion size adopted as a true lesion in the final lesion map. Units given in number of voxels.") parametersSegmentationFormLayout.addRow("Minimum Lesion Size ", self.setMinimumLesionWidget) # # Gray Matter Label # self.setGMLabelWidget = qt.QSpinBox() self.setGMLabelWidget.setMinimum(1) self.setGMLabelWidget.setMaximum(255) self.setGMLabelWidget.setValue(2) self.setGMLabelWidget.setToolTip( "Set the mask value that represents the gray matter. Default is defined based on the Basic Brain Tissues module output.") parametersSegmentationFormLayout.addRow("Gray Matter Label Value ", self.setGMLabelWidget) # # Minimum Lesion Size # self.setWMLabelWidget = qt.QSpinBox() self.setWMLabelWidget.setMinimum(1) self.setWMLabelWidget.setMaximum(255) self.setWMLabelWidget.setValue(3) self.setWMLabelWidget.setToolTip( "et the mask value that represents the white matter. Default is defined based on the Basic Brain Tissues module output.") parametersSegmentationFormLayout.addRow("White Matter Label Value ", self.setWMLabelWidget) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputT1Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.inputFLAIRSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def create(self): self.params = {} self.cparams = {"algorithm":"Yi"} status = EditUtil.EditUtil().getParameterNode().GetParameter('QuickTCGAEffect,erich') if (status == "reset"): params = {} super(QuickTCGAEffectOptions,self).create() # self.helpLabel = qt.QLabel("Press Y to run automatic segmentation on the current image using given parameters.", self.frame) # self.frame.layout().addWidget(self.helpLabel) #self.clearButton = qt.QPushButton(self.frame) #self.clearButton.text = "Clear Selection" #self.frame.layout().addWidget(self.clearButton) #self.clearButton.connect('clicked()', self.clearSelection) self.segnoButton = qt.QPushButton(self.frame) self.segnoButton.text = "Run Segmentation No Declumping (fast)" self.frame.layout().addWidget(self.segnoButton) self.segnoButton.connect('clicked()', self.RunSegmenterWO) self.segButton = qt.QPushButton(self.frame) self.segButton.text = "Run Segmentation With Declumping (slow)" self.frame.layout().addWidget(self.segButton) self.segButton.connect('clicked()', self.RunSegmenter) self.outlineButton = qt.QPushButton(self.frame) self.outlineButton.text = "Toggle Outline" self.frame.layout().addWidget(self.outlineButton) self.outlineButton.connect('clicked()', self.toggleOutline) self.wipeButton = qt.QPushButton(self.frame) self.wipeButton.text = "Clear current segmentation label" self.frame.layout().addWidget(self.wipeButton) self.wipeButton.connect('clicked()', self.wipeSegmentation()) self.locRadFrame = qt.QFrame(self.frame) self.locRadFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.locRadFrame) self.widgets.append(self.locRadFrame) # Nucleus segmentation parameters nucleusSegCollapsibleButton = ctk.ctkCollapsibleButton() nucleusSegCollapsibleButton.text = "Nucleus Segmentation Parameters" nucleusSegCollapsibleButton.collapsed = False; self.frame.layout().addWidget(nucleusSegCollapsibleButton) # Nucleus declumping parameters nucleusDeclumpingCollapsibleButton = ctk.ctkCollapsibleButton() nucleusDeclumpingCollapsibleButton.text = "Nucleus Declumping Parameters" nucleusDeclumpingCollapsibleButton.collapsed = False; self.frame.layout().addWidget(nucleusDeclumpingCollapsibleButton) self.structuresView = slicer.util.findChildren(slicer.modules.SlicerPathologyWidget.editorWidget.volumes, 'StructuresView')[0] self.structuresView.connect("activated(QModelIndex)", self.onStructureClickedOrAdded) # Layout within the seg parameter button nucleusSegFormLayout = qt.QFormLayout(nucleusSegCollapsibleButton) # Layout within the declumping parameter button nucleusDeclumpingFormLayout = qt.QFormLayout(nucleusDeclumpingCollapsibleButton) sr = vtk.vtkSliderRepresentation2D() sr.SetHandleSize(10) self.frameOtsuSlider = ctk.ctkSliderWidget() self.frameOtsuSlider.connect('valueChanged(double)', self.OtsuSliderValueChanged) self.frameOtsuSlider.decimals = 1 self.frameOtsuSlider.minimum = 0.5 self.frameOtsuSlider.maximum = 1.5 self.frameOtsuSlider.value = 1.0 self.frameOtsuSlider.singleStep = 0.1 self.frameOtsuSlider.setToolTip("Threshold gain for calling something in the image as nucleus. Run as default value 1.0. Then, if undersegment, increase this to 1.2 and re-run. If oversegment, decrease to 0.8 and re-run. Smaller value of this parameter will give fewer regions segmented as nucleus.") nucleusSegFormLayout.addRow("Threshold Grain:", self.frameOtsuSlider) self.frameCurvatureWeightSlider = ctk.ctkSliderWidget() self.frameCurvatureWeightSlider.connect('valueChanged(double)', self.CurvatureWeightSliderValueChanged) self.frameCurvatureWeightSlider.decimals = 1 self.frameCurvatureWeightSlider.minimum = 0 self.frameCurvatureWeightSlider.maximum = 10 self.frameCurvatureWeightSlider.value = 8 self.frameCurvatureWeightSlider.singleStep = 0.1 self.frameCurvatureWeightSlider.setToolTip("Large value will result in smoother boundary in the resulting segmentation.") nucleusSegFormLayout.addRow("Expected Roundness/Smoothness:", self.frameCurvatureWeightSlider) self.frameSizeThldSlider = ctk.ctkSliderWidget() self.frameSizeThldSlider.connect('valueChanged(double)', self.SizeThldSliderValueChanged) self.frameSizeThldSlider.decimals = 1 self.frameSizeThldSlider.minimum = 1 self.frameSizeThldSlider.maximum = 30 self.frameSizeThldSlider.value = 3 self.frameSizeThldSlider.singleStep = 0.1 self.frameSizeThldSlider.setToolTip("Any object smaller than this value will be discarded.") nucleusSegFormLayout.addRow("Size Lower Threshold:", self.frameSizeThldSlider) self.frameSizeUpperThldSlider = ctk.ctkSliderWidget() self.frameSizeUpperThldSlider.connect('valueChanged(double)', self.SizeUpperThldSliderValueChanged) self.frameSizeUpperThldSlider.decimals = 0 self.frameSizeUpperThldSlider.minimum = 1 self.frameSizeUpperThldSlider.maximum = 500 self.frameSizeUpperThldSlider.value = 50 self.frameSizeUpperThldSlider.setToolTip("Any object larger than this value will be de-clumped.") nucleusDeclumpingFormLayout.addRow("Size Upper Threshold:", self.frameSizeUpperThldSlider) self.frameKernelSizeSlider = ctk.ctkSliderWidget() self.frameKernelSizeSlider.connect('valueChanged(double)', self.KernelSizeSliderValueChanged) self.frameKernelSizeSlider.decimals = 0 self.frameKernelSizeSlider.minimum = 1 self.frameKernelSizeSlider.maximum = 30 self.frameKernelSizeSlider.value = 20 self.frameKernelSizeSlider.setToolTip("Lower this value will result in smaller object in the declumping.") nucleusDeclumpingFormLayout.addRow("Kernel Size:", self.frameKernelSizeSlider) self.frameMPPSlider = ctk.ctkSliderWidget() self.frameMPPSlider.connect('valueChanged(double)', self.MPPSliderValueChanged) self.frameMPPSlider.decimals = 5 self.frameMPPSlider.minimum = 0.01 self.frameMPPSlider.maximum = 1 self.frameMPPSlider.value = 0.25 self.frameMPPSlider.singleStep = 0.01 self.frameMPPSlider.setToolTip("For 40x, this is around 0.25. For 20x, this is around 0.5.") nucleusDeclumpingFormLayout.addRow("Microns Per Pixel:", self.frameMPPSlider) self.DefaultsButton = qt.QPushButton(self.frame) self.DefaultsButton.text = "Default Parameter Values" self.frame.layout().addWidget(self.DefaultsButton) self.DefaultsButton.connect('clicked()', self.ResetToDefaults) #nucleusSegFormLayout.addWidget(self.DefaultsButton) HelpButton(self.frame, ("Otsu threshold:\n Threshold gain for calling something in the image as nucleus. Run as default value 1.0. Then, if undersegment, increase this to 1.2 and re-run. If oversegment, decrease to 0.8 and re-run. Smaller value of this parameter will give fewer regions segmented as nucleus.\n" + "\nCurvature Weight:\n Large value will result in smoother boundary in the resulting segmentation.\n" + "\nSize Threshold:\n Any object smaller than this value will be discarded.\n" + "\nSize Upper Threshold:\n Any object larger than this value will be de-clumped.\n" + "\nKernel size:\n Lower this value will result in smaller object in the declumping.\n" + "\nMicrons Per Pixel:\n For 40x, this is around 0.25. For 20x, this is around 0.5.\n")) self.frame.layout().addStretch(1) # Add vertical spacer self.omode = 0 self.toggleOutline()
def setup(self): # Instantiate and connect widgets ... # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "AddManyMarkupsFiducialTest Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # reload and test button # (use this during development, but remove it when delivering # your module to users) self.reloadAndTestButton = qt.QPushButton("Reload and Test") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # number of fiducials to add # self.numToAddSliderWidget = ctk.ctkSliderWidget() self.numToAddSliderWidget.singleStep = 1.0 self.numToAddSliderWidget.minimum = 0.0 self.numToAddSliderWidget.maximum = 1000.0 self.numToAddSliderWidget.value = 100.0 self.numToAddSliderWidget.toolTip = "Set the number of fiducials to add." parametersFormLayout.addRow("Number of Fiducials to Add", self.numToAddSliderWidget) # # check box to trigger fewer modify events, adding all the new points # is wrapped inside of a StartModify/EndModify block # self.fewerModifyFlagCheckBox = qt.QCheckBox() self.fewerModifyFlagCheckBox.checked = 0 self.fewerModifyFlagCheckBox.toolTip = 'If checked, wrap adding points inside of a StartModify - EndModify block' parametersFormLayout.addRow("Fewer Modify Events", self.fewerModifyFlagCheckBox) # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): self.measurementsLogic = PETLiverUptakeMeasurementQRLogic() ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Liver Uptake Region Segmentation" self.layout.addWidget(parametersCollapsibleButton) parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.addAttribute("vtkMRMLScalarVolumeNode", "DICOM.instanceUIDs", None) #self.inputSelector.addAttribute("vtkMRMLScalarVolumeNode", "DICOM.MeasurementUnitsCodeValue", "{SUVbw}g/ml") # ensures that the input is a SUV normalized PET scan self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene( slicer.mrmlScene ) self.inputSelector.setToolTip( "Input SUVbw normalized DICOM PET volume") self.inputSelector.connect("currentNodeChanged(bool)",self.refreshUIElements) parametersFormLayout.addRow("Input Volume", self.inputSelector) self.segmentationSelector = slicer.qMRMLNodeComboBox() self.segmentationSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.segmentationSelector.selectNodeUponCreation = True self.segmentationSelector.addEnabled = True self.segmentationSelector.removeEnabled = True self.segmentationSelector.noneEnabled = False self.segmentationSelector.showHidden = False self.segmentationSelector.showChildNodeTypes = False self.segmentationSelector.setMRMLScene( slicer.mrmlScene ) self.segmentationSelector.setToolTip( "Output liver reference region volume") self.segmentationSelector.connect("currentNodeChanged(bool)",self.refreshUIElements) parametersFormLayout.addRow("Output Volume", self.segmentationSelector) self.regionSelector = slicer.qMRMLNodeComboBox() self.regionSelector.nodeTypes = ["vtkMRMLAnnotationROINode"] self.regionSelector.selectNodeUponCreation = True self.regionSelector.addEnabled = True self.regionSelector.removeEnabled = True self.regionSelector.noneEnabled = False self.regionSelector.showHidden = False self.regionSelector.showChildNodeTypes = False self.regionSelector.setMRMLScene( slicer.mrmlScene ) self.regionSelector.setToolTip( "Search Region") self.regionSelector.connect("currentNodeChanged(bool)",self.refreshUIElements) parametersFormLayout.addRow("Region", self.regionSelector) self.thresholdRangeSlider = ctk.ctkRangeWidget() self.thresholdRangeSlider.minimum=0.0 self.thresholdRangeSlider.maximum=20.0 self.thresholdRangeSlider.singleStep = 0.1 self.thresholdRangeSlider.minimumValue = 1.0 self.thresholdRangeSlider.maximumValue = 10.0 self.thresholdRangeSlider.connect("minimumValueChanged(double)",self.refreshUIElements) self.thresholdRangeSlider.connect("maximumValueChanged(double)",self.refreshUIElements) parametersFormLayout.addRow("Thresholds", self.thresholdRangeSlider) self.erosionSlider = ctk.ctkSliderWidget() self.erosionSlider.minimum=0.0 self.erosionSlider.maximum=20.0 self.erosionSlider.singleStep=0.1 self.erosionSlider.value = 3.0 self.erosionSlider.connect("valueChanged(double)",self.refreshUIElements) parametersFormLayout.addRow("Erosion", self.erosionSlider) self.segmentButton = qt.QPushButton("Segment Reference Region") self.segmentButton.toolTip = "Segment reference region and measure uptake" self.segmentButton.connect('clicked(bool)', self.onSegmentButton) parametersFormLayout.addRow("Segment",self.segmentButton) # Measurement results measurementsCollapsibleButton = ctk.ctkCollapsibleButton() measurementsCollapsibleButton.text = "Measurements" self.layout.addWidget(measurementsCollapsibleButton) parametersFormLayout = qt.QFormLayout(measurementsCollapsibleButton) self.meanValueLineEdit = qt.QLineEdit("-") self.meanValueLineEdit.setReadOnly(True) self.meanValueLineEdit.setToolTip( "Mean value in reference region") parametersFormLayout.addRow("Mean",self.meanValueLineEdit) self.stdValueLineEdit = qt.QLineEdit("-") self.stdValueLineEdit.setReadOnly(True) self.stdValueLineEdit.setToolTip( "Standard deviation in reference region") parametersFormLayout.addRow("Standard Deviation",self.stdValueLineEdit) self.medianValueLineEdit = qt.QLineEdit("-") self.medianValueLineEdit.setReadOnly(True) self.medianValueLineEdit.setToolTip( "Mean value in reference region") parametersFormLayout.addRow("Median",self.medianValueLineEdit) # Reporting Section dicomReportingCollapsibleButton = ctk.ctkCollapsibleButton() dicomReportingCollapsibleButton.text = "DICOM Reporting" self.layout.addWidget(dicomReportingCollapsibleButton) reportingFormLayout = qt.QFormLayout(dicomReportingCollapsibleButton) self.readerValueLineEdit = qt.QLineEdit(getpass.getuser()) #self.readerValueLineEdit.setReadOnly(True) self.readerValueLineEdit.setToolTip( "Name of reader reporting the measurement results") reportingFormLayout.addRow("Reader Name",self.readerValueLineEdit) self.reportBoxesFrame = qt.QFrame() self.reportBoxesFrame.setLayout(qt.QHBoxLayout()) self.reportBoxesFrame.layout().setSpacing(0) self.reportBoxesFrame.layout().setMargin(0) self.saveReportButton = qt.QPushButton("Save Report") self.saveReportButton.toolTip = "Create partially completed DICOM Structured Report which could be continued at a later time (work in progress)" self.saveReportButton.connect('clicked(bool)', self.onSaveReportButtonClicked) # note: We don't have the functionality to reload and edit a temporary report, so this option doesn't make sense for us #self.reportBoxesFrame.layout().addWidget(self.saveReportButton) self.completeReportButton = qt.QPushButton("Complete Report") self.completeReportButton.toolTip = "Create the completed DICOM Structured Report and save to database" self.completeReportButton.connect('clicked(bool)', self.onCompleteReportButtonClicked) self.reportBoxesFrame.layout().addWidget(self.completeReportButton) reportingFormLayout.addRow("Report",self.reportBoxesFrame) # Add vertical spacer self.layout.addStretch(1) self.refreshUIElements()
def setup(self): # Instantiate and connect widgets ... # # Reload and Test area # reloadCollapsibleButton = ctk.ctkCollapsibleButton() reloadCollapsibleButton.text = "Reload && Test" self.layout.addWidget(reloadCollapsibleButton) reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton) # reload button # (use this during development, but remove it when delivering # your module to users) self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "FiducialLayoutSwitchBug1914 Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # reload and test button # (use this during development, but remove it when delivering # your module to users) self.reloadAndTestButton = qt.QPushButton("Reload and Test") self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests." reloadFormLayout.addWidget(self.reloadAndTestButton) self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 1 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip( "Set scale factor for the screen shots.") parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = ScreenCaptureLogic() self.logic.logCallback = self.addLog self.viewNodeType = None self.animationMode = None # Instantiate and connect widgets ... # # Input area # inputCollapsibleButton = ctk.ctkCollapsibleButton() inputCollapsibleButton.text = "Input" self.layout.addWidget(inputCollapsibleButton) inputFormLayout = qt.QFormLayout(inputCollapsibleButton) # Input view selector self.viewNodeSelector = slicer.qMRMLNodeComboBox() self.viewNodeSelector.nodeTypes = ["vtkMRMLSliceNode", "vtkMRMLViewNode"] self.viewNodeSelector.addEnabled = False self.viewNodeSelector.removeEnabled = False self.viewNodeSelector.noneEnabled = False self.viewNodeSelector.showHidden = False self.viewNodeSelector.showChildNodeTypes = False self.viewNodeSelector.setMRMLScene( slicer.mrmlScene ) self.viewNodeSelector.setToolTip( "Contents of this slice or 3D view will be captured." ) inputFormLayout.addRow("View to capture: ", self.viewNodeSelector) # Mode self.animationModeWidget = qt.QComboBox() self.animationModeWidget.setToolTip("Select the property that will be adjusted") inputFormLayout.addRow("Animation mode:", self.animationModeWidget) # Slice start offset position self.sliceStartOffsetSliderLabel = qt.QLabel("Start sweep offset:") self.sliceStartOffsetSliderWidget = ctk.ctkSliderWidget() self.sliceStartOffsetSliderWidget.singleStep = 30 self.sliceStartOffsetSliderWidget.minimum = -100 self.sliceStartOffsetSliderWidget.maximum = 100 self.sliceStartOffsetSliderWidget.value = 0 self.sliceStartOffsetSliderWidget.setToolTip("Start slice sweep offset.") inputFormLayout.addRow(self.sliceStartOffsetSliderLabel, self.sliceStartOffsetSliderWidget) # Slice end offset position self.sliceEndOffsetSliderLabel = qt.QLabel("End sweep offset:") self.sliceEndOffsetSliderWidget = ctk.ctkSliderWidget() self.sliceEndOffsetSliderWidget.singleStep = 5 self.sliceEndOffsetSliderWidget.minimum = -100 self.sliceEndOffsetSliderWidget.maximum = 100 self.sliceEndOffsetSliderWidget.value = 0 self.sliceEndOffsetSliderWidget.setToolTip("End slice sweep offset.") inputFormLayout.addRow(self.sliceEndOffsetSliderLabel, self.sliceEndOffsetSliderWidget) # 3D start rotation self.startRotationSliderLabel = qt.QLabel("Start rotation angle:") self.startRotationSliderWidget = ctk.ctkSliderWidget() self.startRotationSliderWidget.singleStep = 5 self.startRotationSliderWidget.minimum = 0 self.startRotationSliderWidget.maximum = 180 self.startRotationSliderWidget.value = 180 self.startRotationSliderWidget.setToolTip("Rotation angle for the first image, relative to current orientation.") inputFormLayout.addRow(self.startRotationSliderLabel, self.startRotationSliderWidget) # 3D end rotation self.endRotationSliderLabel = qt.QLabel("End rotation angle:") self.endRotationSliderWidget = ctk.ctkSliderWidget() self.endRotationSliderWidget.singleStep = 5 self.endRotationSliderWidget.minimum = 0 self.endRotationSliderWidget.maximum = 180 self.endRotationSliderWidget.value = 180 self.endRotationSliderWidget.setToolTip("Rotation angle for the last image, relative to current orientation.") inputFormLayout.addRow(self.endRotationSliderLabel, self.endRotationSliderWidget) # Sequence browser node selector self.sequenceBrowserNodeSelectorLabel = qt.QLabel("End rotation angle:") self.sequenceBrowserNodeSelectorWidget = slicer.qMRMLNodeComboBox() self.sequenceBrowserNodeSelectorWidget.nodeTypes = ["vtkMRMLSequenceBrowserNode"] self.sequenceBrowserNodeSelectorWidget.addEnabled = False self.sequenceBrowserNodeSelectorWidget.removeEnabled = False self.sequenceBrowserNodeSelectorWidget.noneEnabled = False self.sequenceBrowserNodeSelectorWidget.showHidden = False self.sequenceBrowserNodeSelectorWidget.setMRMLScene( slicer.mrmlScene ) self.sequenceBrowserNodeSelectorWidget.setToolTip( "Items defined by this sequence browser will be replayed." ) inputFormLayout.addRow(self.sequenceBrowserNodeSelectorLabel, self.sequenceBrowserNodeSelectorWidget) # Sequence start index self.sequenceStartItemIndexLabel = qt.QLabel("Start index:") self.sequenceStartItemIndexWidget = ctk.ctkSliderWidget() self.sequenceStartItemIndexWidget.minimum = 0 self.sequenceStartItemIndexWidget.decimals = 0 self.sequenceStartItemIndexWidget.setToolTip("First item in the sequence to capture.") inputFormLayout.addRow(self.sequenceStartItemIndexLabel, self.sequenceStartItemIndexWidget) # Sequence end index self.sequenceEndItemIndexLabel = qt.QLabel("End index:") self.sequenceEndItemIndexWidget = ctk.ctkSliderWidget() self.sequenceEndItemIndexWidget.singleStep = 10 self.sequenceEndItemIndexWidget.minimum = 0 self.sequenceEndItemIndexWidget.decimals = 0 self.sequenceEndItemIndexWidget.setToolTip("Last item in the sequence to capture.") inputFormLayout.addRow(self.sequenceEndItemIndexLabel, self.sequenceEndItemIndexWidget) # # Output area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) # Number of steps value self.numberOfStepsSliderWidget = ctk.ctkSliderWidget() self.numberOfStepsSliderWidget.singleStep = 10 self.numberOfStepsSliderWidget.minimum = 2 self.numberOfStepsSliderWidget.maximum = 150 self.numberOfStepsSliderWidget.value = 31 self.numberOfStepsSliderWidget.decimals = 0 self.numberOfStepsSliderWidget.setToolTip("Number of images extracted between start and stop positions.") outputFormLayout.addRow("Number of images:", self.numberOfStepsSliderWidget) # Output directory selector self.outputDirSelector = ctk.ctkPathLineEdit() self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.outputDirSelector.settingKey = 'ScreenCaptureOutputDir' outputFormLayout.addRow("Output directory:", self.outputDirSelector) if not self.outputDirSelector.currentPath: defaultOutputPath = os.path.abspath(os.path.join(slicer.app.defaultScenePath,'SlicerCapture')) self.outputDirSelector.setCurrentPath(defaultOutputPath) self.videoExportCheckBox = qt.QCheckBox() self.videoExportCheckBox.checked = False self.videoExportCheckBox.setToolTip("If checked, exported images will be written as a video file." " Requires setting of ffmpeg executable path in Advanced section.") outputFormLayout.addRow("Video export:", self.videoExportCheckBox) self.videoFileNameWidget = qt.QLineEdit() self.videoFileNameWidget.setToolTip("String that defines file name, type, and numbering scheme. Default: capture.avi.") self.videoFileNameWidget.text = "SlicerCapture.avi" self.videoFileNameWidget.setEnabled(False) outputFormLayout.addRow("Video file name:", self.videoFileNameWidget) self.videoLengthSliderWidget = ctk.ctkSliderWidget() self.videoLengthSliderWidget.singleStep = 0.1 self.videoLengthSliderWidget.minimum = 0.1 self.videoLengthSliderWidget.maximum = 30 self.videoLengthSliderWidget.value = 5 self.videoLengthSliderWidget.suffix = "s" self.videoLengthSliderWidget.decimals = 1 self.videoLengthSliderWidget.setToolTip("Length of the exported video in seconds.") self.videoLengthSliderWidget.setEnabled(False) outputFormLayout.addRow("Video length:", self.videoLengthSliderWidget) # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = True outputFormLayout.addRow(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) self.fileNamePatternWidget = qt.QLineEdit() self.fileNamePatternWidget.setToolTip( "String that defines file name, type, and numbering scheme. Default: image%05d.png.") self.fileNamePatternWidget.text = "image_%05d.png" advancedFormLayout.addRow("Image file name pattern:", self.fileNamePatternWidget) ffmpegPath = self.logic.getFfmpegPath() self.ffmpegPathSelector = ctk.ctkPathLineEdit() self.ffmpegPathSelector.setCurrentPath(ffmpegPath) self.ffmpegPathSelector.nameFilters = ['ffmpeg.exe', 'ffmpeg'] self.ffmpegPathSelector.setMaximumWidth(300) self.ffmpegPathSelector.setToolTip("Set the path to ffmpeg executable. Download from: https://www.ffmpeg.org/") advancedFormLayout.addRow("ffmpeg executable:", self.ffmpegPathSelector) self.extraVideoOptionsWidget = qt.QComboBox() self.extraVideoOptionsWidget.addItem("-c:v mpeg4 -qscale:v 5") self.extraVideoOptionsWidget.addItem("-c:v libx264 -preset veryslow -qp 0") self.extraVideoOptionsWidget.addItem("-f mp4 -vcodec libx264 -pix_fmt yuv420p") self.extraVideoOptionsWidget.setEditable(True) self.extraVideoOptionsWidget.setToolTip( '<html>\n' ' <p>Additional video conversion options passed to ffmpeg.</p>' ' <p><b>Examples:</b>' ' <ul>' ' <li><b>MPEG4: </b>-c:v mpeg4 -qscale:v 5</li>' ' <li><b>H264: </b>-c:v libx264 -preset veryslow -qp 0</li>' ' <li><b>Quicktime: </b>-f mp4 -vcodec libx264 -pix_fmt yuv420p</li>' ' </ul></p>' ' <p>See more encoding options at:' ' <i>https://trac.ffmpeg.org/wiki/Encode/H.264</i> and' ' <i>https://trac.ffmpeg.org/wiki/Encode/MPEG-4</i></p>' '</html>') advancedFormLayout.addRow("Video extra options:", self.extraVideoOptionsWidget) # Capture button self.captureButton = qt.QPushButton("Capture") self.captureButton.toolTip = "Capture slice sweep to image sequence." outputFormLayout.addRow(self.captureButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) self.statusLabel.setCenterOnScroll(True) outputFormLayout.addRow(self.statusLabel) # # Add vertical spacer #self.layout.addStretch(1) # connections self.captureButton.connect('clicked(bool)', self.onCaptureButton) self.viewNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions) self.animationModeWidget.connect("currentIndexChanged(int)", self.updateViewOptions) self.sliceStartOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset) self.sliceEndOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset) self.sequenceBrowserNodeSelectorWidget.connect("currentNodeChanged(vtkMRMLNode*)", self.updateViewOptions) self.sequenceStartItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex) self.sequenceEndItemIndexWidget.connect('valueChanged(double)', self.setSequenceItemIndex) self.videoExportCheckBox.connect('toggled(bool)', self.fileNamePatternWidget, 'setDisabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.videoFileNameWidget, 'setEnabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.videoLengthSliderWidget, 'setEnabled(bool)') self.updateViewOptions()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # this section is for custom color box infoGroupBox = qt.QWidget() hbox = qt.QHBoxLayout() hbox.setMargin(0) self.studySelectionGroupBoxLayout = qt.QGridLayout() infoGroupBox.setLayout(hbox) self.studySelectionGroupBoxLayout.addWidget(infoGroupBox, 0, 3, 1, 1) infoIcon = qt.QPixmap(os.path.join(self.resourcesPath, 'Icons', 'icon-infoBox.png')) self.customLUTInfoIcon = qt.QLabel() self.customLUTInfoIcon.setPixmap(infoIcon) self.customLUTInfoIcon.setSizePolicy(PythonQt.QtGui.QSizePolicy()) hbox.addWidget(self.customLUTInfoIcon) self.customLUTLabel = qt.QLabel() hbox.addWidget(self.customLUTLabel) # end of custom color box section self.setupIcons() self.setupTabBarNavigation() self.setupsetupUI() self.setupimageSelectionUI() self.setupsegmentationUI() self.setupsubmissionUI() self.setupEditorWidget() editUtil = EditorLib.EditUtil.EditUtil() self.parameterNode = editUtil.getParameterNode() # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # scale factor for screen shots # self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.") parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # # Apply Button # #self.applyButton = qt.QPushButton("Apply") #self.applyButton.toolTip = "Run the algorithm." #self.applyButton.enabled = False #parametersFormLayout.addRow(self.applyButton) # Add vertical spacer self.layout.addStretch(1) self.j = {}
def setup(self): ScriptedLoadableModuleWidget.setup(self) # check if the SlicerVmtk module is installed properly # self.__vmtkInstalled = SlicerVmtkCommonLib.Helper.CheckIfVmtkIsInstalled() # Helper.Debug("VMTK found: " + self.__vmtkInstalled) # # the I/O panel # ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "Input/Output" self.layout.addWidget( ioCollapsibleButton ) ioFormLayout = qt.QFormLayout( ioCollapsibleButton ) # inputVolume selector self.__inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' self.__inputVolumeNodeSelector.toolTip = "Select the input volume." self.__inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__inputVolumeNodeSelector.noneEnabled = False self.__inputVolumeNodeSelector.addEnabled = False self.__inputVolumeNodeSelector.removeEnabled = False ioFormLayout.addRow( "Input Volume:", self.__inputVolumeNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) self.__inputVolumeNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged ) # seed selector self.__seedFiducialsNodeSelector = slicer.qMRMLNodeComboBox() self.__seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.__seedFiducialsNodeSelector.toolTip = "Select a fiducial to use as a Seed to detect the maximal diameter." self.__seedFiducialsNodeSelector.nodeTypes = ['vtkMRMLMarkupsFiducialNode'] self.__seedFiducialsNodeSelector.baseName = "DiameterSeed" self.__seedFiducialsNodeSelector.noneEnabled = False self.__seedFiducialsNodeSelector.addEnabled = False self.__seedFiducialsNodeSelector.removeEnabled = False ioFormLayout.addRow( "Seed in largest Vessel:", self.__seedFiducialsNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) self.__seedFiducialsNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.onSeedChanged ) self.__ioAdvancedToggle = qt.QCheckBox( "Show Advanced Properties" ) self.__ioAdvancedToggle.setChecked( False ) ioFormLayout.addRow( self.__ioAdvancedToggle ) # # I/O advanced panel # self.__ioAdvancedPanel = qt.QFrame( ioCollapsibleButton ) self.__ioAdvancedPanel.hide() self.__ioAdvancedPanel.setFrameStyle( 6 ) ioFormLayout.addRow( self.__ioAdvancedPanel ) self.__ioAdvancedToggle.connect( "clicked()", self.onIOAdvancedToggle ) ioAdvancedFormLayout = qt.QFormLayout( self.__ioAdvancedPanel ) # lock button self.__detectPushButton = qt.QPushButton() self.__detectPushButton.text = "Detect parameters automatically" self.__detectPushButton.checkable = True self.__detectPushButton.checked = True # self.__unLockPushButton.connect("clicked()", self.calculateParameters()) ioAdvancedFormLayout.addRow( self.__detectPushButton ) # outputVolume selector self.__outputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__outputVolumeNodeSelector.toolTip = "Select the output labelmap." self.__outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__outputVolumeNodeSelector.baseName = "VesselnessFiltered" self.__outputVolumeNodeSelector.noneEnabled = False self.__outputVolumeNodeSelector.addEnabled = True self.__outputVolumeNodeSelector.selectNodeUponCreation = True self.__outputVolumeNodeSelector.removeEnabled = True ioAdvancedFormLayout.addRow( "Output Volume:", self.__outputVolumeNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) # previewVolume selector self.__previewVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__previewVolumeNodeSelector.toolTip = "Select the preview volume." self.__previewVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__previewVolumeNodeSelector.baseName = "VesselnessPreview" self.__previewVolumeNodeSelector.noneEnabled = False self.__previewVolumeNodeSelector.addEnabled = True self.__previewVolumeNodeSelector.selectNodeUponCreation = True self.__previewVolumeNodeSelector.removeEnabled = True ioAdvancedFormLayout.addRow( "Preview Volume:", self.__previewVolumeNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__previewVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) self.__minimumDiameterSpinBox = qt.QSpinBox() self.__minimumDiameterSpinBox.minimum = 0 self.__minimumDiameterSpinBox.maximum = 1000 self.__minimumDiameterSpinBox.singleStep = 1 self.__minimumDiameterSpinBox.toolTip = "Specify the minimum Diameter manually." ioAdvancedFormLayout.addRow( "Minimum Diameter [vx]:", self.__minimumDiameterSpinBox ) self.__maximumDiameterSpinBox = qt.QSpinBox() self.__maximumDiameterSpinBox.minimum = 0 self.__maximumDiameterSpinBox.maximum = 1000 self.__maximumDiameterSpinBox.singleStep = 1 self.__maximumDiameterSpinBox.toolTip = "Specify the maximum Diameter manually." ioAdvancedFormLayout.addRow( "Maximum Diameter [vx]:", self.__maximumDiameterSpinBox ) # add empty row ioAdvancedFormLayout.addRow( "", qt.QWidget() ) # alpha slider alphaLabel = qt.QLabel() alphaLabel.text = "more Tubes <-> more Plates" + SlicerVmtkCommonLib.Helper.CreateSpace( 16 ) alphaLabel.setAlignment( 4 ) alphaLabel.toolTip = "A lower value detects tubes rather than plate-like structures." ioAdvancedFormLayout.addRow( alphaLabel ) self.__alphaSlider = ctk.ctkSliderWidget() self.__alphaSlider.decimals = 1 self.__alphaSlider.minimum = 0.1 self.__alphaSlider.maximum = 500 self.__alphaSlider.singleStep = 0.1 self.__alphaSlider.toolTip = alphaLabel.toolTip ioAdvancedFormLayout.addRow( self.__alphaSlider ) # beta slider betaLabel = qt.QLabel() betaLabel.text = "more Blobs <-> more Tubes" + SlicerVmtkCommonLib.Helper.CreateSpace( 16 ) betaLabel.setAlignment( 4 ) betaLabel.toolTip = "A higher value detects tubes rather than blobs." ioAdvancedFormLayout.addRow( betaLabel ) self.__betaSlider = ctk.ctkSliderWidget() self.__betaSlider.decimals = 1 self.__betaSlider.minimum = 0.1 self.__betaSlider.maximum = 500 self.__betaSlider.singleStep = 0.1 self.__betaSlider.toolTip = betaLabel.toolTip ioAdvancedFormLayout.addRow( self.__betaSlider ) # contrast slider contrastLabel = qt.QLabel() contrastLabel.text = "low Input Contrast <-> high Input Contrast" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 ) contrastLabel.setAlignment( 4 ) contrastLabel.toolTip = "If the intensity contrast in the input image between vessel and background is high, choose a high value else choose a low value." ioAdvancedFormLayout.addRow( contrastLabel ) self.__contrastSlider = ctk.ctkSliderWidget() self.__contrastSlider.decimals = 0 self.__contrastSlider.minimum = 0 self.__contrastSlider.maximum = 500 self.__contrastSlider.singleStep = 10 self.__contrastSlider.toolTip = contrastLabel.toolTip ioAdvancedFormLayout.addRow( self.__contrastSlider ) # # Reset, preview and apply buttons # self.__buttonBox = qt.QDialogButtonBox() self.__resetButton = self.__buttonBox.addButton( self.__buttonBox.RestoreDefaults ) self.__resetButton.toolTip = "Click to reset all input elements to default." self.__previewButton = self.__buttonBox.addButton( self.__buttonBox.Discard ) self.__previewButton.setIcon( qt.QIcon() ) self.__previewButton.text = "Preview.." self.__previewButton.toolTip = "Click to refresh the preview." self.__startButton = self.__buttonBox.addButton( self.__buttonBox.Apply ) self.__startButton.setIcon( qt.QIcon() ) self.__startButton.text = "Start!" self.__startButton.enabled = False self.__startButton.toolTip = "Click to start the filtering." self.layout.addWidget( self.__buttonBox ) self.__resetButton.connect( "clicked()", self.restoreDefaults ) self.__previewButton.connect( "clicked()", self.onRefreshButtonClicked ) self.__startButton.connect( "clicked()", self.onStartButtonClicked ) self.__inputVolumeNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__seedFiducialsNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__outputVolumeNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__previewVolumeNodeSelector.setMRMLScene( slicer.mrmlScene ) # be ready for events self.__updating = 0 # set default values self.restoreDefaults() # compress the layout self.layout.addStretch( 1 )
def setupOptionsFrame(self): self.methodSelectorComboBox = qt.QComboBox() self.methodSelectorComboBox.addItem("Grow from seeds", GROWCUT) self.methodSelectorComboBox.addItem("Fill between parallel slices", MORPHOLOGICAL_SLICE_INTERPOLATION) self.methodSelectorComboBox.setToolTip("""<html>Auto-complete methods:<ul style="margin: 0"> <li><b>Grow from seeds:</b> Create segments using any editor effect: one segment inside each each region that should belong to a separate segment. Segments will be expanded to create a complete segmentation, taking into account the master volume content. Minimum two segments are required. <li><b>Fill between parallel slices:</b> Perform complete segmentation on selected slices using any editor effect. The complete segmentation will be created by interpolating segmentations on slices that were skipped.</li> (see http://insight-journal.org/browse/publication/977)</li> </ul></html>""") self.scriptedEffect.addLabeledOptionsWidget("Method:", self.methodSelectorComboBox) self.autoUpdateCheckBox = qt.QCheckBox("Auto-update") self.autoUpdateCheckBox.setToolTip("Auto-update results preview when input segments change.") self.autoUpdateCheckBox.setChecked(True) self.autoUpdateCheckBox.setEnabled(False) self.previewButton = qt.QPushButton("Initialize") self.previewButton.objectName = self.__class__.__name__ + 'Preview' self.previewButton.setToolTip("Preview complete segmentation") # qt.QSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # fails on some systems, therefore set the policies using separate method calls qSize = qt.QSizePolicy() qSize.setHorizontalPolicy(qt.QSizePolicy.Expanding) self.previewButton.setSizePolicy(qSize) previewFrame = qt.QHBoxLayout() previewFrame.addWidget(self.autoUpdateCheckBox) previewFrame.addWidget(self.previewButton) self.scriptedEffect.addLabeledOptionsWidget("Preview:", previewFrame) self.previewOpacitySlider = ctk.ctkSliderWidget() self.previewOpacitySlider.setToolTip("Adjust visibility of results preview.") self.previewOpacitySlider.minimum = 0 self.previewOpacitySlider.maximum = 1.0 self.previewOpacitySlider.value = 0.0 self.previewOpacitySlider.singleStep = 0.05 self.previewOpacitySlider.pageStep = 0.1 self.previewOpacitySlider.spinBoxVisible = False displayFrame = qt.QHBoxLayout() displayFrame.addWidget(qt.QLabel("inputs")) displayFrame.addWidget(self.previewOpacitySlider) displayFrame.addWidget(qt.QLabel("results")) self.scriptedEffect.addLabeledOptionsWidget("Display:", displayFrame) self.cancelButton = qt.QPushButton("Cancel") self.cancelButton.objectName = self.__class__.__name__ + 'Cancel' self.cancelButton.setToolTip("Clear preview and cancel auto-complete") self.applyButton = qt.QPushButton("Apply") self.applyButton.objectName = self.__class__.__name__ + 'Apply' self.applyButton.setToolTip("Replace segments by previewed result") finishFrame = qt.QHBoxLayout() finishFrame.addWidget(self.cancelButton) finishFrame.addWidget(self.applyButton) self.scriptedEffect.addOptionsWidget(finishFrame) self.methodSelectorComboBox.connect("currentIndexChanged(int)", self.updateMRMLFromGUI) self.previewButton.connect('clicked()', self.onPreview) self.cancelButton.connect('clicked()', self.onCancel) self.applyButton.connect('clicked()', self.onApply) self.previewOpacitySlider.connect("valueChanged(double)", self.updateMRMLFromGUI) self.autoUpdateCheckBox.connect("stateChanged(int)", self.updateMRMLFromGUI)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # # the I/O panel # inputsCollapsibleButton = ctk.ctkCollapsibleButton() inputsCollapsibleButton.text = "Inputs" self.layout.addWidget(inputsCollapsibleButton) inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton) # inputVolume selector self.inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' self.inputVolumeNodeSelector.toolTip = "Select the input volume. This should always be the original image and not a vesselness image, if possible." self.inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.inputVolumeNodeSelector.noneEnabled = False self.inputVolumeNodeSelector.addEnabled = False self.inputVolumeNodeSelector.removeEnabled = False inputsFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.inputVolumeNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged) # vesselnessVolume selector self.vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector' self.vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume." self.vesselnessVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.vesselnessVolumeNodeSelector.noneEnabled = True self.vesselnessVolumeNodeSelector.addEnabled = False self.vesselnessVolumeNodeSelector.removeEnabled = False inputsFormLayout.addRow("Vesselness Volume:", self.vesselnessVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.vesselnessVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.vesselnessVolumeNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onVesselnessVolumeChanged) self.vesselnessVolumeNodeSelector.setCurrentNode(None) # seed selector self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget() self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.seedFiducialsNodeSelector.toolTip = "Select start and end point of the vessel branch. Only the first and last point in the list are used." self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(0,0,255) # blue self.seedFiducialsNodeSelector.jumpToSliceEnabled = True self.seedFiducialsNodeSelector.markupsPlaceWidget().placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceMultipleMarkups self.seedFiducialsNodeSelector.setNodeBaseName("seeds") self.seedFiducialsNodeSelector.markupsSelectorComboBox().baseName = "Seeds" self.seedFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = False self.seedFiducialsNodeSelector.markupsSelectorComboBox().removeEnabled = True inputsFormLayout.addRow("Seeds:", self.seedFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # stopper selector self.stopperFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget() self.stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector' self.stopperFiducialsNodeSelector.toolTip = "(Optional) Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops." self.stopperFiducialsNodeSelector.defaultNodeColor = qt.QColor(0,0,255) # blue self.stopperFiducialsNodeSelector.setNodeBaseName("seeds") self.stopperFiducialsNodeSelector.tableWidget().hide() self.stopperFiducialsNodeSelector.markupsSelectorComboBox().baseName = "Stoppers" self.stopperFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = True self.stopperFiducialsNodeSelector.markupsSelectorComboBox().removeEnabled = True inputsFormLayout.addRow("Stoppers:", self.stopperFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.stopperFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # # Outputs # outputsCollapsibleButton = ctk.ctkCollapsibleButton() outputsCollapsibleButton.text = "Outputs" self.layout.addWidget(outputsCollapsibleButton) outputsFormLayout = qt.QFormLayout(outputsCollapsibleButton) # outputVolume selector self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.outputVolumeNodeSelector.toolTip = "Select the output labelmap." self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode'] self.outputVolumeNodeSelector.baseName = "LevelSetSegmentation" self.outputVolumeNodeSelector.noneEnabled = False self.outputVolumeNodeSelector.addEnabled = True self.outputVolumeNodeSelector.selectNodeUponCreation = True self.outputVolumeNodeSelector.removeEnabled = True outputsFormLayout.addRow("Output Labelmap:", self.outputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # outputModel selector self.outputModelNodeSelector = slicer.qMRMLNodeComboBox() self.outputModelNodeSelector.objectName = 'outputModelNodeSelector' self.outputModelNodeSelector.toolTip = "Select the output model." self.outputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode'] self.outputModelNodeSelector.hideChildNodeTypes = ['vtkMRMLAnnotationNode'] # hide all annotation nodes self.outputModelNodeSelector.baseName = "LevelSetSegmentationModel" self.outputModelNodeSelector.noneEnabled = False self.outputModelNodeSelector.addEnabled = True self.outputModelNodeSelector.selectNodeUponCreation = True self.outputModelNodeSelector.removeEnabled = True outputsFormLayout.addRow("Output Model:", self.outputModelNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.outputModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # # the segmentation panel # segmentationCollapsibleButton = ctk.ctkCollapsibleButton() segmentationCollapsibleButton.text = "Segmentation" self.layout.addWidget(segmentationCollapsibleButton) segmentationFormLayout = qt.QFormLayout(segmentationCollapsibleButton) # Threshold slider thresholdLabel = qt.QLabel() thresholdLabel.text = "Thresholding" + (' '*7) thresholdLabel.toolTip = "Choose the intensity range to segment." thresholdLabel.setAlignment(4) segmentationFormLayout.addRow(thresholdLabel) self.thresholdSlider = slicer.qMRMLRangeWidget() segmentationFormLayout.addRow(self.thresholdSlider) self.thresholdSlider.connect('valuesChanged(double,double)', self.onThresholdSliderChanged) self.segmentationAdvancedToggle = qt.QCheckBox("Show Advanced Segmentation Properties") self.segmentationAdvancedToggle.setChecked(False) segmentationFormLayout.addRow(self.segmentationAdvancedToggle) # # segmentation advanced panel # self.segmentationAdvancedPanel = qt.QFrame(segmentationCollapsibleButton) self.segmentationAdvancedPanel.hide() self.segmentationAdvancedPanel.setFrameStyle(6) segmentationFormLayout.addRow(self.segmentationAdvancedPanel) self.segmentationAdvancedToggle.connect("clicked()", self.onSegmentationAdvancedToggle) segmentationAdvancedFormLayout = qt.QFormLayout(self.segmentationAdvancedPanel) # inflation slider inflationLabel = qt.QLabel() inflationLabel.text = "less inflation <-> more inflation" + (' '*14) inflationLabel.setAlignment(4) inflationLabel.toolTip = "Define how fast the segmentation expands." segmentationAdvancedFormLayout.addRow(inflationLabel) self.inflationSlider = ctk.ctkSliderWidget() self.inflationSlider.decimals = 0 self.inflationSlider.minimum = -100 self.inflationSlider.maximum = 100 self.inflationSlider.singleStep = 10 self.inflationSlider.toolTip = inflationLabel.toolTip segmentationAdvancedFormLayout.addRow(self.inflationSlider) # curvature slider curvatureLabel = qt.QLabel() curvatureLabel.text = "less curvature <-> more curvature" + (' '*14) curvatureLabel.setAlignment(4) curvatureLabel.toolTip = "Choose a high curvature to generate a smooth segmentation." segmentationAdvancedFormLayout.addRow(curvatureLabel) self.curvatureSlider = ctk.ctkSliderWidget() self.curvatureSlider.decimals = 0 self.curvatureSlider.minimum = -100 self.curvatureSlider.maximum = 100 self.curvatureSlider.singleStep = 10 self.curvatureSlider.toolTip = curvatureLabel.toolTip segmentationAdvancedFormLayout.addRow(self.curvatureSlider) # attraction slider attractionLabel = qt.QLabel() attractionLabel.text = "less attraction to gradient <-> more attraction to gradient" + (' '*14) attractionLabel.setAlignment(4) attractionLabel.toolTip = "Configure how the segmentation travels towards gradient ridges (vessel lumen wall)." segmentationAdvancedFormLayout.addRow(attractionLabel) self.attractionSlider = ctk.ctkSliderWidget() self.attractionSlider.decimals = 0 self.attractionSlider.minimum = -100 self.attractionSlider.maximum = 100 self.attractionSlider.singleStep = 10 self.attractionSlider.toolTip = attractionLabel.toolTip segmentationAdvancedFormLayout.addRow(self.attractionSlider) # iteration spinbox self.iterationSpinBox = qt.QSpinBox() self.iterationSpinBox.minimum = 0 self.iterationSpinBox.maximum = 5000 self.iterationSpinBox.singleStep = 10 self.iterationSpinBox.toolTip = "Choose the number of evolution iterations." segmentationAdvancedFormLayout.addRow((' '*100) + "Iterations:", self.iterationSpinBox) # # Reset, preview and apply buttons # self.buttonBox = qt.QDialogButtonBox() self.resetButton = self.buttonBox.addButton(self.buttonBox.RestoreDefaults) self.resetButton.toolTip = "Click to reset all input elements to default." self.previewButton = self.buttonBox.addButton(self.buttonBox.Discard) self.previewButton.setIcon(qt.QIcon()) self.previewButton.text = "Preview" self.previewButton.toolTip = "Click to refresh the preview." self.startButton = self.buttonBox.addButton(self.buttonBox.Apply) self.startButton.setIcon(qt.QIcon()) self.startButton.text = "Start" self.startButton.enabled = False self.startButton.toolTip = "Click to start the filtering." self.layout.addWidget(self.buttonBox) self.resetButton.connect("clicked()", self.restoreDefaults) self.previewButton.connect("clicked()", self.onPreviewButtonClicked) self.startButton.connect("clicked()", self.onStartButtonClicked) self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) self.vesselnessVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.outputModelNodeSelector.setMRMLScene(slicer.mrmlScene) self.stopperFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) # set default values self.restoreDefaults() self.onInputVolumeChanged() # compress the layout self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) ### Parameters Area parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # fixed image (mrml input) self.fixedMRMLSelector = slicer.qMRMLNodeComboBox() self.fixedMRMLSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.fixedMRMLSelector.selectNodeUponCreation = True self.fixedMRMLSelector.addEnabled = False self.fixedMRMLSelector.removeEnabled = False self.fixedMRMLSelector.noneEnabled = False self.fixedMRMLSelector.showHidden = False self.fixedMRMLSelector.showChildNodeTypes = False self.fixedMRMLSelector.setMRMLScene( slicer.mrmlScene ) self.fixedMRMLSelector.setToolTip ("Choose either an image within the MRML scene, or a directory containing a DICOM image") parametersFormLayout.addRow("Fixed image: ", self.fixedMRMLSelector) # fixed image (directory input) self.fixedInputDirectory = ctk.ctkDirectoryButton() self.fixedInputDirectory.directory = qt.QDir.homePath() parametersFormLayout.addRow("", self.fixedInputDirectory) # moving image (mrml input) self.movingMRMLSelector = slicer.qMRMLNodeComboBox() self.movingMRMLSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.movingMRMLSelector.selectNodeUponCreation = True self.movingMRMLSelector.addEnabled = False self.movingMRMLSelector.removeEnabled = False self.movingMRMLSelector.noneEnabled = False self.movingMRMLSelector.showHidden = False self.movingMRMLSelector.showChildNodeTypes = False self.movingMRMLSelector.setMRMLScene( slicer.mrmlScene ) self.fixedMRMLSelector.setToolTip ("Choose either an image within the MRML scene, or a directory containing a DICOM image") parametersFormLayout.addRow("Moving image: ", self.movingMRMLSelector) # moving image (directory input) self.movingInputDirectory = ctk.ctkDirectoryButton() self.movingInputDirectory.directory = qt.QDir.homePath() parametersFormLayout.addRow("", self.movingInputDirectory) # transform (mrml input) self.xformMRMLSelector = slicer.qMRMLNodeComboBox() self.xformMRMLSelector.nodeTypes = ["vtkMRMLLinearTransformNode"] self.xformMRMLSelector.selectNodeUponCreation = True self.xformMRMLSelector.addEnabled = False self.xformMRMLSelector.removeEnabled = False self.xformMRMLSelector.noneEnabled = False self.xformMRMLSelector.showHidden = False self.xformMRMLSelector.showChildNodeTypes = False self.xformMRMLSelector.setMRMLScene( slicer.mrmlScene ) #self.xformMRMLSelector.setToolTip( "Pick the input to the algorithm." ) parametersFormLayout.addRow("Transform: ", self.xformMRMLSelector) # output directory selector self.outputDirectory = ctk.ctkDirectoryButton() self.outputDirectory.directory = qt.QDir.homePath() parametersFormLayout.addRow("Output Directory: ", self.outputDirectory) # check box to trigger taking screen shots for later use in tutorials self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") # parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # scale factor for screen shots self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget() self.screenshotScaleFactorSliderWidget.singleStep = 1.0 self.screenshotScaleFactorSliderWidget.minimum = 1.0 self.screenshotScaleFactorSliderWidget.maximum = 50.0 self.screenshotScaleFactorSliderWidget.value = 1.0 self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.") # parametersFormLayout.addRow("Screenshot scale factor", self.screenshotScaleFactorSliderWidget) # Apply Button self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False if (self.fixedMRMLSelector.currentNode() and self.movingMRMLSelector.currentNode() and self.xformMRMLSelector.currentNode()): self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.fixedMRMLSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.movingMRMLSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.xformMRMLSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # node type to add # self.nodeTypeComboBox = qt.QComboBox() self.nodeTypeComboBox.addItem("vtkMRMLMarkupsFiducialNode") self.nodeTypeComboBox.addItem("vtkMRMLMarkupsLineNode") self.nodeTypeComboBox.addItem("vtkMRMLMarkupsAngleNode") self.nodeTypeComboBox.addItem("vtkMRMLMarkupsCurveNode") self.nodeTypeComboBox.addItem("vtkMRMLMarkupsClosedCurveNode") self.nodeTypeComboBox.addItem("vtkMRMLMarkupsROINode") parametersFormLayout.addRow("Node type: ", self.nodeTypeComboBox) # # number of nodes to add # self.numberOfNodesSliderWidget = ctk.ctkSliderWidget() self.numberOfNodesSliderWidget.singleStep = 1.0 self.numberOfNodesSliderWidget.decimals = 0 self.numberOfNodesSliderWidget.minimum = 0.0 self.numberOfNodesSliderWidget.maximum = 1000.0 self.numberOfNodesSliderWidget.value = 1.0 self.numberOfNodesSliderWidget.toolTip = "Set the number of nodes to add." parametersFormLayout.addRow("Number of nodes: ", self.numberOfNodesSliderWidget) # # number of fiducials to add # self.numberOfControlPointsSliderWidget = ctk.ctkSliderWidget() self.numberOfControlPointsSliderWidget.singleStep = 1.0 self.numberOfControlPointsSliderWidget.decimals = 0 self.numberOfControlPointsSliderWidget.minimum = 0.0 self.numberOfControlPointsSliderWidget.maximum = 10000.0 self.numberOfControlPointsSliderWidget.value = 500.0 self.numberOfControlPointsSliderWidget.toolTip = "Set the number of control points to add per node." parametersFormLayout.addRow("Number of control points: ", self.numberOfControlPointsSliderWidget) # # check box to trigger fewer modify events, adding all the new points # is wrapped inside of a StartModify/EndModify block # self.fewerModifyFlagCheckBox = qt.QCheckBox() self.fewerModifyFlagCheckBox.checked = 0 self.fewerModifyFlagCheckBox.toolTip = 'If checked, wrap adding points inside of a StartModify - EndModify block' parametersFormLayout.addRow("Fewer modify events: ", self.fewerModifyFlagCheckBox) # # markups locked # self.lockedFlagCheckBox = qt.QCheckBox() self.lockedFlagCheckBox.checked = 0 self.lockedFlagCheckBox.toolTip = 'If checked, markups will be locked for editing' parametersFormLayout.addRow("Locked nodes: ", self.lockedFlagCheckBox) # # markups labels hidden # self.labelsHiddenFlagCheckBox = qt.QCheckBox() self.labelsHiddenFlagCheckBox.checked = 0 self.labelsHiddenFlagCheckBox.toolTip = 'If checked, markups labels will be forced to be hidden, regardless of default markups properties' parametersFormLayout.addRow("Labels hidden: ", self.labelsHiddenFlagCheckBox) # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = True parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) try: import vtkvmtkSegmentationPython as vtkvmtkSegmentation except ImportError: self.layout.addWidget(qt.QLabel("Failed to load VMTK libraries")) return # # the I/O panel # ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "Input/Output" self.layout.addWidget(ioCollapsibleButton) ioFormLayout = qt.QFormLayout(ioCollapsibleButton) # inputVolume selector self.inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' self.inputVolumeNodeSelector.toolTip = "Select the input volume." self.inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.inputVolumeNodeSelector.noneEnabled = False self.inputVolumeNodeSelector.addEnabled = False self.inputVolumeNodeSelector.removeEnabled = False ioFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # seed selector self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget() self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget() self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.seedFiducialsNodeSelector.toolTip = "Select a point in the largest vessel. Preview will be shown around this point. This is point is also used for determining maximum vessel diameter if automatic filtering parameters computation is enabled." self.seedFiducialsNodeSelector.setNodeBaseName("DiameterSeed") self.seedFiducialsNodeSelector.tableWidget().hide() self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(255,0,0) # red self.seedFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = False self.seedFiducialsNodeSelector.markupsPlaceWidget().placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup ioFormLayout.addRow("Seed point:", self.seedFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # outputVolume selector self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.outputVolumeNodeSelector.toolTip = "Select the output labelmap." self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.outputVolumeNodeSelector.baseName = "VesselnessFiltered" self.outputVolumeNodeSelector.noneEnabled = True self.outputVolumeNodeSelector.noneDisplay = "Create new volume" self.outputVolumeNodeSelector.addEnabled = True self.outputVolumeNodeSelector.selectNodeUponCreation = True self.outputVolumeNodeSelector.removeEnabled = True ioFormLayout.addRow("Output Volume:", self.outputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = True self.layout.addWidget(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) # previewVolume selector self.previewVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.previewVolumeNodeSelector.toolTip = "Select the preview volume." self.previewVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.previewVolumeNodeSelector.baseName = "VesselnessPreview" self.previewVolumeNodeSelector.noneEnabled = True self.previewVolumeNodeSelector.noneDisplay = "Create new volume" self.previewVolumeNodeSelector.addEnabled = True self.previewVolumeNodeSelector.selectNodeUponCreation = True self.previewVolumeNodeSelector.removeEnabled = True advancedFormLayout.addRow("Preview volume:", self.previewVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.previewVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.displayThresholdSlider = ctk.ctkSliderWidget() self.displayThresholdSlider.decimals = 2 self.displayThresholdSlider.minimum = 0 self.displayThresholdSlider.maximum = 1.0 self.displayThresholdSlider.singleStep = 0.01 self.displayThresholdSlider.toolTip = "Voxels below this vesselness value will be hidden. It does not change the voxel values, only how the vesselness volume is displayed." advancedFormLayout.addRow("Display threshold:", self.displayThresholdSlider) self.displayThresholdSlider.connect('valueChanged(double)', self.onDisplayThresholdChanged) self.previewVolumeDiameterVoxelSlider = ctk.ctkSliderWidget() self.previewVolumeDiameterVoxelSlider.decimals = 0 self.previewVolumeDiameterVoxelSlider.minimum = 10 self.previewVolumeDiameterVoxelSlider.maximum = 200 self.previewVolumeDiameterVoxelSlider.singleStep = 5 self.previewVolumeDiameterVoxelSlider.suffix = " voxels" self.previewVolumeDiameterVoxelSlider.toolTip = "Diameter of the preview area in voxels." advancedFormLayout.addRow("Preview volume size:", self.previewVolumeDiameterVoxelSlider) # detect filterint parameters self.detectPushButton = qt.QPushButton() self.detectPushButton.text = "Compute vessel diameters and contrast from seed point" self.detectPushButton.checkable = True self.detectPushButton.checked = True advancedFormLayout.addRow(self.detectPushButton) self.detectPushButton.connect("clicked()", self.onNodeSelectionChanged) self.minimumDiameterSpinBox = qt.QSpinBox() self.minimumDiameterSpinBox.minimum = 1 self.minimumDiameterSpinBox.maximum = 1000 self.minimumDiameterSpinBox.singleStep = 1 self.minimumDiameterSpinBox.suffix = " voxels" self.minimumDiameterSpinBox.enabled = False self.minimumDiameterSpinBox.toolTip = "Tubular structures that have minimum this diameter will be enhanced." advancedFormLayout.addRow("Minimum vessel diameter:", self.minimumDiameterSpinBox) self.detectPushButton.connect("toggled(bool)", self.minimumDiameterSpinBox.setDisabled) self.maximumDiameterSpinBox = qt.QSpinBox() self.maximumDiameterSpinBox.minimum = 0 self.maximumDiameterSpinBox.maximum = 1000 self.maximumDiameterSpinBox.singleStep = 1 self.maximumDiameterSpinBox.suffix = " voxels" self.maximumDiameterSpinBox.enabled = False self.maximumDiameterSpinBox.toolTip = "Tubular structures that have maximum this diameter will be enhanced." advancedFormLayout.addRow("Maximum vessel diameter:", self.maximumDiameterSpinBox) self.detectPushButton.connect("toggled(bool)", self.maximumDiameterSpinBox.setDisabled) self.contrastSlider = ctk.ctkSliderWidget() self.contrastSlider.decimals = 0 self.contrastSlider.minimum = 0 self.contrastSlider.maximum = 500 self.contrastSlider.singleStep = 10 self.contrastSlider.enabled = False self.contrastSlider.toolTip = "If the intensity contrast in the input image between vessel and background is high, choose a high value else choose a low value." advancedFormLayout.addRow("Vessel contrast:", self.contrastSlider) self.detectPushButton.connect("toggled(bool)", self.contrastSlider.setDisabled) self.suppressPlatesSlider = ctk.ctkSliderWidget() self.suppressPlatesSlider.decimals = 0 self.suppressPlatesSlider.minimum = 0 self.suppressPlatesSlider.maximum = 100 self.suppressPlatesSlider.singleStep = 1 self.suppressPlatesSlider.suffix = " %" self.suppressPlatesSlider.toolTip = "A higher value filters out more plate-like structures." advancedFormLayout.addRow("Suppress plates:", self.suppressPlatesSlider) self.suppressBlobsSlider = ctk.ctkSliderWidget() self.suppressBlobsSlider.decimals = 0 self.suppressBlobsSlider.minimum = 0 self.suppressBlobsSlider.maximum = 100 self.suppressBlobsSlider.singleStep = 1 self.suppressBlobsSlider.suffix = " %" self.suppressBlobsSlider.toolTip = "A higher value filters out more blob-like structures." advancedFormLayout.addRow("Suppress blobs:", self.suppressBlobsSlider) # # Reset, preview and apply buttons # self.buttonBox = qt.QDialogButtonBox() self.resetButton = self.buttonBox.addButton(self.buttonBox.RestoreDefaults) self.resetButton.toolTip = "Click to reset all input elements to default." self.previewButton = self.buttonBox.addButton(self.buttonBox.Discard) self.previewButton.setIcon(qt.QIcon()) self.previewButton.text = "Preview" self.startButton = self.buttonBox.addButton(self.buttonBox.Apply) self.startButton.setIcon(qt.QIcon()) self.startButton.text = "Start" self.startButton.enabled = False self.layout.addWidget(self.buttonBox) self.resetButton.connect("clicked()", self.restoreDefaults) self.previewButton.connect("clicked()", self.onPreviewButtonClicked) self.startButton.connect("clicked()", self.onStartButtonClicked) self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.previewVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.inputVolumeNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged) self.seedFiducialsNodeSelector.markupsSelectorComboBox().connect("currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged) self.seedFiducialsNodeSelector.connect("updateFinished()", self.onNodeSelectionChanged) # set default values self.restoreDefaults() self.onNodeSelectionChanged() # compress the layout self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene( slicer.mrmlScene ) self.inputSelector.setToolTip( "Pick the input to the algorithm." ) parametersFormLayout.addRow("Input Volume: ", self.inputSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene( slicer.mrmlScene ) self.outputSelector.setToolTip( "Pick the output to the algorithm." ) parametersFormLayout.addRow("Output Volume: ", self.outputSelector) # # threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 0.1 self.imageThresholdSliderWidget.minimum = -100 self.imageThresholdSliderWidget.maximum = 100 self.imageThresholdSliderWidget.value = 0.5 self.imageThresholdSliderWidget.setToolTip("Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero.") parametersFormLayout.addRow("Image threshold", self.imageThresholdSliderWidget) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.") parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Array selector 1 # self.ArraySelector1 = slicer.qMRMLNodeComboBox() self.ArraySelector1.nodeTypes = ( ("vtkMRMLDoubleArrayNode"), "" ) self.ArraySelector1.selectNodeUponCreation = False self.ArraySelector1.addEnabled = False self.ArraySelector1.removeEnabled = True self.ArraySelector1.noneEnabled = True self.ArraySelector1.showHidden = False self.ArraySelector1.showChildNodeTypes = False self.ArraySelector1.setMRMLScene( slicer.mrmlScene ) self.ArraySelector1.setToolTip( "Array for analysis" ) parametersFormLayout.addRow("First function: ", self.ArraySelector1) # # Array selector 2 # self.ArraySelector2 = slicer.qMRMLNodeComboBox() self.ArraySelector2.nodeTypes = ( ("vtkMRMLDoubleArrayNode"), "" ) self.ArraySelector2.selectNodeUponCreation = False self.ArraySelector2.addEnabled = False self.ArraySelector2.removeEnabled = True self.ArraySelector2.noneEnabled = True self.ArraySelector2.showHidden = False self.ArraySelector2.showChildNodeTypes = False self.ArraySelector2.setMRMLScene( slicer.mrmlScene ) self.ArraySelector2.setToolTip( "Array for analysis" ) parametersFormLayout.addRow("Second function: ", self.ArraySelector2) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # # Results Area # resultsCollapsibleButton = ctk.ctkCollapsibleButton() resultsCollapsibleButton.text = "Results" self.layout.addWidget(resultsCollapsibleButton) # Layout within the dummy collapsible button resultsFormLayout = qt.QFormLayout(resultsCollapsibleButton) # # delay value # self.delaySW = ctk.ctkSliderWidget() self.delaySW.singleStep = 1 self.delaySW.minimum = 0 self.delaySW.maximum = 0 self.delaySW.value = 0 self.delaySW.setToolTip("The delay for cross corralation") self.delaySW.enabled=False resultsFormLayout.addRow("Delay", self.delaySW) # # result value # self.resultLE=qt.QLineEdit() self.resultLE.readOnly=True self.resultLE.text="" resultsFormLayout.addRow("CC Value: ",self.resultLE) # # GOTO MAX Button # self.gomaxButton = qt.QPushButton("Go to Max") self.gomaxButton.toolTip = "Goto the maximum" #self.gomaxButton.enabled = False resultsFormLayout.addRow(self.gomaxButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.gomaxButton.connect('clicked(bool)', self.onGomaxButton) self.ArraySelector1.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.ArraySelector2.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.delaySW.connect("valueChanged(double)",self.getCC) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Path collapsible button pathCollapsibleButton = ctk.ctkCollapsibleButton() pathCollapsibleButton.text = "Path" self.layout.addWidget(pathCollapsibleButton) # Layout within the path collapsible button pathFormLayout = qt.QFormLayout(pathCollapsibleButton) # Camera node selector cameraNodeSelector = slicer.qMRMLNodeComboBox() cameraNodeSelector.objectName = 'cameraNodeSelector' cameraNodeSelector.toolTip = "Select a camera that will fly along this path." cameraNodeSelector.nodeTypes = ['vtkMRMLCameraNode'] cameraNodeSelector.noneEnabled = False cameraNodeSelector.addEnabled = False cameraNodeSelector.removeEnabled = False cameraNodeSelector.connect('currentNodeChanged(bool)', self.enableOrDisableCreateButton) cameraNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.setCameraNode) pathFormLayout.addRow("Camera:", cameraNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', cameraNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # Input fiducials node selector inputFiducialsNodeSelector = slicer.qMRMLNodeComboBox() inputFiducialsNodeSelector.objectName = 'inputFiducialsNodeSelector' inputFiducialsNodeSelector.toolTip = "Select a fiducial list to define control points for the path." inputFiducialsNodeSelector.nodeTypes = ['vtkMRMLMarkupsFiducialNode', 'vtkMRMLAnnotationHierarchyNode', 'vtkMRMLFiducialListNode'] inputFiducialsNodeSelector.noneEnabled = False inputFiducialsNodeSelector.addEnabled = False inputFiducialsNodeSelector.removeEnabled = False inputFiducialsNodeSelector.connect('currentNodeChanged(bool)', self.enableOrDisableCreateButton) pathFormLayout.addRow("Input Fiducials:", inputFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # CreatePath button createPathButton = qt.QPushButton("Create path") createPathButton.toolTip = "Create the path." createPathButton.enabled = False pathFormLayout.addRow(createPathButton) createPathButton.connect('clicked()', self.onCreatePathButtonClicked) # Flythrough collapsible button flythroughCollapsibleButton = ctk.ctkCollapsibleButton() flythroughCollapsibleButton.text = "Flythrough" flythroughCollapsibleButton.enabled = False self.layout.addWidget(flythroughCollapsibleButton) # Layout within the Flythrough collapsible button flythroughFormLayout = qt.QFormLayout(flythroughCollapsibleButton) # Frame slider frameSlider = ctk.ctkSliderWidget() frameSlider.connect('valueChanged(double)', self.frameSliderValueChanged) frameSlider.decimals = 0 flythroughFormLayout.addRow("Frame:", frameSlider) # Frame skip slider frameSkipSlider = ctk.ctkSliderWidget() frameSkipSlider.connect('valueChanged(double)', self.frameSkipSliderValueChanged) frameSkipSlider.decimals = 0 frameSkipSlider.minimum = 0 frameSkipSlider.maximum = 10 flythroughFormLayout.addRow("Frame skip:", frameSkipSlider) # Frame delay slider frameDelaySlider = ctk.ctkSliderWidget() frameDelaySlider.connect('valueChanged(double)', self.frameDelaySliderValueChanged) frameDelaySlider.decimals = 0 frameDelaySlider.minimum = 5 frameDelaySlider.maximum = 100 frameDelaySlider.suffix = " ms" frameDelaySlider.value = 20 flythroughFormLayout.addRow("Frame delay:", frameDelaySlider) # View angle slider viewAngleSlider = ctk.ctkSliderWidget() viewAngleSlider.connect('valueChanged(double)', self.viewAngleSliderValueChanged) viewAngleSlider.decimals = 0 viewAngleSlider.minimum = 30 viewAngleSlider.maximum = 180 flythroughFormLayout.addRow("View Angle:", viewAngleSlider) # Play button playButton = qt.QPushButton("Play") playButton.toolTip = "Fly through path." playButton.checkable = True flythroughFormLayout.addRow(playButton) playButton.connect('toggled(bool)', self.onPlayButtonToggled) # Add vertical spacer self.layout.addStretch(1) # Set local var as instance attribute self.cameraNodeSelector = cameraNodeSelector self.inputFiducialsNodeSelector = inputFiducialsNodeSelector self.createPathButton = createPathButton self.flythroughCollapsibleButton = flythroughCollapsibleButton self.frameSlider = frameSlider self.viewAngleSlider = viewAngleSlider self.playButton = playButton cameraNodeSelector.setMRMLScene(slicer.mrmlScene) inputFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = PFileParserLogic() # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Volume: ", self.inputSelector) # %%%%%%%%%%%%%%% Read PFile button section %%%%%%%%%%%%%% # Collapsible bar pCollapsibleBar = ctk.ctkCollapsibleButton() pCollapsibleBar.text = "fMRSI data" self.layout.addWidget(pCollapsibleBar) # Layout within the sample collapsible button formLayout = qt.QFormLayout(pCollapsibleBar) # Frame input edit sub-layout frameLayout = qt.QHBoxLayout(pCollapsibleBar) pStartAtFrameText = self.createFrameText( frameLayout, "From frame: ", 100, "First frame to be read from fMRSI file (1 = first).") # Add spacer frameLayout.addStretch(1) # Text input frame end pStopAtFrameText = self.createFrameText( frameLayout, "To frame: ", 100, "Last frame to be read from fMRSI file.") # Add horizontal frame to form layout formLayout.addRow(frameLayout) # ============== Buttons ============== # Button widget code pFileButton = qt.QPushButton("Read PFile...") pFileButton.toolTip = "Load raw PFile (.7) data" pFileButton.enabled = False formLayout.addRow(pFileButton) # =============== Radio Buttons ======== self.units = ("ppm", "hz", "points") pUnitsBox = qt.QGroupBox("Units") pUnitsBox.enabled = False pUnitsBox.setLayout(qt.QFormLayout()) pUnitsButtons = {} for units in self.units: pUnitsButtons[units] = qt.QRadioButton() pUnitsButtons[units].text = units pUnitsBox.layout().addRow(pUnitsButtons[units]) self.selectedUnits = self.units[0] pUnitsButtons[self.selectedUnits].checked = True formLayout.addRow(pUnitsBox) # =============== Sliders ============== # Frame slider pFrameSlider = ctk.ctkSliderWidget() pFrameSlider.decimals = 0 pFrameSlider.minimum = 1 pFrameSlider.maximum = 1 pFrameSlider.enabled = False formLayout.addRow("Frame:", pFrameSlider) # X axis Slider pXAxisRange = ctk.ctkRangeWidget() pXAxisRange.enabled = False pXAxisRange.minimum = 0.0 pXAxisRange.maximum = 0.0 formLayout.addRow("X axis range:", pXAxisRange) # Button widget code pPlotSpectrumButton = qt.QPushButton("Plot Spectrum...") pPlotSpectrumButton.toolTip = "Plot mean single voxel spectrum from PFile (.7) data" pPlotSpectrumButton.enabled = False formLayout.addRow(pPlotSpectrumButton) # ============== Info Text ============== # Text Info pInfoText = qt.QTextEdit() pInfoText.setReadOnly(True) pInfoText.setToolTip("Data read from fMRSI file.") formLayout.addRow(pInfoText) # connections pFileButton.connect('clicked(bool)', self.onPFileButtonClicked) pPlotSpectrumButton.connect('clicked(bool)', self.onPlotSpectrumButtonClicked) self.inputSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onSelect) for units in self.units: pUnitsButtons[units].connect( 'clicked()', lambda u=units: self.onPUnitsButtonsClicked(u)) # Set local var as instance attribute self.pFileButton = pFileButton self.pPlotSpectrumButton = pPlotSpectrumButton self.pInfoText = pInfoText self.pStartAtFrameText = pStartAtFrameText self.pStopAtFrameText = pStopAtFrameText self.pFrameSlider = pFrameSlider self.pXAxisRange = pXAxisRange self.pUnitsBox = pUnitsBox self.pUnitsButtons = pUnitsButtons # Add spacer self.layout.addStretch(1) # Refresh button status self.onSelect()
def create(self): super(QuickTCGAEffectOptions,self).create() # self.helpLabel = qt.QLabel("Press Y to run automatic segmentation on the current image using given parameters.", self.frame) # self.frame.layout().addWidget(self.helpLabel) #self.clearButton = qt.QPushButton(self.frame) #self.clearButton.text = "Clear Selection" #self.frame.layout().addWidget(self.clearButton) #self.clearButton.connect('clicked()', self.clearSelection) self.segButton = qt.QPushButton(self.frame) self.segButton.text = "Run Segmentation No Declumping" self.frame.layout().addWidget(self.segButton) self.segButton.connect('clicked()', self.RunSegmenterWO) self.segnoButton = qt.QPushButton(self.frame) self.segnoButton.text = "Run Segmentation With Declumping" self.frame.layout().addWidget(self.segnoButton) self.segnoButton.connect('clicked()', self.RunSegmenter) self.outlineButton = qt.QPushButton(self.frame) self.outlineButton.text = "Toggle Outline" self.frame.layout().addWidget(self.outlineButton) self.outlineButton.connect('clicked()', self.toggleOutline) self.locRadFrame = qt.QFrame(self.frame) self.locRadFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.locRadFrame) self.widgets.append(self.locRadFrame) # Nucleus segmentation parameters (Yi Gao's algorithm) nucleusSegCollapsibleButton = ctk.ctkCollapsibleButton() nucleusSegCollapsibleButton.text = "Nucleus Segmentation Parameters" nucleusSegCollapsibleButton.collapsed = False; self.frame.layout().addWidget(nucleusSegCollapsibleButton) self.structuresView = slicer.util.findChildren(slicer.modules.SlicerPathologyWidget.editorWidget.volumes, 'StructuresView')[0] self.structuresView.connect("activated(QModelIndex)", self.onStructureClickedOrAdded) # Layout within the parameter button nucleusSegFormLayout = qt.QFormLayout(nucleusSegCollapsibleButton) self.frameOtsuSlider = ctk.ctkSliderWidget() self.frameOtsuSlider.connect('valueChanged(double)', self.OtsuSliderValueChanged) self.frameOtsuSlider.decimals = 1 self.frameOtsuSlider.minimum = 0.5 self.frameOtsuSlider.maximum = 1.5 self.frameOtsuSlider.value = 1.0 self.frameOtsuSlider.singleStep = 0.1 nucleusSegFormLayout.addRow("Otsu Threshold:", self.frameOtsuSlider) self.frameCurvatureWeightSlider = ctk.ctkSliderWidget() self.frameCurvatureWeightSlider.connect('valueChanged(double)', self.CurvatureWeightSliderValueChanged) self.frameCurvatureWeightSlider.decimals = 1 self.frameCurvatureWeightSlider.minimum = 0 self.frameCurvatureWeightSlider.maximum = 10 self.frameCurvatureWeightSlider.value = 8 self.frameCurvatureWeightSlider.singleStep = 0.1 nucleusSegFormLayout.addRow("Curvature Weight:", self.frameCurvatureWeightSlider) self.frameSizeThldSlider = ctk.ctkSliderWidget() self.frameSizeThldSlider.connect('valueChanged(double)', self.SizeThldSliderValueChanged) self.frameSizeThldSlider.decimals = 1 self.frameSizeThldSlider.minimum = 1 self.frameSizeThldSlider.maximum = 30 self.frameSizeThldSlider.value = 3 self.frameSizeThldSlider.singleStep = 0.1 nucleusSegFormLayout.addRow("Size Threshold:", self.frameSizeThldSlider) self.frameSizeUpperThldSlider = ctk.ctkSliderWidget() self.frameSizeUpperThldSlider.connect('valueChanged(double)', self.SizeUpperThldSliderValueChanged) self.frameSizeUpperThldSlider.decimals = 0 self.frameSizeUpperThldSlider.minimum = 1 self.frameSizeUpperThldSlider.maximum = 500 self.frameSizeUpperThldSlider.value = 50 nucleusSegFormLayout.addRow("Size Upper Threshold:", self.frameSizeUpperThldSlider) self.frameKernelSizeSlider = ctk.ctkSliderWidget() self.frameKernelSizeSlider.connect('valueChanged(double)', self.KernelSizeSliderValueChanged) self.frameKernelSizeSlider.decimals = 0 self.frameKernelSizeSlider.minimum = 1 self.frameKernelSizeSlider.maximum = 30 self.frameKernelSizeSlider.value = 20 nucleusSegFormLayout.addRow("Kernel Size:", self.frameKernelSizeSlider) self.frameMPPSlider = ctk.ctkSliderWidget() self.frameMPPSlider.connect('valueChanged(double)', self.MPPSliderValueChanged) self.frameMPPSlider.decimals = 5 self.frameMPPSlider.minimum = 0.01 self.frameMPPSlider.maximum = 1 self.frameMPPSlider.value = 0.25 self.frameMPPSlider.singleStep = 0.01 nucleusSegFormLayout.addRow("Microns Per Pixel:", self.frameMPPSlider) self.DefaultsButton = qt.QPushButton(self.frame) self.DefaultsButton.text = "Default Parameter Values" nucleusSegFormLayout.addWidget(self.DefaultsButton) self.DefaultsButton.connect('clicked()', self.ResetToDefaults) HelpButton(self.frame, ("TO USE: \n Start the QuickTCGA segmenter and initialize the segmentation with any other editor tool like PaintEffect. Press the following keys to interact:" + "\n KEYS for Global Segmentation: " + "\n Q: quit ShortCut" + "\n Mouse: LEFT for foreground, RIGHT for background") ) self.frame.layout().addStretch(1) # Add vertical spacer self.omode = 0 self.toggleOutline()
def setup(self): ScriptedLoadableModuleWidget.setup(self) try: import vtkvmtkSegmentationPython as vtkvmtkSegmentation except ImportError: self.layout.addWidget(qt.QLabel("Failed to load VMTK libraries")) return # # the I/O panel # ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "Input/Output" self.layout.addWidget(ioCollapsibleButton) ioFormLayout = qt.QFormLayout(ioCollapsibleButton) # inputVolume selector self.inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' self.inputVolumeNodeSelector.toolTip = "Select the input volume." self.inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.inputVolumeNodeSelector.noneEnabled = False self.inputVolumeNodeSelector.addEnabled = False self.inputVolumeNodeSelector.removeEnabled = False ioFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # seed selector self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget() self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget() self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.seedFiducialsNodeSelector.toolTip = "Select a point in the largest vessel. Preview will be shown around this point. This is point is also used for determining maximum vessel diameter if automatic filtering parameters computation is enabled." self.seedFiducialsNodeSelector.setNodeBaseName("DiameterSeed") self.seedFiducialsNodeSelector.tableWidget().hide() self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(255, 0, 0) # red self.seedFiducialsNodeSelector.markupsSelectorComboBox( ).noneEnabled = False self.seedFiducialsNodeSelector.markupsPlaceWidget( ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup ioFormLayout.addRow("Seed point:", self.seedFiducialsNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # outputVolume selector self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.outputVolumeNodeSelector.toolTip = "Select the output labelmap." self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.outputVolumeNodeSelector.baseName = "VesselnessFiltered" self.outputVolumeNodeSelector.noneEnabled = True self.outputVolumeNodeSelector.noneDisplay = "Create new volume" self.outputVolumeNodeSelector.addEnabled = True self.outputVolumeNodeSelector.selectNodeUponCreation = True self.outputVolumeNodeSelector.removeEnabled = True ioFormLayout.addRow("Output Volume:", self.outputVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = True self.layout.addWidget(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) # previewVolume selector self.previewVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.previewVolumeNodeSelector.toolTip = "Select the preview volume." self.previewVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.previewVolumeNodeSelector.baseName = "VesselnessPreview" self.previewVolumeNodeSelector.noneEnabled = True self.previewVolumeNodeSelector.noneDisplay = "Create new volume" self.previewVolumeNodeSelector.addEnabled = True self.previewVolumeNodeSelector.selectNodeUponCreation = True self.previewVolumeNodeSelector.removeEnabled = True advancedFormLayout.addRow("Preview volume:", self.previewVolumeNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.previewVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.displayThresholdSlider = ctk.ctkSliderWidget() self.displayThresholdSlider.decimals = 2 self.displayThresholdSlider.minimum = 0 self.displayThresholdSlider.maximum = 1.0 self.displayThresholdSlider.singleStep = 0.01 self.displayThresholdSlider.toolTip = "Voxels below this vesselness value will be hidden. It does not change the voxel values, only how the vesselness volume is displayed." advancedFormLayout.addRow("Display threshold:", self.displayThresholdSlider) self.displayThresholdSlider.connect('valueChanged(double)', self.onDisplayThresholdChanged) self.previewVolumeDiameterVoxelSlider = ctk.ctkSliderWidget() self.previewVolumeDiameterVoxelSlider.decimals = 0 self.previewVolumeDiameterVoxelSlider.minimum = 10 self.previewVolumeDiameterVoxelSlider.maximum = 200 self.previewVolumeDiameterVoxelSlider.singleStep = 5 self.previewVolumeDiameterVoxelSlider.suffix = " voxels" self.previewVolumeDiameterVoxelSlider.toolTip = "Diameter of the preview area in voxels." advancedFormLayout.addRow("Preview volume size:", self.previewVolumeDiameterVoxelSlider) # detect filterint parameters self.detectPushButton = qt.QPushButton() self.detectPushButton.text = "Compute vessel diameters and contrast from seed point" self.detectPushButton.checkable = True self.detectPushButton.checked = True advancedFormLayout.addRow(self.detectPushButton) self.detectPushButton.connect("clicked()", self.onNodeSelectionChanged) self.minimumDiameterSpinBox = qt.QSpinBox() self.minimumDiameterSpinBox.minimum = 1 self.minimumDiameterSpinBox.maximum = 1000 self.minimumDiameterSpinBox.singleStep = 1 self.minimumDiameterSpinBox.suffix = " voxels" self.minimumDiameterSpinBox.enabled = False self.minimumDiameterSpinBox.toolTip = "Tubular structures that have minimum this diameter will be enhanced." advancedFormLayout.addRow("Minimum vessel diameter:", self.minimumDiameterSpinBox) self.detectPushButton.connect("toggled(bool)", self.minimumDiameterSpinBox.setDisabled) self.maximumDiameterSpinBox = qt.QSpinBox() self.maximumDiameterSpinBox.minimum = 0 self.maximumDiameterSpinBox.maximum = 1000 self.maximumDiameterSpinBox.singleStep = 1 self.maximumDiameterSpinBox.suffix = " voxels" self.maximumDiameterSpinBox.enabled = False self.maximumDiameterSpinBox.toolTip = "Tubular structures that have maximum this diameter will be enhanced." advancedFormLayout.addRow("Maximum vessel diameter:", self.maximumDiameterSpinBox) self.detectPushButton.connect("toggled(bool)", self.maximumDiameterSpinBox.setDisabled) self.contrastSlider = ctk.ctkSliderWidget() self.contrastSlider.decimals = 0 self.contrastSlider.minimum = 0 self.contrastSlider.maximum = 500 self.contrastSlider.singleStep = 10 self.contrastSlider.enabled = False self.contrastSlider.toolTip = "If the intensity contrast in the input image between vessel and background is high, choose a high value else choose a low value." advancedFormLayout.addRow("Vessel contrast:", self.contrastSlider) self.detectPushButton.connect("toggled(bool)", self.contrastSlider.setDisabled) self.suppressPlatesSlider = ctk.ctkSliderWidget() self.suppressPlatesSlider.decimals = 0 self.suppressPlatesSlider.minimum = 0 self.suppressPlatesSlider.maximum = 100 self.suppressPlatesSlider.singleStep = 1 self.suppressPlatesSlider.suffix = " %" self.suppressPlatesSlider.toolTip = "A higher value filters out more plate-like structures." advancedFormLayout.addRow("Suppress plates:", self.suppressPlatesSlider) self.suppressBlobsSlider = ctk.ctkSliderWidget() self.suppressBlobsSlider.decimals = 0 self.suppressBlobsSlider.minimum = 0 self.suppressBlobsSlider.maximum = 100 self.suppressBlobsSlider.singleStep = 1 self.suppressBlobsSlider.suffix = " %" self.suppressBlobsSlider.toolTip = "A higher value filters out more blob-like structures." advancedFormLayout.addRow("Suppress blobs:", self.suppressBlobsSlider) # # Reset, preview and apply buttons # self.buttonBox = qt.QDialogButtonBox() self.resetButton = self.buttonBox.addButton( self.buttonBox.RestoreDefaults) self.resetButton.toolTip = "Click to reset all input elements to default." self.previewButton = self.buttonBox.addButton(self.buttonBox.Discard) self.previewButton.setIcon(qt.QIcon()) self.previewButton.text = "Preview" self.startButton = self.buttonBox.addButton(self.buttonBox.Apply) self.startButton.setIcon(qt.QIcon()) self.startButton.text = "Start" self.startButton.enabled = False self.layout.addWidget(self.buttonBox) self.resetButton.connect("clicked()", self.restoreDefaults) self.previewButton.connect("clicked()", self.onPreviewButtonClicked) self.startButton.connect("clicked()", self.onStartButtonClicked) self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene) self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.previewVolumeNodeSelector.setMRMLScene(slicer.mrmlScene) self.inputVolumeNodeSelector.connect( "currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged) self.seedFiducialsNodeSelector.markupsSelectorComboBox().connect( "currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged) self.seedFiducialsNodeSelector.connect("updateFinished()", self.onNodeSelectionChanged) # set default values self.restoreDefaults() self.onNodeSelectionChanged() # compress the layout self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = ScreenCaptureLogic() self.logic.logCallback = self.addLog # Instantiate and connect widgets ... # # Input area # inputCollapsibleButton = ctk.ctkCollapsibleButton() inputCollapsibleButton.text = "Input" self.layout.addWidget(inputCollapsibleButton) inputFormLayout = qt.QFormLayout(inputCollapsibleButton) # Input view selector self.viewNodeSelector = slicer.qMRMLNodeComboBox() self.viewNodeSelector.nodeTypes = ["vtkMRMLSliceNode", "vtkMRMLViewNode"] self.viewNodeSelector.addEnabled = False self.viewNodeSelector.removeEnabled = False self.viewNodeSelector.noneEnabled = False self.viewNodeSelector.showHidden = False self.viewNodeSelector.showChildNodeTypes = False self.viewNodeSelector.setMRMLScene( slicer.mrmlScene ) self.viewNodeSelector.setToolTip( "Contents of this slice or 3D view will be captured." ) inputFormLayout.addRow("View to capture: ", self.viewNodeSelector) # # Slice view options area # self.sliceViewOptionsCollapsibleButton = ctk.ctkCollapsibleButton() self.sliceViewOptionsCollapsibleButton.text = "Slice viewer sweep" self.layout.addWidget(self.sliceViewOptionsCollapsibleButton) sliceViewOptionsLayout = qt.QFormLayout(self.sliceViewOptionsCollapsibleButton) # Start slice offset position self.startSliceOffsetSliderWidget = ctk.ctkSliderWidget() self.startSliceOffsetSliderWidget.singleStep = 30 self.startSliceOffsetSliderWidget.minimum = -100 self.startSliceOffsetSliderWidget.maximum = 100 self.startSliceOffsetSliderWidget.value = 0 self.startSliceOffsetSliderWidget.setToolTip("Start slice offset.") sliceViewOptionsLayout.addRow("Start offset:", self.startSliceOffsetSliderWidget) # End slice offset position self.endSliceOffsetSliderWidget = ctk.ctkSliderWidget() self.endSliceOffsetSliderWidget.singleStep = 5 self.endSliceOffsetSliderWidget.minimum = -100 self.endSliceOffsetSliderWidget.maximum = 100 self.endSliceOffsetSliderWidget.value = 0 self.endSliceOffsetSliderWidget.setToolTip("End slice offset.") sliceViewOptionsLayout.addRow("End offset:", self.endSliceOffsetSliderWidget) # # 3D view options area # self.threeDViewOptionsCollapsibleButton = ctk.ctkCollapsibleButton() self.threeDViewOptionsCollapsibleButton.text = "3D view rotation" self.layout.addWidget(self.threeDViewOptionsCollapsibleButton) threeDViewOptionsLayout = qt.QFormLayout(self.threeDViewOptionsCollapsibleButton) # Start rotation self.startRotationSliderWidget = ctk.ctkSliderWidget() self.startRotationSliderWidget.singleStep = 5 self.startRotationSliderWidget.minimum = 0 self.startRotationSliderWidget.maximum = 180 self.startRotationSliderWidget.value = 180 self.startRotationSliderWidget.setToolTip("Rotation angle for the first image, relative to current orientation.") threeDViewOptionsLayout.addRow("Start rotation angle:", self.startRotationSliderWidget) # End rotation self.endRotationSliderWidget = ctk.ctkSliderWidget() self.endRotationSliderWidget.singleStep = 5 self.endRotationSliderWidget.minimum = 0 self.endRotationSliderWidget.maximum = 180 self.endRotationSliderWidget.value = 180 self.endRotationSliderWidget.setToolTip("Rotation angle for the last image, relative to current orientation.") threeDViewOptionsLayout.addRow("End rotation angle:", self.endRotationSliderWidget) # # Output area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" self.layout.addWidget(outputCollapsibleButton) outputFormLayout = qt.QFormLayout(outputCollapsibleButton) # Number of steps value self.numberOfStepsSliderWidget = ctk.ctkSliderWidget() self.numberOfStepsSliderWidget.singleStep = 5 self.numberOfStepsSliderWidget.minimum = 2 self.numberOfStepsSliderWidget.maximum = 150 self.numberOfStepsSliderWidget.value = 30 self.numberOfStepsSliderWidget.decimals = 0 self.numberOfStepsSliderWidget.setToolTip("Number of images extracted between start and stop positions.") outputFormLayout.addRow("Number of images:", self.numberOfStepsSliderWidget) # Output directory selector self.outputDirSelector = ctk.ctkPathLineEdit() self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs self.outputDirSelector.settingKey = 'ScreenCaptureOutputDir' outputFormLayout.addRow("Output directory:", self.outputDirSelector) if not self.outputDirSelector.currentPath: defaultOutputPath = os.path.abspath(os.path.join(slicer.app.defaultScenePath,'SlicerCapture')) self.outputDirSelector.setCurrentPath(defaultOutputPath) self.videoExportCheckBox = qt.QCheckBox() self.videoExportCheckBox.checked = False self.videoExportCheckBox.setToolTip("If checked, exported images will be written as a video file.") outputFormLayout.addRow("Video export:", self.videoExportCheckBox) self.videoFileNameWidget = qt.QLineEdit() self.videoFileNameWidget.setToolTip("String that defines file name, type, and numbering scheme. Default: capture.avi.") self.videoFileNameWidget.text = "SlicerCapture.avi" self.videoFileNameWidget.setEnabled(False) outputFormLayout.addRow("Video file name:", self.videoFileNameWidget) self.videoQualitySliderWidget = ctk.ctkSliderWidget() self.videoQualitySliderWidget.singleStep = 0.1 self.videoQualitySliderWidget.minimum = 0 self.videoQualitySliderWidget.maximum = 20 self.videoQualitySliderWidget.value = 2 self.videoQualitySliderWidget.decimals = 1 self.videoQualitySliderWidget.setToolTip("Bit-rate of video. Higher value means higher quality and larger file size.") outputFormLayout.addRow("Video quality:", self.videoQualitySliderWidget) self.videoFrameRateSliderWidget = ctk.ctkSliderWidget() self.videoFrameRateSliderWidget.singleStep = 0.1 self.videoFrameRateSliderWidget.minimum = 0.1 self.videoFrameRateSliderWidget.maximum = 60 self.videoFrameRateSliderWidget.value = 25 self.videoFrameRateSliderWidget.decimals = 0 self.videoFrameRateSliderWidget.setToolTip("Frames per second. Higher values mean faster, shorter videos.") outputFormLayout.addRow("Frame rate:", self.videoFrameRateSliderWidget) # Capture button self.captureButton = qt.QPushButton("Capture") self.captureButton.toolTip = "Capture slice sweep to image sequence." outputFormLayout.addRow(self.captureButton) self.statusLabel = qt.QPlainTextEdit() self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse) self.statusLabel.setCenterOnScroll(True) outputFormLayout.addRow(self.statusLabel) # # Advanced area # self.advancedCollapsibleButton = ctk.ctkCollapsibleButton() self.advancedCollapsibleButton.text = "Advanced" self.advancedCollapsibleButton.collapsed = (self.logic.getFfmpegPath() is not None) self.layout.addWidget(self.advancedCollapsibleButton) advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton) self.fileNamePatternWidget = qt.QLineEdit() self.fileNamePatternWidget.setToolTip("String that defines file name, type, and numbering scheme. Default: image%05d.png.") self.fileNamePatternWidget.text = "image_%05d.png" advancedFormLayout.addRow("Image file name pattern:", self.fileNamePatternWidget) ffmpegPath = self.logic.getFfmpegPath() self.ffmpegPathSelector = ctk.ctkPathLineEdit() self.ffmpegPathSelector.setCurrentPath(ffmpegPath) self.ffmpegPathSelector.nameFilters = ['ffmpeg.exe', 'ffmpeg'] self.ffmpegPathSelector.setMaximumWidth(300) self.ffmpegPathSelector.setToolTip("Set the path to ffmpeg executable. Download from: https://www.ffmpeg.org/") self.ffmpegPathSelector.setEnabled(False) advancedFormLayout.addRow("ffmpeg executable:", self.ffmpegPathSelector) # Add vertical spacer self.layout.addStretch(1) # connections self.captureButton.connect('clicked(bool)', self.onCaptureButton) self.viewNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onViewNodeSelected) self.startSliceOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset) self.endSliceOffsetSliderWidget.connect('valueChanged(double)', self.setSliceOffset) self.videoExportCheckBox.connect('toggled(bool)', self.fileNamePatternWidget, 'setDisabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.ffmpegPathSelector, 'setEnabled(bool)') self.videoExportCheckBox.connect('toggled(bool)', self.videoFileNameWidget, 'setEnabled(bool)') self.onViewNodeSelected()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.selectNodeUponCreation = True self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = False self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Pick the input to the algorithm.") parametersFormLayout.addRow("Input Volume: ", self.inputSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = False self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip("Pick the output to the algorithm.") parametersFormLayout.addRow("Output Volume: ", self.outputSelector) # # threshold value # self.imageThresholdSliderWidget = ctk.ctkSliderWidget() self.imageThresholdSliderWidget.singleStep = 0.1 self.imageThresholdSliderWidget.minimum = -100 self.imageThresholdSliderWidget.maximum = 100 self.imageThresholdSliderWidget.value = 0.5 self.imageThresholdSliderWidget.setToolTip( "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero." ) parametersFormLayout.addRow("Image threshold", self.imageThresholdSliderWidget) # # check box to trigger taking screen shots for later use in tutorials # self.enableScreenshotsFlagCheckBox = qt.QCheckBox() self.enableScreenshotsFlagCheckBox.checked = 0 self.enableScreenshotsFlagCheckBox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def create(self): super(QuickTCGAEffectOptions,self).create() self.helpLabel = qt.QLabel("Press Y to run automatic segmentation on the current image using given parameters.", self.frame) self.frame.layout().addWidget(self.helpLabel) #create a "Start Bot" button self.botButton = qt.QPushButton(self.frame) self.frame.layout().addWidget(self.botButton) self.botButton.connect('clicked()', self.onStartBot) self.locRadFrame = qt.QFrame(self.frame) self.locRadFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.locRadFrame) self.widgets.append(self.locRadFrame) # Nucleus segmentation parameters (Yi Gao's algorithm) nucleusSegCollapsibleButton = ctk.ctkCollapsibleButton() nucleusSegCollapsibleButton.text = "Nucleus Segmentation Parameters (Yi Gao)" nucleusSegCollapsibleButton.collapsed = True; self.frame.layout().addWidget(nucleusSegCollapsibleButton) self.structuresView = slicer.util.findChildren(slicer.modules.SlicerPathologyWidget.editorWidget.volumes, 'StructuresView')[0] self.structuresView.connect("activated(QModelIndex)", self.onStructureClickedOrAdded) # Layout within the parameter button nucleusSegFormLayout = qt.QFormLayout(nucleusSegCollapsibleButton) self.frameOtsuSlider = ctk.ctkSliderWidget() self.frameOtsuSlider.connect('valueChanged(double)', self.OtsuSliderValueChanged) self.frameOtsuSlider.decimals = 0 self.frameOtsuSlider.minimum = 0 self.frameOtsuSlider.maximum = 10 self.frameOtsuSlider.value = 1.0 nucleusSegFormLayout.addRow("Otsu Threshold:", self.frameOtsuSlider) self.frameCurvatureWeightSlider = ctk.ctkSliderWidget() self.frameCurvatureWeightSlider.connect('valueChanged(double)', self.CurvatureWeightSliderValueChanged) self.frameCurvatureWeightSlider.decimals = 0 self.frameCurvatureWeightSlider.minimum = 0 self.frameCurvatureWeightSlider.maximum = 10 self.frameCurvatureWeightSlider.value = 8 nucleusSegFormLayout.addRow("Curvature Weight:", self.frameCurvatureWeightSlider) self.frameSizeThldSlider = ctk.ctkSliderWidget() self.frameSizeThldSlider.connect('valueChanged(double)', self.SizeThldSliderValueChanged) self.frameSizeThldSlider.decimals = 0 self.frameSizeThldSlider.minimum = 1 self.frameSizeThldSlider.maximum = 100 self.frameSizeThldSlider.value = 3 nucleusSegFormLayout.addRow("Size Threshold:", self.frameSizeThldSlider) self.frameSizeUpperThldSlider = ctk.ctkSliderWidget() self.frameSizeUpperThldSlider.connect('valueChanged(double)', self.SizeUpperThldSliderValueChanged) self.frameSizeUpperThldSlider.decimals = 0 self.frameSizeUpperThldSlider.minimum = 100 self.frameSizeUpperThldSlider.maximum = 500 self.frameSizeUpperThldSlider.value = 300 nucleusSegFormLayout.addRow("Size Upper Threshold:", self.frameSizeUpperThldSlider) self.frameMPPSlider = ctk.ctkSliderWidget() self.frameMPPSlider.connect('valueChanged(double)', self.MPPSliderValueChanged) self.frameMPPSlider.decimals = 0 self.frameMPPSlider.minimum = 0 self.frameMPPSlider.maximum = 100 self.frameMPPSlider.value = 25 nucleusSegFormLayout.addRow("Size Upper Threshold:", self.frameMPPSlider) HelpButton(self.frame, ("TO USE: \n Start the QuickTCGA segmenter and initialize the segmentation with any other editor tool like PaintEffect. Press the following keys to interact:" + "\n KEYS for Global Segmentation: " + "\n S: start Global segmentation \n E: toggle between seed image and segmentation result" + " \n R: reset seed/label image for Global Segmentation " + "\n F: toggle between selected ROI(Region of Interest) and segmentation result" + "\n Space key to go back to Slicer mode" "\n \nKEYS for ShortCut" "\n C: start ShortCut to refine the segmentation inside ROI"+ "\n N: run ShortCut" + "\n R: reset ShortCut parameters" "\n Q: quit ShortCut" + "\n Mouse: LEFT for foreground, RIGHT for background") ) self.frame.layout().addStretch(1) # Add vertical spacer if hasattr(slicer.modules, 'TCGAEditorBot'): slicer.util.showStatusMessage(slicer.modules.TCGAEditorBot.logic.currentMessage) self.botButton.text = "Stop Quick TCGA Segmenter" if self.locRadFrame: self.locRadFrame.hide() else: self.botButton.text = "Start Quick TCGA Segmenter" if self.locRadFrame: self.locRadFrame.show()
def setup(self): # Instantiate and connect widgets ... # reload button self.reloadButton = qt.QPushButton("Reload") self.reloadButton.toolTip = "Reload this module." self.reloadButton.name = "SteeredPolyAffineRegistration Reload" self.layout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # # IO Collapsible button # ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "Volume and Transform Parameters" self.layout.addWidget(ioCollapsibleButton) # Layout within the parameter collapsible button ioFormLayout = qt.QFormLayout(ioCollapsibleButton) # # InitialTransform node selector # self.initialTransformSelector = slicer.qMRMLNodeComboBox() # self.initialTransformSelector.objectName = 'initialTransformSelector' # self.initialTransformSelector.toolTip = "The initial transform volume." # self.initialTransformSelector.nodeTypes = ['vtkMRMLGridTransformNode'] # self.initialTransformSelector.noneEnabled = True # self.initialTransformSelector.addEnabled = True # self.initialTransformSelector.removeEnabled = True # ioFormLayout.addRow("Initial Transform:", self.initialTransformSelector) # self.initialTransformSelector.setMRMLScene(slicer.mrmlScene) # self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', # self.initialTransformSelector, 'setMRMLScene(vtkMRMLScene*)') # Fixed Volume node selector self.fixedSelector = slicer.qMRMLNodeComboBox() self.fixedSelector.objectName = 'fixedSelector' self.fixedSelector.toolTip = "The fixed volume." self.fixedSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.fixedSelector.noneEnabled = False self.fixedSelector.addEnabled = False self.fixedSelector.removeEnabled = False ioFormLayout.addRow("Fixed Volume:", self.fixedSelector) self.fixedSelector.setMRMLScene(slicer.mrmlScene) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.fixedSelector, 'setMRMLScene(vtkMRMLScene*)') # Moving Volume node selector self.movingSelector = slicer.qMRMLNodeComboBox() self.movingSelector.objectName = 'movingSelector' self.movingSelector.toolTip = "The moving volume." self.movingSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.movingSelector.noneEnabled = False self.movingSelector.addEnabled = False self.movingSelector.removeEnabled = False ioFormLayout.addRow("Moving Volume:", self.movingSelector) self.movingSelector.setMRMLScene(slicer.mrmlScene) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.movingSelector, 'setMRMLScene(vtkMRMLScene*)') # # Transform node selector # self.transformSelector = slicer.qMRMLNodeComboBox() # self.transformSelector.objectName = 'transformSelector' # self.transformSelector.toolTip = "The transform volume." # self.transformSelector.nodeTypes = ['vtkMRMLGridTransformNode'] # self.transformSelector.noneEnabled = True # self.transformSelector.addEnabled = True # self.transformSelector.removeEnabled = True # ioFormLayout.addRow("Moving To Fixed Transform:", self.transformSelector) # self.transformSelector.setMRMLScene(slicer.mrmlScene) # self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', # self.transformSelector, 'setMRMLScene(vtkMRMLScene*)') # Output Volume node selector self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.objectName = 'outputSelector' self.outputSelector.toolTip = "The output volume." self.outputSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.outputSelector.noneEnabled = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True ioFormLayout.addRow("Output Volume:", self.outputSelector) self.outputSelector.setMRMLScene(slicer.mrmlScene) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.outputSelector, 'setMRMLScene(vtkMRMLScene*)') selectors = (self.fixedSelector, self.movingSelector, self.outputSelector) for selector in selectors: selector.connect('currentNodeChanged(vtkMRMLNode*)', self.updateLogicFromGUI) # # Interaction options collapsible button # uiOptCollapsibleButton = ctk.ctkCollapsibleButton() uiOptCollapsibleButton.text = "Steering UI Parameters" self.layout.addWidget(uiOptCollapsibleButton) # Layout within the parameter collapsible button uiOptFormLayout = qt.QFormLayout(uiOptCollapsibleButton) # Interaction mode steerModeLayout = qt.QGridLayout() self.eraseModeRadio = qt.QRadioButton("Erase") self.rotateModeRadio = qt.QRadioButton("Rotate") self.scaleModeRadio = qt.QRadioButton("Scale") steerModeLayout.addWidget(self.eraseModeRadio, 0, 0) steerModeLayout.addWidget(self.rotateModeRadio, 0, 1) steerModeLayout.addWidget(self.scaleModeRadio, 0, 2) steerModeRadios = (self.eraseModeRadio, self.scaleModeRadio, self.rotateModeRadio) for r in steerModeRadios: r.connect('clicked(bool)', self.updateLogicFromGUI) self.rotateModeRadio.checked = True uiOptFormLayout.addRow("Steering Mode: ", steerModeLayout) # Number of polyaffine transforms at each dimension self.numberAffinesSlider = ctk.ctkSliderWidget() self.numberAffinesSlider.decimals = 0 self.numberAffinesSlider.singleStep = 1 self.numberAffinesSlider.minimum = 1 self.numberAffinesSlider.maximum = 8 self.numberAffinesSlider.toolTip = "Number of affines in each dim" uiOptFormLayout.addRow("Number of affines per dim:", self.numberAffinesSlider) self.numberAffinesSlider.value = self.logic.numberAffines # Draw iterations self.drawIterationSlider = ctk.ctkSliderWidget() self.drawIterationSlider.decimals = 0 self.drawIterationSlider.singleStep = 1 self.drawIterationSlider.minimum = 1 self.drawIterationSlider.maximum = 100 self.drawIterationSlider.toolTip = "Update and draw every N iterations" uiOptFormLayout.addRow("Redraw Iterations:", self.drawIterationSlider) self.drawIterationSlider.value = self.logic.drawIterations # # Registration regOptions collapsible button # regOptCollapsibleButton = ctk.ctkCollapsibleButton() regOptCollapsibleButton.text = "Registration Parameters" self.layout.addWidget(regOptCollapsibleButton) # Layout within the parameter collapsible button regOptFormLayout = qt.QFormLayout(regOptCollapsibleButton) # TODO: button for adding transform at current slice positions? self.polyAffineRadius = ctk.ctkSliderWidget() self.polyAffineRadius.decimals = 1 self.polyAffineRadius.singleStep = 0.5 self.polyAffineRadius.minimum = 1.0 self.polyAffineRadius.maximum = 100.0 self.polyAffineRadius.toolTip = "Area of effect for new transform." regOptFormLayout.addRow("Polyaffine radius: ", self.polyAffineRadius) self.polyAffineRadius.value = self.logic.polyAffineRadius sliders = (self.drawIterationSlider, self.polyAffineRadius) for slider in sliders: slider.connect('valueChanged(double)', self.updateLogicFromGUI) # # Developer collapsible button # devCollapsibleButton = ctk.ctkCollapsibleButton() devCollapsibleButton.text = "Developer Parameters" self.layout.addWidget(devCollapsibleButton) # Layout within the parameter collapsible button devFormLayout = qt.QFormLayout(devCollapsibleButton) self.profilingButton = qt.QCheckBox("Code Profiling") self.profilingButton.toolTip = "Obtain statistics of code execution." self.profilingButton.name = "SteeredPolyAffineRegistration Profiling" self.profilingButton.connect('toggled(bool)', self.toggleProfiling) devFormLayout.addWidget(self.profilingButton) self.debugButton = qt.QCheckBox("Print Debug Messages") self.debugButton.toolTip = "Display extra messages in Python console." self.debugButton.name = "SteeredPolyAffineRegistration Debug" self.debugButton.connect('toggled(bool)', self.updateLogicFromGUI) devFormLayout.addWidget(self.debugButton) # # Execution triggers # # TODO: # add check box for auto registration on/off # Start button self.regButton = qt.QPushButton("Start") self.regButton.toolTip = "Run steered registration" self.regButton.checkable = True self.layout.addWidget(self.regButton) self.regButton.connect('toggled(bool)', self.onStart) # Add vertical spacer #self.layout.addStretch(1) self.profiler = cProfile.Profile() # to support quicker development: import os if (os.getenv('USERNAME') == '212357326') or (os.getenv('USER') == 'prastawa'): #if False: self.logic.testingData() self.fixedSelector.setCurrentNode(slicer.util.getNode('blob_big')) # Disable anyway, in case checkbox clicked during execution self.movingSelector.setCurrentNode(slicer.util.getNode('blob_small'))
def _addCustomizationSection(self): customizationCollapsibleButton = ctk.ctkCollapsibleButton() customizationCollapsibleButton.text = 'Extraction Customization' customizationCollapsibleButton.collapsed = True self.layout.addWidget(customizationCollapsibleButton) customizationFormLayout = qt.QFormLayout(customizationCollapsibleButton) # # Radiobuttons to select customization Type # self.manualCustomizationRadioButton = qt.QRadioButton() self.manualCustomizationRadioButton.text = 'Manual Customization' self.manualCustomizationRadioButton.checked = True customizationFormLayout.layout().addWidget(self.manualCustomizationRadioButton) self.parameterFileCustomizationRadioButton = qt.QRadioButton() self.parameterFileCustomizationRadioButton.text = 'Parameter File Customization' self.parameterFileCustomizationRadioButton.checked = False customizationFormLayout.layout().addWidget(self.parameterFileCustomizationRadioButton) # # Manual Customization # self.manualCustomizationGroupBox = qt.QGroupBox('Manual Customization') self.manualCustomizationGroupBox.visible = True # self.manualCustomizationGroupBox.checkable = True customizationFormLayout.addWidget(self.manualCustomizationGroupBox) manualCustomizationFormLayout = qt.QFormLayout(self.manualCustomizationGroupBox) # Feature Class section featureClassCollapsibleButton = ctk.ctkCollapsibleButton() featureClassCollapsibleButton.text = 'Feature Classes' featureClassCollapsibleButton.collapsed = False manualCustomizationFormLayout.addWidget(featureClassCollapsibleButton) featureClassLayout = qt.QFormLayout(featureClassCollapsibleButton) self.featuresLayout = qt.QHBoxLayout() featureClassLayout.addRow('Features:', self.featuresLayout) self.featuresButtonGroup = qt.QButtonGroup(self.featuresLayout) self.featuresButtonGroup.exclusive = False # Get the feature classes dynamically self.features = list(getFeatureClasses().keys()) # Create a checkbox for each feature featureButtons = {} for feature in self.features: featureButtons[feature] = qt.QCheckBox(feature) # TODO: decide which features to enable by default featureButtons[feature].checked = False if feature == 'firstorder': featureButtons[feature].checked = True self.featuresButtonGroup.addButton(featureButtons[feature]) self.featuresLayout.layout().addWidget(featureButtons[feature]) # set the ID to be the index of this feature in the list self.featuresButtonGroup.setId(featureButtons[feature], self.features.index(feature)) # Add buttons to select all or none self.buttonsLayout = qt.QHBoxLayout() featureClassLayout.addRow('Toggle Features:', self.buttonsLayout) self.calculateAllFeaturesButton = qt.QPushButton('All Features') self.calculateAllFeaturesButton.toolTip = 'Calculate all feature classes.' self.calculateAllFeaturesButton.enabled = True self.buttonsLayout.addWidget(self.calculateAllFeaturesButton) self.calculateNoFeaturesButton = qt.QPushButton('No Features') self.calculateNoFeaturesButton.toolTip = 'Calculate no feature classes.' self.calculateNoFeaturesButton.enabled = True self.buttonsLayout.addWidget(self.calculateNoFeaturesButton) # Resampling and Filtering filteringCollapsibleButton = ctk.ctkCollapsibleButton() filteringCollapsibleButton.text = 'Resampling and Filtering' filteringCollapsibleButton.collapsed = False manualCustomizationFormLayout.addRow(filteringCollapsibleButton) # Layout within the dummy collapsible button filteringFormLayout = qt.QFormLayout(filteringCollapsibleButton) # Resampling self.resampledVoxelSize = qt.QLineEdit() self.resampledVoxelSize.toolTip = 'Three floating-point numbers separated by comma defining the resampled pixel ' \ 'size (mm).' filteringFormLayout.addRow('Resampled voxel size', self.resampledVoxelSize) # LoG kernel sizes. default to 5 (?) self.logKernelSizes = qt.QLineEdit() self.logKernelSizes.toolTip = 'Laplacian of Gaussian filter kernel sizes (mm), separated by comma. ' \ 'If empty, no LoG filtering will be applied.' filteringFormLayout.addRow('LoG kernel sizes', self.logKernelSizes) # Wavelet self.waveletCheckBox = qt.QCheckBox() self.waveletCheckBox.checked = 0 self.waveletCheckBox.toolTip = 'If checked, PyRadiomics will calculate features on the image after applying ' \ 'wavelet transformation' filteringFormLayout.addRow('Wavelet-based features', self.waveletCheckBox) # # Feature calculation settings # settingsCollapsibleButton = ctk.ctkCollapsibleButton() settingsCollapsibleButton.text = 'Settings' settingsCollapsibleButton.collapsed = False manualCustomizationFormLayout.addWidget(settingsCollapsibleButton) # Layout within the dummy collapsible button settingsFormLayout = qt.QFormLayout(settingsCollapsibleButton) # bin width, defaults to 25 self.binWidthSliderWidget = ctk.ctkSliderWidget() self.binWidthSliderWidget.singleStep = 1 self.binWidthSliderWidget.decimals = 2 self.binWidthSliderWidget.minimum = 0.01 self.binWidthSliderWidget.maximum = 100 self.binWidthSliderWidget.value = 25 self.binWidthSliderWidget.toolTip = 'Set the bin width' settingsFormLayout.addRow('Bin Width', self.binWidthSliderWidget) # symmetricalGLCM flag, defaults to false self.symmetricalGLCMCheckBox = qt.QCheckBox() self.symmetricalGLCMCheckBox.checked = 1 self.symmetricalGLCMCheckBox.toolTip = 'Use a symmetrical GLCM matrix' settingsFormLayout.addRow('Enforce Symmetrical GLCM', self.symmetricalGLCMCheckBox) # # Parameter File Customization # self.parameterCustomizationGroupBox = qt.QGroupBox('Parameter File Customization') self.parameterCustomizationGroupBox.visible = False # self.parameterCustomizationGroupBox.checkable = True customizationFormLayout.addWidget(self.parameterCustomizationGroupBox) parameterCustomizationFormLayout = qt.QFormLayout(self.parameterCustomizationGroupBox) # Path edit to select parameter file self.parameterFilePathLineEdit = ctk.ctkPathLineEdit() parameterCustomizationFormLayout.addRow("Parameter File", self.parameterFilePathLineEdit)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Segmentation volume selector # self.segmentationSelector = slicer.qMRMLNodeComboBox() self.segmentationSelector.nodeTypes = ["vtkMRMLScalarVolumeNode", "vtkMRMLLabelMapVolumeNode"] self.segmentationSelector.selectNodeUponCreation = True self.segmentationSelector.addEnabled = False self.segmentationSelector.removeEnabled = False self.segmentationSelector.noneEnabled = False self.segmentationSelector.showHidden = False self.segmentationSelector.showChildNodeTypes = False self.segmentationSelector.setMRMLScene( slicer.mrmlScene ) self.segmentationSelector.setToolTip("Choose the segmentation to dilate.") parametersFormLayout.addRow("Segmentation: ", self.segmentationSelector) # # False negative volume selector # self.falseNegativeSelector = slicer.qMRMLNodeComboBox() self.falseNegativeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode", "vtkMRMLLabelMapVolumeNode"] self.falseNegativeSelector.selectNodeUponCreation = True self.falseNegativeSelector.addEnabled = False self.falseNegativeSelector.removeEnabled = False self.falseNegativeSelector.noneEnabled = False self.falseNegativeSelector.showHidden = False self.falseNegativeSelector.showChildNodeTypes = False self.falseNegativeSelector.setMRMLScene( slicer.mrmlScene ) self.falseNegativeSelector.setToolTip("Choose the false negative test line.") parametersFormLayout.addRow("False negative line: ", self.falseNegativeSelector) # # True positive volume selector # self.truePositiveSelector = slicer.qMRMLNodeComboBox() self.truePositiveSelector.nodeTypes = ["vtkMRMLScalarVolumeNode", "vtkMRMLLabelMapVolumeNode"] self.truePositiveSelector.selectNodeUponCreation = True self.truePositiveSelector.addEnabled = False self.truePositiveSelector.removeEnabled = False self.truePositiveSelector.noneEnabled = False self.truePositiveSelector.showHidden = False self.truePositiveSelector.showChildNodeTypes = False self.truePositiveSelector.setMRMLScene( slicer.mrmlScene ) self.truePositiveSelector.setToolTip("Choose the true positive test region.") parametersFormLayout.addRow("True positive region: ", self.truePositiveSelector) # # Dilation value # self.dilationSliderWidget = ctk.ctkSliderWidget() self.dilationSliderWidget.singleStep = 1 self.dilationSliderWidget.minimum = 0 self.dilationSliderWidget.maximum = 20 self.dilationSliderWidget.value = 5 self.dilationSliderWidget.setToolTip("""Set the value to dilate the segmentation line when calculating false negatives with respect to the false negative line.""") parametersFormLayout.addRow("Dilation factor", self.dilationSliderWidget) # # Apply Button # self.applyButton = qt.QPushButton("Run") self.applyButton.toolTip = "Run the computation." self.applyButton.enabled = False parametersFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.segmentationSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.falseNegativeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.truePositiveSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def __init__(self, logic): super(VisualizationWidget, self).__init__() self.rockCount = 0 self.rocking = False self.rockTimer = None self.flickerTimer = None self.logic = logic self.revealCursor = None self.volumes = ("Fixed", "Moving", "Transformed") self.layoutOptions = ("Axial", "Coronal", "Sagittal", "Axi/Sag/Cor") self.layoutOption = "Axi/Sag/Cor" self.volumeDisplayCheckboxes = {} # mimic the structure of the LandmarksWidget for visual # consistency (it needs sub widget so it can delete and refresh the internals) self.widget = qt.QWidget() self.layout = qt.QFormLayout(self.widget) self.boxHolder = qt.QWidget() self.boxHolder.setLayout(qt.QVBoxLayout()) self.layout.addRow(self.boxHolder) self.groupBox = qt.QGroupBox("Visualization") self.groupBoxLayout = qt.QFormLayout(self.groupBox) self.boxHolder.layout().addWidget(self.groupBox) # # layout selection # layoutHolder = qt.QWidget() layout = qt.QHBoxLayout() layoutHolder.setLayout(layout) for layoutOption in self.layoutOptions: layoutButton = qt.QPushButton(layoutOption) layoutButton.connect("clicked()", lambda lo=layoutOption: self.selectLayout(lo)) layout.addWidget(layoutButton) self.groupBoxLayout.addRow("Layout", layoutHolder) # # Volume display selection # checkboxHolder = qt.QWidget() layout = qt.QHBoxLayout() checkboxHolder.setLayout(layout) for volume in self.volumes: checkBox = qt.QCheckBox() checkBox.text = volume checkBox.checked = True checkBox.connect("toggled(bool)", self.updateVisualization) layout.addWidget(checkBox) self.volumeDisplayCheckboxes[volume] = checkBox checkBox = qt.QCheckBox() checkBox.text = "RevealCursor" checkBox.checked = False checkBox.connect("toggled(bool)", self.revealToggled) layout.addWidget(checkBox) self.groupBoxLayout.addRow("Display", checkboxHolder) # # fade slider # fadeHolder = qt.QWidget() fadeLayout = qt.QHBoxLayout() fadeHolder.setLayout(fadeLayout) self.fadeSlider = ctk.ctkSliderWidget() self.fadeSlider.minimum = 0 self.fadeSlider.maximum = 1.0 self.fadeSlider.value = 0.5 self.fadeSlider.singleStep = 0.05 self.fadeSlider.connect("valueChanged(double)", self.onFadeChanged) fadeLayout.addWidget(self.fadeSlider) # # Rock and Flicker # animaHolder = qt.QWidget() animaLayout = qt.QVBoxLayout() animaHolder.setLayout(animaLayout) fadeLayout.addWidget(animaHolder) # Rock checkBox = qt.QCheckBox() checkBox.text = "Rock" checkBox.checked = False checkBox.connect("toggled(bool)", self.onRockToggled) animaLayout.addWidget(checkBox) # Flicker checkBox = qt.QCheckBox() checkBox.text = "Flicker" checkBox.checked = False checkBox.connect("toggled(bool)", self.onFlickerToggled) animaLayout.addWidget(checkBox) self.groupBoxLayout.addRow("Fade", fadeHolder) # # zoom control # zoomHolder = qt.QWidget() layout = qt.QHBoxLayout() zoomHolder.setLayout(layout) zooms = {"+": 0.7, "-": 1.3, "Fit": "Fit"} for zoomLabel, zoomFactor in zooms.items(): zoomButton = qt.QPushButton(zoomLabel) zoomButton.connect("clicked()", lambda zf=zoomFactor: self.onZoom(zf)) layout.addWidget(zoomButton) self.groupBoxLayout.addRow("Zoom", zoomHolder)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # check if the SlicerVmtk module is installed properly # self.__vmtkInstalled = SlicerVmtkCommonLib.Helper.CheckIfVmtkIsInstalled() # Helper.Debug("VMTK found: " + self.__vmtkInstalled) # # the I/O panel # ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "Input/Output" self.layout.addWidget( ioCollapsibleButton ) ioFormLayout = qt.QFormLayout( ioCollapsibleButton ) # inputVolume selector self.__inputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector' self.__inputVolumeNodeSelector.toolTip = "Select the input volume. This should always be the original image and not a vesselness image, if possible." self.__inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__inputVolumeNodeSelector.noneEnabled = False self.__inputVolumeNodeSelector.addEnabled = False self.__inputVolumeNodeSelector.removeEnabled = False ioFormLayout.addRow( "Input Volume:", self.__inputVolumeNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) self.__inputVolumeNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged ) self.__inputVolumeNodeSelector.connect( 'nodeActivated(vtkMRMLNode*)', self.onInputVolumeChanged ) # seed selector self.__seedFiducialsNodeSelector = slicer.qMRMLNodeComboBox() self.__seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector' self.__seedFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Seeds." self.__seedFiducialsNodeSelector.nodeTypes = ['vtkMRMLMarkupsFiducialNode'] self.__seedFiducialsNodeSelector.baseName = "Seeds" self.__seedFiducialsNodeSelector.noneEnabled = False self.__seedFiducialsNodeSelector.addEnabled = False self.__seedFiducialsNodeSelector.removeEnabled = False ioFormLayout.addRow( "Seeds:", self.__seedFiducialsNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) self.__ioAdvancedToggle = qt.QCheckBox( "Show Advanced I/O Properties" ) self.__ioAdvancedToggle.setChecked( False ) ioFormLayout.addRow( self.__ioAdvancedToggle ) # # I/O advanced panel # self.__ioAdvancedPanel = qt.QFrame( ioCollapsibleButton ) self.__ioAdvancedPanel.hide() self.__ioAdvancedPanel.setFrameStyle( 6 ) ioFormLayout.addRow( self.__ioAdvancedPanel ) self.__ioAdvancedToggle.connect( "clicked()", self.onIOAdvancedToggle ) ioAdvancedFormLayout = qt.QFormLayout( self.__ioAdvancedPanel ) # inputVolume selector self.__vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector' self.__vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume. This is optional input." self.__vesselnessVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] self.__vesselnessVolumeNodeSelector.noneEnabled = True self.__vesselnessVolumeNodeSelector.addEnabled = False self.__vesselnessVolumeNodeSelector.removeEnabled = False ioAdvancedFormLayout.addRow( "Vesselness Volume:", self.__vesselnessVolumeNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__vesselnessVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) self.__vesselnessVolumeNodeSelector.setCurrentNode( None ) # stopper selector self.__stopperFiducialsNodeSelector = slicer.qMRMLNodeComboBox() self.__stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector' self.__stopperFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops." self.__stopperFiducialsNodeSelector.nodeTypes = ['vtkMRMLMarkupsFiducialNode'] self.__stopperFiducialsNodeSelector.baseName = "Stoppers" self.__stopperFiducialsNodeSelector.noneEnabled = False self.__stopperFiducialsNodeSelector.addEnabled = True self.__stopperFiducialsNodeSelector.removeEnabled = False ioAdvancedFormLayout.addRow( "Stoppers:", self.__stopperFiducialsNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__stopperFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) # outputVolume selector self.__outputVolumeNodeSelector = slicer.qMRMLNodeComboBox() self.__outputVolumeNodeSelector.toolTip = "Select the output labelmap." self.__outputVolumeNodeSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode'] self.__outputVolumeNodeSelector.baseName = "LevelSetSegmentation" self.__outputVolumeNodeSelector.noneEnabled = False self.__outputVolumeNodeSelector.addEnabled = True self.__outputVolumeNodeSelector.selectNodeUponCreation = True self.__outputVolumeNodeSelector.removeEnabled = True ioAdvancedFormLayout.addRow( "Output Labelmap:", self.__outputVolumeNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) # outputModel selector self.__outputModelNodeSelector = slicer.qMRMLNodeComboBox() self.__outputModelNodeSelector.objectName = 'outputModelNodeSelector' self.__outputModelNodeSelector.toolTip = "Select the output model." self.__outputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode'] self.__outputModelNodeSelector.baseName = "LevelSetSegmentationModel" self.__outputModelNodeSelector.hideChildNodeTypes = ['vtkMRMLMarkupsFiducialNode']# hide all annotation nodes self.__outputModelNodeSelector.noneEnabled = False self.__outputModelNodeSelector.addEnabled = True self.__outputModelNodeSelector.selectNodeUponCreation = True self.__outputModelNodeSelector.removeEnabled = True ioAdvancedFormLayout.addRow( "Output Model:", self.__outputModelNodeSelector ) self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)', self.__outputModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)' ) # # the segmentation panel # segmentationCollapsibleButton = ctk.ctkCollapsibleButton() segmentationCollapsibleButton.text = "Segmentation" self.layout.addWidget( segmentationCollapsibleButton ) segmentationFormLayout = qt.QFormLayout( segmentationCollapsibleButton ) # Threshold slider thresholdLabel = qt.QLabel() thresholdLabel.text = "Thresholding" + SlicerVmtkCommonLib.Helper.CreateSpace( 7 ) thresholdLabel.toolTip = "Choose the intensity range to segment." thresholdLabel.setAlignment( 4 ) segmentationFormLayout.addRow( thresholdLabel ) self.__thresholdSlider = slicer.qMRMLRangeWidget() segmentationFormLayout.addRow( self.__thresholdSlider ) self.__thresholdSlider.connect( 'valuesChanged(double,double)', self.onThresholdSliderChanged ) self.__segmentationAdvancedToggle = qt.QCheckBox( "Show Advanced Segmentation Properties" ) self.__segmentationAdvancedToggle.setChecked( False ) segmentationFormLayout.addRow( self.__segmentationAdvancedToggle ) # # segmentation advanced panel # self.__segmentationAdvancedPanel = qt.QFrame( segmentationCollapsibleButton ) self.__segmentationAdvancedPanel.hide() self.__segmentationAdvancedPanel.setFrameStyle( 6 ) segmentationFormLayout.addRow( self.__segmentationAdvancedPanel ) self.__segmentationAdvancedToggle.connect( "clicked()", self.onSegmentationAdvancedToggle ) segmentationAdvancedFormLayout = qt.QFormLayout( self.__segmentationAdvancedPanel ) # inflation slider inflationLabel = qt.QLabel() inflationLabel.text = "less inflation <-> more inflation" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 ) inflationLabel.setAlignment( 4 ) inflationLabel.toolTip = "Define how fast the segmentation expands." segmentationAdvancedFormLayout.addRow( inflationLabel ) self.__inflationSlider = ctk.ctkSliderWidget() self.__inflationSlider.decimals = 0 self.__inflationSlider.minimum = -100 self.__inflationSlider.maximum = 100 self.__inflationSlider.singleStep = 10 self.__inflationSlider.toolTip = inflationLabel.toolTip segmentationAdvancedFormLayout.addRow( self.__inflationSlider ) # curvature slider curvatureLabel = qt.QLabel() curvatureLabel.text = "less curvature <-> more curvature" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 ) curvatureLabel.setAlignment( 4 ) curvatureLabel.toolTip = "Choose a high curvature to generate a smooth segmentation." segmentationAdvancedFormLayout.addRow( curvatureLabel ) self.__curvatureSlider = ctk.ctkSliderWidget() self.__curvatureSlider.decimals = 0 self.__curvatureSlider.minimum = -100 self.__curvatureSlider.maximum = 100 self.__curvatureSlider.singleStep = 10 self.__curvatureSlider.toolTip = curvatureLabel.toolTip segmentationAdvancedFormLayout.addRow( self.__curvatureSlider ) # attraction slider attractionLabel = qt.QLabel() attractionLabel.text = "less attraction to gradient <-> more attraction to gradient" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 ) attractionLabel.setAlignment( 4 ) attractionLabel.toolTip = "Configure how the segmentation travels towards gradient ridges (vessel lumen wall)." segmentationAdvancedFormLayout.addRow( attractionLabel ) self.__attractionSlider = ctk.ctkSliderWidget() self.__attractionSlider.decimals = 0 self.__attractionSlider.minimum = -100 self.__attractionSlider.maximum = 100 self.__attractionSlider.singleStep = 10 self.__attractionSlider.toolTip = attractionLabel.toolTip segmentationAdvancedFormLayout.addRow( self.__attractionSlider ) # iteration spinbox self.__iterationSpinBox = qt.QSpinBox() self.__iterationSpinBox.minimum = 0 self.__iterationSpinBox.maximum = 5000 self.__iterationSpinBox.singleStep = 10 self.__iterationSpinBox.toolTip = "Choose the number of evolution iterations." segmentationAdvancedFormLayout.addRow( SlicerVmtkCommonLib.Helper.CreateSpace( 100 ) + "Iterations:", self.__iterationSpinBox ) # # Reset, preview and apply buttons # self.__buttonBox = qt.QDialogButtonBox() self.__resetButton = self.__buttonBox.addButton( self.__buttonBox.RestoreDefaults ) self.__resetButton.toolTip = "Click to reset all input elements to default." self.__previewButton = self.__buttonBox.addButton( self.__buttonBox.Discard ) self.__previewButton.setIcon( qt.QIcon() ) self.__previewButton.text = "Preview.." self.__previewButton.toolTip = "Click to refresh the preview." self.__startButton = self.__buttonBox.addButton( self.__buttonBox.Apply ) self.__startButton.setIcon( qt.QIcon() ) self.__startButton.text = "Start!" self.__startButton.enabled = False self.__startButton.toolTip = "Click to start the filtering." self.layout.addWidget( self.__buttonBox ) self.__resetButton.connect( "clicked()", self.restoreDefaults ) self.__previewButton.connect( "clicked()", self.onRefreshButtonClicked ) self.__startButton.connect( "clicked()", self.onStartButtonClicked ) self.__inputVolumeNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__seedFiducialsNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__vesselnessVolumeNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__outputVolumeNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__outputModelNodeSelector.setMRMLScene( slicer.mrmlScene ) self.__stopperFiducialsNodeSelector.setMRMLScene( slicer.mrmlScene ) # be ready for events self.__updating = 0 # set default values self.restoreDefaults() # compress the layout self.layout.addStretch( 1 )
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.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> <li><b>Joint smoothing:</b> smoothes all visible segments at once. It requires segments to be non-overlapping. Bypasses masking settings.</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.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)