Ejemplo n.º 1
1
  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()
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 8
0
    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()
Ejemplo n.º 9
0
  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 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)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
  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)
Ejemplo n.º 16
0
  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)
Ejemplo n.º 17
0
 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
Ejemplo n.º 18
0
  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)
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
    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)
Ejemplo n.º 22
0
  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)
Ejemplo n.º 23
0
    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)
Ejemplo n.º 24
0
    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)
Ejemplo n.º 25
0
  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)
Ejemplo n.º 27
0
  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)
Ejemplo n.º 29
0
  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()
Ejemplo n.º 30
0
  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()
Ejemplo n.º 33
0
    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)
Ejemplo n.º 34
0
  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()
Ejemplo n.º 35
0
  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 = {}
Ejemplo n.º 36
0
  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 )
Ejemplo n.º 37
0
    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 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)
Ejemplo n.º 40
0
  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)
Ejemplo n.º 41
0
    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)
Ejemplo n.º 43
0
  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)
Ejemplo n.º 44
0
  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()
Ejemplo n.º 46
0
  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)
Ejemplo n.º 47
0
    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()
Ejemplo n.º 48
0
  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()
Ejemplo n.º 49
0
    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)
Ejemplo n.º 50
0
  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()
Ejemplo n.º 51
0
    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()
Ejemplo n.º 52
0
  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'))
Ejemplo n.º 54
0
  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)
Ejemplo n.º 55
0
  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()
Ejemplo n.º 56
0
    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)
Ejemplo n.º 57
0
  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 )
Ejemplo n.º 58
0
  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)