Esempio n. 1
0
    def create(self):
        super(FastGrowCutEffectOptions, self).create()
        self.helpLabel = qt.QLabel(
            "Run the Fast GrowCut segmentation on the current label/seed image.\n Background and foreground seeds will be used as starting points to fill in the rest of the volume.",
            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)

        #HelpButton(self.frame, "TO USE: \n Start the interactive segmenter and initialize the segmentation with any other editor tool. \n KEYS: \n Press the following keys to interact: \n C: copy label slice \n V: paste label slice \n Q: evolve contour in 2D \n E: evolve contour in 3D \n A: toggle between draw/erase modes" )
        HelpButton(
            self.frame,
            "TO USE: \n Start the Fast GrowCut segmenter and initialize the segmentation with any other editor tool. \n KEYS: \n Press the following keys to interact: \n G: start Fast GrowCut \n S: toggle between seed image and segmentation result \n R: reset fast GrowCut \n"
        )
        self.frame.layout().addStretch(1)  # Add vertical spacer

        if hasattr(slicer.modules, 'FGCEditorBot'):
            slicer.util.showStatusMessage(
                slicer.modules.FGCEditorBot.logic.currentMessage)
            self.botButton.text = "Stop FastGrowCut Segmenter"
            if self.locRadFrame:
                self.locRadFrame.hide()
        else:
            self.botButton.text = "Start FastGrowCut Segmenter"
            if self.locRadFrame:
                self.locRadFrame.show()
Esempio n. 2
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)
  def create(self):
    super(EditorExtensionTemplateOptions,self).create()
    self.apply = qt.QPushButton("Apply", self.frame)
    self.apply.setToolTip("Apply the extension operation")
    self.frame.layout().addWidget(self.apply)
    self.widgets.append(self.apply)

    HelpButton(self.frame, "This is a sample with no real functionality.")

    self.apply.connect('clicked()', self.onApply)

    # Add vertical spacer
    self.frame.layout().addStretch(1)
Esempio n. 4
0
  def create(self):
    super(TemplateKeyEffectOptions,self).create()
    self.apply = qt.QPushButton("Apply", self.frame)
    self.apply.objectName = self.__class__.__name__ + 'Apply'
    self.apply.setToolTip("Apply the extension operation")
    self.frame.layout().addWidget(self.apply)
    self.widgets.append(self.apply)

    HelpButton(self.frame, "This is a sample with no real functionality.")

    self.connections.append( (self.apply, 'clicked()', self.onApply) )

    # Add vertical spacer
    self.frame.layout().addStretch(1)
Esempio n. 5
0
  def create(self):
    super(WandEffectOptions,self).create()

    self.toleranceFrame = qt.QFrame(self.frame)
    self.toleranceFrame.setLayout(qt.QHBoxLayout())
    self.frame.layout().addWidget(self.toleranceFrame)
    self.widgets.append(self.toleranceFrame)
    self.toleranceLabel = qt.QLabel("Tolerance:", self.toleranceFrame)
    self.toleranceLabel.setToolTip("Set the tolerance of the wand in terms of background pixel values")
    self.toleranceFrame.layout().addWidget(self.toleranceLabel)
    self.widgets.append(self.toleranceLabel)
    self.toleranceSpinBox = qt.QDoubleSpinBox(self.toleranceFrame)
    self.toleranceSpinBox.setToolTip("Set the tolerance of the wand in terms of background pixel values")
    self.toleranceSpinBox.minimum = 0
    self.toleranceSpinBox.maximum = 1000
    self.toleranceSpinBox.suffix = ""
    self.toleranceFrame.layout().addWidget(self.toleranceSpinBox)
    self.widgets.append(self.toleranceSpinBox)

    self.maxPixelsFrame = qt.QFrame(self.frame)
    self.maxPixelsFrame.setLayout(qt.QHBoxLayout())
    self.frame.layout().addWidget(self.maxPixelsFrame)
    self.widgets.append(self.maxPixelsFrame)
    self.maxPixelsLabel = qt.QLabel("Max Pixels per click:", self.maxPixelsFrame)
    self.maxPixelsLabel.setToolTip("Set the maxPixels for each click")
    self.maxPixelsFrame.layout().addWidget(self.maxPixelsLabel)
    self.widgets.append(self.maxPixelsLabel)
    self.maxPixelsSpinBox = qt.QDoubleSpinBox(self.maxPixelsFrame)
    self.maxPixelsSpinBox.setToolTip("Set the maxPixels for each click")
    self.maxPixelsSpinBox.minimum = 1
    self.maxPixelsSpinBox.maximum = 100000
    self.maxPixelsSpinBox.suffix = ""
    self.maxPixelsFrame.layout().addWidget(self.maxPixelsSpinBox)
    self.widgets.append(self.maxPixelsSpinBox)

    HelpButton(self.frame, "Use this tool to label all voxels that are within a tolerance of where you click")

    # don't connect the signals and slots directly - instead, add these
    # to the list of connections so that gui callbacks can be cleanly 
    # disabled while the gui is being updated.  This allows several gui
    # elements to be interlinked with signal/slots but still get updated
    # as a unit to the new value of the mrml node.
    self.connections.append( 
        (self.toleranceSpinBox, 'valueChanged(double)', self.onToleranceSpinBoxChanged) )
    self.connections.append( 
        (self.maxPixelsSpinBox, 'valueChanged(double)', self.onMaxPixelsSpinBoxChanged) )

    # Add vertical spacer
    self.frame.layout().addStretch(1)
Esempio n. 6
0
  def create(self):
    super(GrowCutCLOptions,self).create()

    self.deviceTypeComboBox = qt.QComboBox()
    self.deviceTypeComboBox.addItem('CPU')
    self.deviceTypeComboBox.addItem('GPU')
    self.deviceTypeComboBox.connect('currentIndexChanged(int)', self.onDeviceTypeChanged)
    self.frame.layout().addWidget(self.deviceTypeComboBox)

    self.botButton = qt.QPushButton(self.frame)
    if hasattr(slicer.modules, 'editorBot'):
      self.botButton.text = "Stop Bot"
    else:
      self.botButton.text = "Start Bot"
    self.frame.layout().addWidget(self.botButton)

    self.acceptButton = qt.QPushButton(self.frame)
    self.acceptButton.text = "Accept Steered Label"
    self.frame.layout().addWidget(self.acceptButton)

    HelpButton(self.frame, "This is an interactive segmentation tool that is actively calculating a region-growing method as you provide additional input.  Starting the Bot will cause the segmentation to grow using your current labels as input.")

    self.botButton.connect('clicked()', self.onStartBot)
    self.acceptButton.connect('clicked()', self.onAccept)

    # Add vertical spacer
    self.frame.layout().addStretch(1)

    # TODO: the functionality for the steered volume should migrate to
    # the edit helper class when functionality is finalized.
    backgroundVolume = self.editUtil.getBackgroundVolume()
    labelVolume = self.editUtil.getLabelVolume()
    steeredName = backgroundVolume.GetName() + '-steered'
    steeredVolume = slicer.util.getNode(steeredName)
    if not steeredVolume:
      volumesLogic = slicer.modules.volumes.logic()
      steeredVolume = volumesLogic.CloneVolume(
                           slicer.mrmlScene, labelVolume, steeredName)
    compositeNodes = slicer.util.getNodes('vtkMRMLSliceCompositeNode*')
    for compositeNode in compositeNodes.values():
      compositeNode.SetForegroundVolumeID(steeredVolume.GetID())
      compositeNode.SetForegroundOpacity(0.5)
    def create(self):
        super(ShortCutOptions, self).create()
        self.helpLabel = qt.QLabel("Run the Quick TCGA Segmenter on the current label/seed image.", self.frame)
        self.frame.layout().addWidget(self.helpLabel)

        # Create a "Start Bot" button: "Start Quick TCGA Segmenter"
        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)

        # Skip for now:
        # self.nucleus_segmentation_parameters()

        HelpButton(self.frame, (
            "TO USE: \n Start the ShortCut 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()
Esempio n. 8
0
    def create(self):
        super(IsobrushEffectOptions, self).create()
        self.apply = qt.QPushButton("Apply", self.frame)
        self.apply.objectName = self.__class__.__name__ + 'Apply'
        self.apply.setToolTip("Apply the extension operation")
        self.frame.layout().addWidget(self.apply)
        self.widgets.append(self.apply)
        self.connections.append((self.apply, 'clicked()', self.onApply))

        if self.developerMode:
            self.reload = qt.QPushButton("Reload", self.frame)
            self.reload.objectName = self.__class__.__name__ + 'Apply'
            self.reload.setToolTip("Reload this effect")
            self.frame.layout().addWidget(self.reload)
            self.widgets.append(self.reload)
            self.connections.append((self.reload, 'clicked()', self.onReload))

        HelpButton(self.frame, "This is a fancy paint brush.")

        # Add vertical spacer
        self.frame.layout().addStretch(1)
Esempio n. 9
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()
Esempio n. 10
0
  def create(self):
    super(WatershedFromMarkerEffectOptions,self).create()

    if not HAVE_SIMPLEITK:
      self.warningLabel = qt.QLabel()
      self.warningLabel.text = "WatershedFromMarker is not available because\nSimpleITK is not available in this build"
      self.widgets.append(self.warningLabel)
      self.frame.layout().addWidget(self.warningLabel)
      return

    labelVolume = self.editUtil.getLabelVolume()
    if labelVolume and labelVolume.GetImageData():
      spacing = labelVolume.GetSpacing()
      self.minimumSigma = 0.1 * min(spacing)
      self.maximumSigma = 100 * self.minimumSigma
    else:
      self.minimumSigma = 0.1
      self.maximumSigma = 10


    self.sigmaFrame = qt.QFrame(self.frame)
    self.sigmaFrame.setLayout(qt.QHBoxLayout())
    self.frame.layout().addWidget(self.sigmaFrame)
    self.widgets.append(self.sigmaFrame)

    tip = "Increasing this value smooths the segmentation and reduces leaks. This is the sigma used for edge detection."
    self.sigmaLabel = qt.QLabel("Object Scale: ", self.frame)
    self.sigmaLabel.setToolTip(tip)
    self.sigmaFrame.layout().addWidget(self.sigmaLabel)
    self.widgets.append(self.sigmaLabel)

    self.sigmaSlider = qt.QSlider( qt.Qt.Horizontal, self.frame )
    self.sigmaFrame.layout().addWidget(self.sigmaSlider)
    self.sigmaFrame.setToolTip(tip)
    self.widgets.append(self.sigmaSlider)

    self.sigmaSpinBox = qt.QDoubleSpinBox(self.frame)
    self.sigmaSpinBox.setToolTip(tip)
    self.sigmaSpinBox.suffix = "mm"

    self.sigmaFrame.layout().addWidget(self.sigmaSpinBox)
    self.widgets.append(self.sigmaSpinBox)

    self.sigmaSpinBox.minimum = self.minimumSigma
    self.sigmaSlider.minimum = self.minimumSigma
    self.sigmaSpinBox.maximum = self.maximumSigma
    self.sigmaSlider.maximum = self.maximumSigma

    decimals = math.floor(math.log(self.minimumSigma,10))
    if decimals < 0:
      self.sigmaSpinBox.decimals = -decimals + 2


    self.apply = qt.QPushButton("Apply", self.frame)
    self.apply.setToolTip("Apply the extension operation")

    self.frame.layout().addWidget(self.apply)
    self.widgets.append(self.apply)

    helpDoc = \
        """Use this effect to apply the watershed from markers segmentation from multiple initial labels.

The input to this filter is current labelmap image which is expected to contain multiple labels as initial markss. The marks or labels are grown to fill the image and with edges defining the bondaries between. To segment a single object, mark the object, and then it is suggested to surround the object with a negative label on each axis.

The "Object Scale" parameter is use to adjust the smoothness of the output image and prevent leakage. It is used internally for the sigma of the gradient magnitude.
    """
    HelpButton(self.frame, helpDoc)



    self.sigmaSlider.connect( 'valueChanged(int)', self.sigmaSpinBox.setValue )
    self.sigmaSpinBox.connect( 'valueChanged(double)', self.sigmaSlider.setValue )

    # if either widget is changed both should change and this should be triggered
    self.connections.append( ( self.sigmaSpinBox, 'valueChanged(double)', self.onSigmaValueChanged ) )

    self.connections.append( (self.apply, 'clicked()', self.onApply) )

    # Add vertical spacer
    self.frame.layout().addStretch(1)
Esempio n. 11
0
  def create(self):
    super(GooCutOptions,self).create()

    self.botButton = qt.QPushButton(self.frame)
    self.botButton.text = "Start Bot"
    self.frame.layout().addWidget(self.botButton)

    self.toleranceFrame = qt.QFrame(self.frame)
    self.toleranceFrame.setLayout(qt.QHBoxLayout())
    self.frame.layout().addWidget(self.toleranceFrame)
    self.widgets.append(self.toleranceFrame)
    self.toleranceLabel = qt.QLabel("Tolerance:", self.toleranceFrame)
    self.toleranceLabel.setToolTip("Set the tolerance of the wand in terms of background pixel values")
    self.toleranceFrame.layout().addWidget(self.toleranceLabel)
    self.widgets.append(self.toleranceLabel)
    self.toleranceSpinBox = qt.QDoubleSpinBox(self.toleranceFrame)
    self.toleranceSpinBox.setToolTip("Set the tolerance of the wand in terms of background pixel values")
    self.toleranceSpinBox.minimum = 0
    self.toleranceSpinBox.maximum = 1000
    self.toleranceSpinBox.suffix = ""
    self.toleranceFrame.layout().addWidget(self.toleranceSpinBox)
    self.widgets.append(self.toleranceSpinBox)

    self.maxPixelsFrame = qt.QFrame(self.frame)
    self.maxPixelsFrame.setLayout(qt.QHBoxLayout())
    self.frame.layout().addWidget(self.maxPixelsFrame)
    self.widgets.append(self.maxPixelsFrame)
    self.maxPixelsLabel = qt.QLabel("Max Pixels per click:", self.maxPixelsFrame)
    self.maxPixelsLabel.setToolTip("Set the maxPixels for each click")
    self.maxPixelsFrame.layout().addWidget(self.maxPixelsLabel)
    self.widgets.append(self.maxPixelsLabel)
    self.maxPixelsSpinBox = qt.QDoubleSpinBox(self.maxPixelsFrame)
    self.maxPixelsSpinBox.setToolTip("Set the maxPixels for each click")
    self.maxPixelsSpinBox.minimum = 1
    self.maxPixelsSpinBox.maximum = 1000
    self.maxPixelsSpinBox.suffix = ""
    self.maxPixelsFrame.layout().addWidget(self.maxPixelsSpinBox)
    self.widgets.append(self.maxPixelsSpinBox)

    HelpButton(self.frame, "Use this tool to label all voxels that are within a tolerance of where you click")

    self.botButton.connect('clicked()', self.onStartBot)
    self.toleranceSpinBox.connect('valueChanged(double)', self.onToleranceSpinBoxChanged)
    self.maxPixelsSpinBox.connect('valueChanged(double)', self.onMaxPixelsSpinBoxChanged)

    # Add vertical spacer
    self.frame.layout().addStretch(1)

    # TODO: the functionality for the steered volume should migrate to
    # the edit helper class when functionality is finalized.
    backgroundVolume = self.editUtil.getBackgroundVolume()
    labelVolume = self.editUtil.getLabelVolume()
    steeredName = backgroundVolume.GetName() + '-steered'
    steeredVolume = slicer.util.getNode(steeredName)
    if not steeredVolume:
      volumesLogic = slicer.modules.volumes.logic()
      steeredVolume = volumesLogic.CloneVolume(
                           slicer.mrmlScene, labelVolume, steeredName)
    compositeNodes = slicer.util.getNodes('vtkMRMLSliceCompositeNode*')
    for compositeNode in compositeNodes.values():
      compositeNode.SetForegroundVolumeID(steeredVolume.GetID())
      compositeNode.SetForegroundOpacity(0.5)
Esempio n. 12
0
    def create(self):

        super(BinaryWatershedEffectOptions, self).create()

        if not HAVE_SIMPLEITK:
            self.warningLabel = qt.QLabel()
            self.warningLabel.text = "BinaryWatershed is not available because\nSimpleITK is not available in this build"
            self.widgets.append(self.warningLabel)
            self.frame.layout().addWidget(self.warningLabel)
            return

        self.splitSizeFrame = qt.QFrame(self.frame)
        self.splitSizeFrame.setLayout(qt.QHBoxLayout())
        self.frame.layout().addWidget(self.splitSizeFrame)
        self.widgets.append(self.splitSizeFrame)

        tip = "Sets the a minimum size for labels which will be split into multiple objects."
        self.splitSizeLabel = qt.QLabel("Split Size:", self.frame)
        self.splitSizeLabel.setToolTip(tip)
        self.splitSizeFrame.layout().addWidget(self.splitSizeLabel)
        self.widgets.append(self.splitSizeLabel)

        self.minimumSplitSize = 0
        self.maximumSplitSize = 100

        self.splitSizeSlider = qt.QSlider(qt.Qt.Horizontal, self.frame)
        self.splitSizeSlider.setValue(1)
        self.splitSizeFrame.layout().addWidget(self.splitSizeSlider)
        self.splitSizeFrame.setToolTip(tip)
        self.widgets.append(self.splitSizeSlider)

        self.splitSizeSpinBox = qt.QDoubleSpinBox(self.frame)
        self.splitSizeSpinBox.setToolTip(tip)
        self.splitSizeSpinBox.setValue(1)
        self.splitSizeSpinBox.suffix = "mm"

        self.splitSizeFrame.layout().addWidget(self.splitSizeSpinBox)
        self.widgets.append(self.splitSizeSpinBox)

        self.splitSizeSpinBox.minimum = self.minimumSplitSize
        self.splitSizeSlider.minimum = self.minimumSplitSize
        self.splitSizeSpinBox.maximum = self.maximumSplitSize
        self.splitSizeSlider.maximum = self.maximumSplitSize

        self.apply = qt.QPushButton("Apply", self.frame)
        self.apply.setToolTip("Apply the binary watershed operation")
        self.frame.layout().addWidget(self.apply)
        self.widgets.append(self.apply)

        helpDoc = """Split selected label into separate objects based at minimum size the objects."""
        HelpButton(self.frame, helpDoc)

        self.apply.connect('clicked()', self.onApply)

        self.splitSizeSlider.connect('valueChanged(int)',
                                     self.splitSizeSpinBox.setValue)
        self.splitSizeSpinBox.connect('valueChanged(double)',
                                      self.splitSizeSlider.setValue)

        # if either widget is changed both should change and this should be triggered
        self.connections.append((self.splitSizeSpinBox, 'valueChanged(double)',
                                 self.onSplitSizeValueChanged))

        # Add vertical spacer
        self.frame.layout().addStretch(1)
Esempio n. 13
0
    def create(self):
        super(PETTumorSegmentationEffectOptions, self).create()

        #Save space in the GUI
        self.frame.layout().setSpacing(0)
        self.frame.layout().setMargin(0)

        # refinementBoxesFrame contains the options for how clicks are handled
        self.refinementBoxesFrame = qt.QFrame(self.frame)
        self.refinementBoxesFrame.setLayout(qt.QHBoxLayout())
        self.refinementBoxesFrame.layout().setSpacing(0)
        self.refinementBoxesFrame.layout().setMargin(0)
        self.frame.layout().addWidget(self.refinementBoxesFrame)

        #default is global refinement (threshold refinement)
        self.noRefinementRadioButton = qt.QRadioButton(
            "Create new", self.refinementBoxesFrame)
        self.noRefinementRadioButton.setToolTip(
            "On click, always segment a new object.")
        self.globalRefinementRadioButton = qt.QRadioButton(
            "Global refinement", self.refinementBoxesFrame)
        self.globalRefinementRadioButton.setToolTip(
            "On click, refine globally (adjusting then entire boundary) if no center point for the label, otherwise segment a new object."
        )
        self.localRefinementRadioButton = qt.QRadioButton(
            "Local refinement", self.refinementBoxesFrame)
        self.localRefinementRadioButton.setToolTip(
            "On click, refine locally (adjusting part of the boundary) if no center point for the label, otherwise segment a new object."
        )
        self.globalRefinementRadioButton.setChecked(True)

        #radio button so only one can be applied
        self.refinementBoxesFrame.layout().addWidget(
            qt.QLabel("Interaction style: ", self.refinementBoxesFrame))
        self.refinementBoxesFrame.layout().addWidget(
            self.noRefinementRadioButton)
        self.refinementBoxesFrame.layout().addWidget(
            self.globalRefinementRadioButton)
        self.refinementBoxesFrame.layout().addWidget(
            self.localRefinementRadioButton)
        self.refinementBoxesFrame.layout().addStretch(1)
        self.widgets.append(self.noRefinementRadioButton)
        self.widgets.append(self.globalRefinementRadioButton)
        self.widgets.append(self.localRefinementRadioButton)
        self.noRefinementRadioButton.connect('clicked()',
                                             self.onRefinementTypeChanged)
        self.localRefinementRadioButton.connect('clicked()',
                                                self.onRefinementTypeChanged)
        self.globalRefinementRadioButton.connect('clicked()',
                                                 self.onRefinementTypeChanged)

        #options are hidden (collapsed) until requested
        self.optFrame = ctk.ctkCollapsibleButton(self.frame)
        self.optFrame.setText("Options")
        self.optFrame.setLayout(qt.QVBoxLayout())
        self.optFrame.layout().setSpacing(0)
        self.optFrame.layout().setMargin(0)
        self.optFrame.visible = True
        self.optFrame.collapsed = True
        self.optFrame.collapsedHeight = 0
        self.optFrame.setToolTip("Displays algorithm options.")

        #most useful options are kept on top: Splitting, Sealing, Assist Centering, Allow
        # Overwriting
        #to save vertical space, put 2 ina  row, so subframes here with horizontal layout are used

        #first row
        self.commonCheckBoxesFrame1 = qt.QFrame(self.optFrame)
        self.commonCheckBoxesFrame1.setLayout(qt.QHBoxLayout())
        self.commonCheckBoxesFrame1.layout().setSpacing(0)
        self.commonCheckBoxesFrame1.layout().setMargin(0)
        self.optFrame.layout().addWidget(self.commonCheckBoxesFrame1)

        #top left
        self.splittingCheckBox = qt.QCheckBox("Splitting",
                                              self.commonCheckBoxesFrame1)
        self.splittingCheckBox.setToolTip(
            "Cut off adjacent objects to the target via watershed or local minimum.  Useful for lymph node chains."
        )
        self.splittingCheckBox.checked = False
        self.commonCheckBoxesFrame1.layout().addWidget(self.splittingCheckBox)
        self.widgets.append(self.splittingCheckBox)

        #top right
        self.sealingCheckBox = qt.QCheckBox("Sealing",
                                            self.commonCheckBoxesFrame1)
        self.sealingCheckBox.setToolTip(
            "Close single-voxel gaps in the object or between the object and other objects, if above the threshold.  Useful for lymph node chains."
        )
        self.sealingCheckBox.checked = False
        self.commonCheckBoxesFrame1.layout().addWidget(self.sealingCheckBox)
        self.widgets.append(self.sealingCheckBox)

        #second row
        self.commonCheckBoxesFrame2 = qt.QFrame(self.optFrame)
        self.commonCheckBoxesFrame2.setLayout(qt.QHBoxLayout())
        self.commonCheckBoxesFrame2.layout().setSpacing(0)
        self.commonCheckBoxesFrame2.layout().setMargin(0)
        self.optFrame.layout().addWidget(self.commonCheckBoxesFrame2)

        #bottom left
        self.assistCenteringCheckBox = qt.QCheckBox(
            "Assist Centering", self.commonCheckBoxesFrame2)
        self.assistCenteringCheckBox.setToolTip(
            "Move the center to the highest voxel within 7 physical units, without being on or next to other object labels.  Improves consistency."
        )
        self.assistCenteringCheckBox.checked = True
        self.commonCheckBoxesFrame2.layout().addWidget(
            self.assistCenteringCheckBox)
        self.widgets.append(self.assistCenteringCheckBox)

        #bottom right
        self.allowOverwritingCheckBox = qt.QCheckBox(
            "Allow Overwriting", self.commonCheckBoxesFrame2)
        self.allowOverwritingCheckBox.setToolTip("Ignore other object labels.")
        self.allowOverwritingCheckBox.checked = False
        self.commonCheckBoxesFrame2.layout().addWidget(
            self.allowOverwritingCheckBox)
        self.widgets.append(self.allowOverwritingCheckBox)

        #advanced options, for abnormal cases such as massive necrotic objects or
        #low-transition scans like phantoms
        #infrequently used, just keep vertical
        self.advFrame = ctk.ctkCollapsibleButton(self.optFrame)
        self.advFrame.setText("Advanced")
        self.advFrame.setLayout(qt.QVBoxLayout())
        self.advFrame.layout().setSpacing(0)
        self.advFrame.layout().setMargin(0)
        self.advFrame.visible = True
        self.advFrame.collapsed = True
        self.advFrame.collapsedHeight = 0
        self.advFrame.setToolTip(
            "Displays more advanced algorithm options.  Do not use if you don't know what they mean."
        )

        #top
        self.necroticRegionCheckBox = qt.QCheckBox("Necrotic Region",
                                                   self.advFrame)
        self.necroticRegionCheckBox.setToolTip(
            "Prevents cutoff from low uptake.  Use if placing a center inside a necrotic region."
        )
        self.necroticRegionCheckBox.checked = False
        self.advFrame.layout().addWidget(self.necroticRegionCheckBox)
        self.widgets.append(self.necroticRegionCheckBox)

        #middle
        self.denoiseThresholdCheckBox = qt.QCheckBox("Denoise Threshold",
                                                     self.advFrame)
        self.denoiseThresholdCheckBox.setToolTip(
            "Calculates threshold based on median-filtered image.  Use only if scan is very noisey."
        )
        self.denoiseThresholdCheckBox.checked = False
        self.advFrame.layout().addWidget(self.denoiseThresholdCheckBox)
        self.widgets.append(self.denoiseThresholdCheckBox)

        #bottom
        self.linearCostCheckBox = qt.QCheckBox("Linear Cost", self.advFrame)
        self.linearCostCheckBox.setToolTip(
            "Cost function below threshold is linear rather than based on region.  Use only if little/no transition region in uptake."
        )
        self.linearCostCheckBox.checked = False
        self.advFrame.layout().addWidget(self.linearCostCheckBox)
        self.widgets.append(self.linearCostCheckBox)

        self.optFrame.layout().addWidget(self.advFrame)

        #apply button kept at bottom of all options
        self.applyButton = qt.QPushButton("Apply", self.optFrame)
        self.optFrame.layout().addWidget(self.applyButton)
        self.applyButton.connect('clicked()', self.onApply)
        self.widgets.append(self.applyButton)
        self.applyButton.setToolTip(
            "Redo last segmentation with the same center and refinement points with any changes in options."
        )

        #When changing settings, update the MRML with it
        self.assistCenteringCheckBox.connect('toggled(bool)',
                                             self.updateMRMLFromGUI)
        self.allowOverwritingCheckBox.connect('toggled(bool)',
                                              self.updateMRMLFromGUI)
        self.splittingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI)
        self.sealingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI)
        self.necroticRegionCheckBox.connect('toggled(bool)',
                                            self.updateMRMLFromGUI)
        self.denoiseThresholdCheckBox.connect('toggled(bool)',
                                              self.updateMRMLFromGUI)
        self.linearCostCheckBox.connect('toggled(bool)',
                                        self.updateMRMLFromGUI)

        self.frame.layout().addWidget(self.optFrame)

        HelpButton(
            self.frame,
            "Click on a lesion in a PET scan to segment it. Depending on refinement settings, click again to refine globally and/or locally. Options may help deal with cases such as segmenting individual lesions in a chain. For more information: http://www.slicer.org/slicerWiki/index.php/Documentation/4.4/Modules/PETTumorSegmentationEffect"
        )

        # Add vertical spacer
        self.frame.layout().addStretch(1)

        # Clear any existing data and undo/redo queue; working directly with other tools is
        # beyond the scope of this
        self.logic.reset()

        self.updateGUIFromMRML(self, 0)
Esempio n. 14
0
    def create(self):

        super(RobustStatisticsSegmenterOptions, self).create()
        self.goToRobustStatisticsSegmenter = qt.QPushButton(
            "Go To RSS Segmenter", self.frame)
        self.goToRobustStatisticsSegmenter.setToolTip(
            "Robust Statistics Segmentation - allows fast segmentation of 2D/3D data given an initial seed."
        )
        self.frame.layout().addWidget(self.goToRobustStatisticsSegmenter)
        self.widgets.append(self.goToRobustStatisticsSegmenter)

        # gui widgets for exposing some parameter control
        self.smooth_boundary = qt.QCheckBox("Smooth Boundary?", self.frame)
        self.good_contrast = qt.QCheckBox("Good Contrast?", self.frame)
        self.smooth_boundary.checked = True
        self.good_contrast.checked = True
        self.smooth_boundary.setToolTip(
            "Is the boundary of the region smooth (not jagged)?.")
        self.good_contrast.setToolTip(
            "Is the boundary of the region visually very clear?.")
        self.frame.layout().addWidget(self.smooth_boundary)
        self.frame.layout().addWidget(self.good_contrast)
        self.widgets.append(self.smooth_boundary)
        self.widgets.append(self.good_contrast)

        # create button group for selecting size
        self.region_small = qt.QRadioButton("Small ~10mL", self.frame)
        self.region_small.setToolTip("about the size of a grape")
        self.region_medium = qt.QRadioButton("Medium ~100mL", self.frame)
        self.region_medium.setToolTip("about the size of a golf ball")
        self.region_large = qt.QRadioButton("Large ~500mL", self.frame)
        self.region_large.setToolTip("about the size of your fist")
        self.region_medium.checked = True
        self.frame.layout().addWidget(self.region_small)
        self.widgets.append(self.region_small)
        self.frame.layout().addWidget(self.region_medium)
        self.widgets.append(self.region_medium)
        self.frame.layout().addWidget(self.region_large)
        self.widgets.append(self.region_large)

        #
        # Setup parameters [minimalist & intuitive]
        #

        self.apply = qt.QPushButton("Apply", self.frame)
        self.apply.setToolTip(
            "Segment the region of interest from the seed provided - using the Robust Statistical Segmenter"
        )
        self.frame.layout().addWidget(self.apply)
        self.widgets.append(self.apply)

        HelpButton(self.frame, "Use this tool to segment 3D regions.")

        # Add vertical spacer
        self.frame.layout().addStretch(1)

        self.apply.connect('clicked()', self.onApply)
        self.goToRobustStatisticsSegmenter.connect(
            'clicked()', self.onGoToRobustStatisticsSegmenter)

        # disable segmentation unless seed is selected
        self.confirmSeedSelection()
Esempio n. 15
0
    def create(self):
        super(TraceAndSelectOptions, self).create()

        ## Custom threshold box
        # Note: This is needed because other tools can disable, hide, or manipulate the default threshold box
        # We need one unique to our tool
        self.threshLabel = qt.QLabel("Threshold", self.frame)
        self.threshLabel.setToolTip(
            "In threshold mode, the label will only be set if the background value is within this range."
        )
        self.frame.layout().addWidget(self.threshLabel)
        self.widgets.append(self.threshLabel)
        self.thresh = ctk.ctkRangeWidget(self.frame)
        self.thresh.spinBoxAlignment = 0xff  # put enties on top
        self.thresh.singleStep = 0.01
        self.setRangeWidgetToBackgroundRange(self.thresh)
        self.frame.layout().addWidget(self.thresh)
        self.widgets.append(self.thresh)
        ## End custom threshold box

        ## Preview checkbox
        self.preview = qt.QCheckBox("Preview outlines", self.frame)
        self.preview.setToolTip(
            "Preview the outline of a selection with right-click.")
        self.frame.layout().addWidget(self.preview)
        ## End preview checkbox

        self.modeButtons = qt.QButtonGroup(self.frame)
        self.tissueRadioButton = qt.QRadioButton("Tissue Mode", self.frame)
        self.boneRadioButton = qt.QRadioButton("Bone/Nerve Mode", self.frame)
        self.hbox = qt.QHBoxLayout()
        self.hbox.addWidget(self.boneRadioButton)
        self.hbox.addWidget(self.tissueRadioButton)
        self.frame.layout().addLayout(self.hbox)
        self.modeButtons.addButton(self.boneRadioButton)
        self.modeButtons.addButton(self.tissueRadioButton)

        self.widgets.append(self.tissueRadioButton)
        self.widgets.append(self.boneRadioButton)

        ## ERROR MESSAGE FRAME
        self.errorMessageFrame = qt.QTextEdit(self.frame)
        self.frame.layout().addWidget(self.errorMessageFrame)
        #self.errorMessageFrame.setLayout(qt.QHBoxLayout)
        self.errorMessageFrame.setFixedWidth(280)
        self.errorMessageFrame.setReadOnly(True)
        self.errorMessageFrame.setText('No Error Detected')
        self.errorMessageFrame.setStyleSheet("QTextEdit {color:green}")
        self.widgets.append(self.errorMessageFrame)
        ## END ERROR MESSAGE FRAME

        ## For the offset value selection process
        self.offsetvalueFrame = qt.QFrame(self.frame)
        self.offsetvalueFrame.setLayout(qt.QHBoxLayout())
        self.frame.layout().addWidget(self.offsetvalueFrame)
        self.widgets.append(self.offsetvalueFrame)
        self.offsetvalueLabel = qt.QLabel("Offset Value:",
                                          self.offsetvalueFrame)
        self.offsetvalueLabel.setToolTip(
            "Set the offset value shift upon an action")
        self.offsetvalueFrame.layout().addWidget(self.offsetvalueLabel)
        self.widgets.append(self.offsetvalueLabel)
        self.offsetvalueSpinBox = qt.QDoubleSpinBox(self.offsetvalueFrame)
        self.offsetvalueSpinBox.setToolTip(
            "Set the offset value shift upon an action")
        self.offsetvalueSpinBox.minimum = -1000
        self.offsetvalueSpinBox.maximum = 1000
        self.offsetvalueSpinBox.suffix = ""
        self.offsetvalueFrame.layout().addWidget(self.offsetvalueSpinBox)
        self.widgets.append(self.offsetvalueSpinBox)
        ## End offset value selection

        self.maxPixelsFrame = qt.QFrame(self.frame)
        self.maxPixelsFrame.setLayout(qt.QHBoxLayout())
        self.frame.layout().addWidget(self.maxPixelsFrame)
        self.widgets.append(self.maxPixelsFrame)
        self.maxPixelsLabel = qt.QLabel("Max Pixels per click:",
                                        self.maxPixelsFrame)
        self.maxPixelsLabel.setToolTip("Set the maxPixels for each click")
        self.maxPixelsFrame.layout().addWidget(self.maxPixelsLabel)
        self.widgets.append(self.maxPixelsLabel)
        self.maxPixelsSpinBox = qt.QDoubleSpinBox(self.maxPixelsFrame)
        self.maxPixelsSpinBox.setToolTip("Set the maxPixels for each click")
        self.maxPixelsSpinBox.minimum = 1
        self.maxPixelsSpinBox.maximum = 100000
        self.maxPixelsSpinBox.suffix = ""
        self.maxPixelsFrame.layout().addWidget(self.maxPixelsSpinBox)
        self.widgets.append(self.maxPixelsSpinBox)

        # Help Browser
        self.helpBrowser = qt.QPushButton("Visit the Webpage")

        # End Help Browser
        self.frame.layout().addWidget(self.helpBrowser)

        HelpButton(
            self.frame,
            "Use this tool to help you label all voxels enclosed in an area bounded by the the largest path of pixels within the specified threshold."
        )

        # don't connect the signals and slots directly - instead, add these
        # to the list of connections so that gui callbacks can be cleanly
        # disabled while the gui is being updated.  This allows several gui
        # elements to be interlinked with signal/slots but still get updated
        # as a unit to the new value of the mrml node.
        # self.thresholdPaint.hide()
        self.connections.append((self.maxPixelsSpinBox, 'valueChanged(double)',
                                 self.onMaxPixelsSpinBoxChanged))
        self.connections.append(
            (self.preview, "clicked()", self.onPreviewChanged))

        self.connections.append(
            (self.tissueRadioButton, "clicked()", self.onTissueButtonChanged))
        self.connections.append(
            (self.boneRadioButton, "clicked()", self.onBoneButtonChanged))

        self.connections.append(
            (self.offsetvalueSpinBox, 'valueChanged(double)',
             self.onOffsetValueSpinBoxChanged))
        self.connections.append((self.thresh, "valuesChanged(double,double)",
                                 self.onThreshValuesChange))

        self.connections.append(
            (self.helpBrowser, "clicked()", self.onHelpBrowserPressed))

        # Add vertical spacer
        self.frame.layout().addStretch(1)