Пример #1
0
    def paintPixel(self, x, y):
        """
    paint with a single pixel (in label space)
    """
        sliceLogic = self.sliceWidget.sliceLogic()
        labelLogic = sliceLogic.GetLabelLayer()
        labelNode = labelLogic.GetVolumeNode()
        labelImage = labelNode.GetImageData()

        if not labelNode:
            # if there's no label, we can't paint
            return

        xyToIJK = labelLogic.GetXYToIJKTransform()
        ijkFloat = xyToIJK.TransformDoublePoint((x, y, 0))
        ijk = []
        for e in ijkFloat:
            try:
                index = int(round(e))
            except ValueError:
                return
            ijk.append(index)
        dims = labelImage.GetDimensions()
        for e, d in zip(ijk, dims):  # clamp to volume extent
            if e < 0 or e >= d:
                return

        parameterNode = EditUtil.getParameterNode()
        paintLabel = int(parameterNode.GetParameter("label"))
        labelImage.SetScalarComponentFromFloat(ijk[0], ijk[1], ijk[2], 0,
                                               paintLabel)
        EditUtil.markVolumeNodeAsModified(labelNode)
  def deleteSelectedStructure(self, confirm=True):
    """delete the currently selected structure"""

    merge = self.merge
    if not merge:
      return

    selectionModel = self.structuresView.selectionModel()
    selected = selectionModel.currentIndex().row()

    if selected >= 0:

      structureName = self.structures.item(selected,2).text()
      labelNode = slicer.util.getNode(self.structures.item(selected,3).text())

      if confirm:
        if not slicer.util.confirmOkCancelDisplay("Delete \'%s\' volume?" % structureName, windowTitle='Editor'):
          return

      slicer.mrmlScene.SaveStateForUndo()

      slicer.mrmlScene.RemoveNode( labelNode )
      self.updateStructures()
      if self.structures.rowCount() > 0:
        self.selectStructure((selected-1) if (selected-1 >= 0) else 0)
      else:
        EditUtil.setActiveVolumes(self.master, merge)
        self.edit(0)
Пример #3
0
  def changeLabel(self):
    #
    # change the label values based on the parameter node
    #
    if not self.sliceLogic:
      self.sliceLogic = EditUtil.getSliceLogic()
    parameterNode = EditUtil.getParameterNode()
    parameterNode = EditUtil.getParameterNode()
    inputColor = int(parameterNode.GetParameter("ChangeLabelEffect,inputColor"))
    outputColor = int(parameterNode.GetParameter("ChangeLabelEffect,outputColor"))

    change = slicer.vtkImageLabelChange()
    if vtk.VTK_MAJOR_VERSION <= 5:
      change.SetInput( self.getScopedLabelInput() )
    else:
      change.SetInputData( self.getScopedLabelInput() )
    change.SetOutput( self.getScopedLabelOutput() )
    change.SetInputLabel( inputColor )
    change.SetOutputLabel( outputColor )

    # TODO
    #$this setProgressFilter $change "Change Label"
    change.Update()

    self.applyScopedLabel()
    change.SetOutput( None )
Пример #4
0
    def changeLabel(self):
        #
        # change the label values based on the parameter node
        #
        if not self.sliceLogic:
            self.sliceLogic = EditUtil.getSliceLogic()
        parameterNode = EditUtil.getParameterNode()
        parameterNode = EditUtil.getParameterNode()
        inputColor = int(
            parameterNode.GetParameter("ChangeLabelEffect,inputColor"))
        outputColor = int(
            parameterNode.GetParameter("ChangeLabelEffect,outputColor"))

        change = slicer.vtkImageLabelChange()
        if vtk.VTK_MAJOR_VERSION <= 5:
            change.SetInput(self.getScopedLabelInput())
        else:
            change.SetInputData(self.getScopedLabelInput())
        change.SetOutput(self.getScopedLabelOutput())
        change.SetInputLabel(inputColor)
        change.SetOutputLabel(outputColor)

        # TODO
        #$this setProgressFilter $change "Change Label"
        change.Update()

        self.applyScopedLabel()
        change.SetOutput(None)
Пример #5
0
    def export(self):
        """create a DICOM Segmentation Object from the current labels
    and put it in the slicer dicom database"""

        if not hasattr(slicer.modules, "encodeseg"):
            # TODO: change this message when EncodeSEG is in the trunk
            qt.QMessageBox.critical(
                slicer.util.mainWindow(),
                "DICOM",
                "The Reporting extension must be installed in order to export segmentation objects",
            )
            return

        if not self.master.GetAttribute("DICOM.instanceUIDs"):
            qt.QMessageBox.critical(slicer.util.mainWindow(), "DICOM", "Master volume must have DICOM context")
            return

        rows = self.structures.rowCount()
        if rows == 0:
            self.split()
            rows = self.structures.rowCount()
            if rows == 0:
                logging.info("Cannot export empty segmentation")  # TODO: should you be able to?
                return

        EditUtil.exportAsDICOMSEG(self.master)
        logging.info("Segmentations exported to DICOM Database")
Пример #6
0
    def export(self):
        """create a DICOM Segmentation Object from the current labels
    and put it in the slicer dicom database"""

        if not hasattr(slicer.modules, 'encodeseg'):
            # TODO: change this message when EncodeSEG is in the trunk
            qt.QMessageBox.critical(
                slicer.util.mainWindow(), "DICOM",
                "The Reporting extension must be installed in order to export segmentation objects"
            )
            return

        if not self.master.GetAttribute("DICOM.instanceUIDs"):
            qt.QMessageBox.critical(slicer.util.mainWindow(), "DICOM",
                                    "Master volume must have DICOM context")
            return

        rows = self.structures.rowCount()
        if rows == 0:
            self.split()
            rows = self.structures.rowCount()
            if rows == 0:
                logging.info("Cannot export empty segmentation"
                             )  # TODO: should you be able to?
                return

        EditUtil.exportAsDICOMSEG(self.master)
        logging.info("Segmentations exported to DICOM Database")
Пример #7
0
    def deleteStructures(self, confirm=True):
        """delete all the structures"""

        #
        # iterate through structures and delete them
        #
        merge = self.merge
        if not merge:
            return

        rows = self.structures.rowCount()

        if confirm:
            if not slicer.util.confirmOkCancelDisplay(
                    "Delete %d structure volume(s)?" % rows,
                    windowTitle='Editor'):
                return

        slicer.mrmlScene.SaveStateForUndo()

        volumeNodes = self.structureVolumes()
        for volumeNode in volumeNodes:
            slicer.mrmlScene.RemoveNode(volumeNode)
        self.updateStructures()
        EditUtil.setActiveVolumes(self.master, merge)
        self.edit(0)
Пример #8
0
    def deleteSelectedStructure(self, confirm=True):
        """delete the currently selected structure"""

        merge = self.merge
        if not merge:
            return

        selectionModel = self.structuresView.selectionModel()
        selected = selectionModel.currentIndex().row()

        if selected >= 0:

            structureName = self.structures.item(selected, 2).text()
            labelNode = slicer.util.getNode(
                self.structures.item(selected, 3).text())

            if confirm:
                if not slicer.util.confirmOkCancelDisplay(
                        "Delete \'%s\' volume?" % structureName,
                        windowTitle='Editor'):
                    return

            slicer.mrmlScene.SaveStateForUndo()

            slicer.mrmlScene.RemoveNode(labelNode)
            self.updateStructures()
            if self.structures.rowCount() > 0:
                self.selectStructure((selected -
                                      1) if (selected - 1 >= 0) else 0)
            else:
                EditUtil.setActiveVolumes(self.master, merge)
                self.edit(0)
Пример #9
0
  def paintPixel(self, x, y):
    """
    paint with a single pixel (in label space)
    """
    sliceLogic = self.sliceWidget.sliceLogic()
    labelLogic = sliceLogic.GetLabelLayer()
    labelNode = labelLogic.GetVolumeNode()
    labelImage = labelNode.GetImageData()

    if not labelNode:
      # if there's no label, we can't paint
      return

    xyToIJK = labelLogic.GetXYToIJKTransform()
    ijkFloat = xyToIJK.TransformDoublePoint( (x, y, 0) )
    ijk = []
    for e in ijkFloat:
      try:
        index = int(round(e))
      except ValueError:
        return
      ijk.append(index)
    dims = labelImage.GetDimensions()
    for e,d in zip(ijk,dims): # clamp to volume extent
      if e < 0 or e >= d:
        return

    parameterNode = EditUtil.getParameterNode()
    paintLabel = int(parameterNode.GetParameter("label"))
    labelImage.SetScalarComponentFromFloat(ijk[0],ijk[1],ijk[2],0, paintLabel)
    EditUtil.markVolumeNodeAsModified(labelNode)
Пример #10
0
 def _onParameterNodeModified(self, caller, event=-1):
     self._onEffectChanged(caller.GetParameter("effect"))
     EditUtil.setEraseEffectEnabled(EditUtil.isEraseEffectEnabled())
     self.actions["EraseLabel"].checked = EditUtil.isEraseEffectEnabled()
     effectName = EditUtil.getCurrentEffect()
     if effectName not in self.actions:
         print('Warning: effect %s not a valid action' % effectName)
         return
     self.actions[effectName].checked = True
Пример #11
0
 def _onParameterNodeModified(self, caller, event=-1):
   self._onEffectChanged(caller.GetParameter("effect"))
   EditUtil.setEraseEffectEnabled(EditUtil.isEraseEffectEnabled())
   self.actions["EraseLabel"].checked = EditUtil.isEraseEffectEnabled()
   effectName = EditUtil.getCurrentEffect()
   if effectName not in self.actions:
     print('Warning: effect %s not a valid action' % effectName)
     return
   self.actions[effectName].checked = True
Пример #12
0
    def split(self):
        """split the merge volume into individual structures"""

        self.statusText("Splitting...")
        if self.merge:
            EditUtil.splitPerStructureVolumes(self.master, self.merge)
            self.updateStructures()
        else:
            logging.info("No merged label map, cannot split")
        self.statusText("Finished splitting.")
Пример #13
0
  def split(self):
    """split the merge volume into individual structures"""

    self.statusText( "Splitting..." )
    if self.merge:
      EditUtil.splitPerStructureVolumes(self.master, self.merge)
      self.updateStructures()
    else:
      logging.info("No merged label map, cannot split")
    self.statusText( "Finished splitting." )
Пример #14
0
    def edit(self, label):
        """select the picked label for editing"""

        merge = self.merge
        if not merge:
            return
        colorNode = merge.GetDisplayNode().GetColorNode()

        structureName = colorNode.GetColorName(label)
        structureVolume = self.structureVolume(structureName)

        EditUtil.setActiveVolumes(self.master, structureVolume)
        EditUtil.setLabel(label)
Пример #15
0
  def edit(self,label):
    """select the picked label for editing"""

    merge = self.merge
    if not merge:
      return
    colorNode = merge.GetDisplayNode().GetColorNode()

    structureName = colorNode.GetColorName( label )
    structureVolume = self.structureVolume( structureName )

    EditUtil.setActiveVolumes(self.master, structureVolume)
    EditUtil.setLabel(label)
Пример #16
0
    def split(self):
        """split the merge volume into individual structures"""

        self.statusText("Splitting...")
        merge = self.merge
        if not merge:
            return
        colorNode = merge.GetDisplayNode().GetColorNode()

        accum = vtk.vtkImageAccumulate()
        if vtk.VTK_MAJOR_VERSION <= 5:
            accum.SetInput(merge.GetImageData())
        else:
            accum.SetInputConnection(merge.GetImageDataConnection())
        accum.Update()
        lo = int(accum.GetMin()[0])
        hi = int(accum.GetMax()[0])

        # TODO: pending resolution of bug 1822, run the thresholding
        # in single threaded mode to avoid data corruption observed on mac release
        # builds
        thresholder = vtk.vtkImageThreshold()
        thresholder.SetNumberOfThreads(1)
        for i in xrange(lo, hi + 1):
            self.statusText("Splitting label %d..." % i)
            if vtk.VTK_MAJOR_VERSION <= 5:
                thresholder.SetInput(merge.GetImageData())
            else:
                thresholder.SetInputConnection(merge.GetImageDataConnection())
            thresholder.SetInValue(i)
            thresholder.SetOutValue(0)
            thresholder.ReplaceInOn()
            thresholder.ReplaceOutOn()
            thresholder.ThresholdBetween(i, i)
            thresholder.SetOutputScalarType(
                merge.GetImageData().GetScalarType())
            thresholder.Update()
            if thresholder.GetOutput().GetScalarRange() != (0.0, 0.0):
                labelName = colorNode.GetColorName(i)
                self.statusText("Creating structure volume %s..." % labelName)
                structureVolume = self.structureVolume(labelName)
                if not structureVolume:
                    self.addStructure(i, "noEdit")
                structureVolume = self.structureVolume(labelName)
                structureVolume.GetImageData().DeepCopy(
                    thresholder.GetOutput())
                EditUtil.markVolumeNodeAsModified(structureVolume)

        self.statusText("Finished splitting.")
Пример #17
0
 def updateParameterNode(self, caller, event):
   node = EditUtil.getParameterNode()
   if node != self.parameterNode:
     if self.parameterNode:
       node.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = node
     self.parameterNodeTag = node.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
Пример #18
0
  def __init__(self, sliceWidget):
    super(PaintEffectTool,self).__init__(sliceWidget)
    # create a logic instance to do the non-gui work
    self.logic = PaintEffectLogic(self.sliceWidget.sliceLogic())

    # configuration variables
    self.delayedPaint = True
    self.parameterNode = EditUtil.getParameterNode()
    self.sphere = not (0 == int(self.parameterNode.GetParameter("PaintEffect,sphere")))
    self.smudge = not (0 == int(self.parameterNode.GetParameter("PaintEffect,smudge")))
    self.pixelMode = not (0 == int(self.parameterNode.GetParameter("PaintEffect,pixelMode")))
    self.radius = float(self.parameterNode.GetParameter("PaintEffect,radius"))

    # interaction state variables
    self.position = [0, 0, 0]
    self.paintCoordinates = []
    self.feedbackActors = []
    self.lastRadius = 0

    # scratch variables
    self.rasToXY = vtk.vtkMatrix4x4()

    # initialization
    self.brush = vtk.vtkPolyData()
    self.createGlyph(self.brush)
    self.mapper = vtk.vtkPolyDataMapper2D()
    self.actor = vtk.vtkActor2D()
    self.mapper.SetInputData(self.brush)
    self.actor.SetMapper(self.mapper)
    self.actor.VisibilityOff()

    self.renderer.AddActor2D(self.actor)
    self.actors.append(self.actor)

    self.processEvent()
  def onApply(self):
    logic = WatershedFromMarkerEffectLogic( EditUtil.getSliceLogic() )
    logic.undoRedo = self.undoRedo

    logic.sigma = float( self.sigmaSpinBox.value )

    logic.doit()
Пример #20
0
    def create(self):

        self.findEffects()

        self.mainFrame = qt.QFrame(self.parent)
        self.mainFrame.objectName = 'MainFrame'
        vbox = qt.QVBoxLayout()
        self.mainFrame.setLayout(vbox)
        self.parent.layout().addWidget(self.mainFrame)

        #
        # the buttons
        #
        self.rowFrames = []
        self.actions = {}
        self.buttons = {}
        self.icons = {}
        self.callbacks = {}

        # create all of the buttons
        # createButtonRow() ensures that only effects in self.effects are exposed,
        self.createButtonRow(
            ("DefaultTool", "EraseLabel", "PaintEffect", "DrawEffect",
             "WandEffect", "LevelTracingEffect", "RectangleEffect",
             "IdentifyIslandsEffect", "ChangeIslandEffect",
             "RemoveIslandsEffect", "SaveIslandEffect"))
        self.createButtonRow(
            ("ErodeEffect", "DilateEffect", "GrowCutEffect",
             "WatershedFromMarkerEffect", "ThresholdEffect",
             "ChangeLabelEffect", "MakeModelEffect", "FastMarchingEffect"))

        extensions = []
        for k in slicer.modules.editorExtensions:
            extensions.append(k)
        self.createButtonRow(extensions)

        self.createButtonRow(("PreviousCheckPoint", "NextCheckPoint"),
                             rowLabel="Undo/Redo: ")

        #
        # the labels
        #
        self.toolsActiveToolFrame = qt.QFrame(self.parent)
        self.toolsActiveToolFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(self.toolsActiveToolFrame)
        self.toolsActiveTool = qt.QLabel(self.toolsActiveToolFrame)
        self.toolsActiveTool.setText('Active Tool:')
        self.toolsActiveTool.setStyleSheet(
            "background-color: rgb(232,230,235)")
        self.toolsActiveToolFrame.layout().addWidget(self.toolsActiveTool)
        self.toolsActiveToolName = qt.QLabel(self.toolsActiveToolFrame)
        self.toolsActiveToolName.setText('')
        self.toolsActiveToolName.setStyleSheet(
            "background-color: rgb(232,230,235)")
        self.toolsActiveToolFrame.layout().addWidget(self.toolsActiveToolName)

        vbox.addStretch(1)

        self.updateUndoRedoButtons()
        self._onParameterNodeModified(EditUtil.getParameterNode())
Пример #21
0
    def __init__(self, parent=None):
        VTKObservationMixin.__init__(self)

        self.editUtil = EditUtil()  # Kept for backward compatibility

        # mrml volume node instances
        self.master = None
        self.masterWhenMergeWasSet = None
        # Editor color LUT
        self.colorNodeID = None
        # string
        self.createMergeOptions = ""
        self.mergeVolumePostfix = "-label"
        # slicer helper class
        self.volumesLogic = slicer.modules.volumes.logic()
        # widgets that are dynamically created on demand
        # pseudo signals
        # - python callable that gets True or False
        self.selectCommand = None

        if not parent:
            self.parent = slicer.qMRMLWidget()
            self.parent.setLayout(qt.QVBoxLayout())
            self.parent.setMRMLScene(slicer.mrmlScene)
            self.create()
            self.parent.show()
        else:
            self.parent = parent
            self.create()
Пример #22
0
  def updateGUIFromMRML(self,caller,event):
    if self.parameterNode.GetParameter(self.parameter) == '':
      # parameter does not exist - probably initializing
      return
    label = int(self.parameterNode.GetParameter(self.parameter))

    self.colorNode = EditUtil.getColorNode()
    if self.colorNode:
      self.frame.setDisabled(0)
      self.labelName.setText( self.colorNode.GetColorName( label ) )
      lut = self.colorNode.GetLookupTable()
      rgb = lut.GetTableValue( label )
      self.colorPatch.setStyleSheet(
          "background-color: rgb(%s,%s,%s)" % (rgb[0]*255, rgb[1]*255, rgb[2]*255) )
      self.colorSpin.setMaximum( self.colorNode.GetNumberOfColors()-1 )
    else:
      self.frame.setDisabled(1)

    try:
      self.colorSpin.setValue(label)

    except ValueError:
      # TODO: why does the python class still exist if the widget is destroyed?
      # - this only happens when reloading the module.  The owner of the
      # instance is gone and the widgets are gone, but this instance still
      # has observer on the parameter node - this indicates memory leaks
      # that need to be fixed
      self.cleanup()
      return
Пример #23
0
  def showColorBox(self):
    self.colorNode = EditUtil.getColorNode()

    if not self.colorBox:
      self.colorBox = ColorBox.ColorBox(parameterNode=self.parameterNode, parameter=self.parameter, colorNode=self.colorNode)

    self.colorBox.show(parameterNode=self.parameterNode, parameter=self.parameter, colorNode=self.colorNode)
Пример #24
0
    def updateGUIFromMRML(self, caller, event):
        if self.parameterNode.GetParameter(self.parameter) == '':
            # parameter does not exist - probably intializing
            return
        label = int(self.parameterNode.GetParameter(self.parameter))

        self.colorNode = EditUtil.getColorNode()
        if self.colorNode:
            self.frame.setDisabled(0)
            self.labelName.setText(self.colorNode.GetColorName(label))
            lut = self.colorNode.GetLookupTable()
            rgb = lut.GetTableValue(label)
            self.colorPatch.setStyleSheet(
                "background-color: rgb(%s,%s,%s)" %
                (rgb[0] * 255, rgb[1] * 255, rgb[2] * 255))
            self.colorSpin.setMaximum(self.colorNode.GetNumberOfColors() - 1)
        else:
            self.frame.setDisabled(1)

        try:
            self.colorSpin.setValue(label)

        except ValueError:
            # TODO: why does the python class still exist if the widget is destroyed?
            # - this only happens when reloading the module.  The owner of the
            # instance is gone and the widgets are gone, but this instance still
            # has observer on the parameter node - this indicates memory leaks
            # that need to be fixed
            self.cleanup()
            return
Пример #25
0
    def onApply(self):
        logic = WatershedFromMarkerEffectLogic(EditUtil.getSliceLogic())
        logic.undoRedo = self.undoRedo

        logic.sigma = float(self.sigmaSpinBox.value)

        logic.doit()
Пример #26
0
  def showColorBox(self):
    self.colorNode = EditUtil.getColorNode()

    if not self.colorBox:
      self.colorBox = ColorBox.ColorBox(parameterNode=self.parameterNode, parameter=self.parameter, colorNode=self.colorNode)

    self.colorBox.show(parameterNode=self.parameterNode, parameter=self.parameter, colorNode=self.colorNode)
Пример #27
0
  def create(self):
    self.frame = qt.QFrame(self.parent)
    self.frame.objectName = 'EditColorFrame'
    self.frame.setLayout(qt.QHBoxLayout())
    self.parent.layout().addWidget(self.frame)

    self.label = qt.QLabel(self.frame)
    self.label.setText("Label: ")
    self.frame.layout().addWidget(self.label)

    self.labelName = qt.QLabel(self.frame)
    self.labelName.setText("")
    self.frame.layout().addWidget(self.labelName)

    self.colorSpin = qt.QSpinBox(self.frame)
    self.colorSpin.objectName = 'ColorSpinBox'
    self.colorSpin.setMaximum( 64000)
    self.colorSpin.setValue( EditUtil.getLabel() )
    self.colorSpin.setToolTip( "Click colored patch at right to bring up color selection pop up window.  Use the 'c' key to bring up color popup menu." )
    self.frame.layout().addWidget(self.colorSpin)

    self.colorPatch = qt.QPushButton(self.frame)
    self.colorPatch.setObjectName('ColorPatchButton')
    self.frame.layout().addWidget(self.colorPatch)

    self.updateParameterNode(slicer.mrmlScene, vtk.vtkCommand.ModifiedEvent)
    self.updateGUIFromMRML(self.parameterNode, vtk.vtkCommand.ModifiedEvent)

    self.frame.connect( 'destroyed()', self.cleanup)
    self.colorSpin.connect( 'valueChanged(int)', self.updateMRMLFromGUI)
    self.colorPatch.connect( 'clicked()', self.showColorBox )

    # TODO: change this to look for specfic events (added, removed...)
    # but this requires being able to access events by number from wrapped code
    self.addObserver(slicer.mrmlScene, vtk.vtkCommand.ModifiedEvent, self.updateParameterNode)
Пример #28
0
 def updateParameterNode(self, caller, event):
   node = EditUtil.getParameterNode()
   if node != self.parameterNode:
     if self.parameterNode:
       node.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = node
     self.parameterNodeTag = node.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
Пример #29
0
    def __init__(self, parent=None):
        VTKObservationMixin.__init__(self)
        self.parent = parent
        self.updatingGUI = False
        self.widgets = []
        self.parameterNode = None
        self.parameterNodeTag = None
        self.editUtil = EditUtil()  # Kept for backward compatibility
        self.tools = []

        # connections is a list of widget/signal/slot tripples
        # for the options gui that can be connected/disconnected
        # as needed to prevent triggering mrml updates while
        # updating the state of the gui
        # - each level of the inheritance tree can add entries
        #   to this list for use by the connectWidgets
        #   and disconnectWidgets methods
        self.connections = []
        self.connectionsConnected = False

        # 1) find the parameter node in the scene and observe it
        # 2) set the defaults (will only set them if they are not
        # already set)
        self.updateParameterNode(self.parameterNode,
                                 vtk.vtkCommand.ModifiedEvent)

        # TODO: change this to look for specfic events (added, removed...)
        # but this requires being able to access events by number from wrapped code
        self.addObserver(slicer.mrmlScene, vtk.vtkCommand.ModifiedEvent,
                         self.updateParameterNode)
  def split(self):
    """split the merge volume into individual structures"""

    self.statusText( "Splitting..." )
    merge = self.merge
    if not merge:
      return
    colorNode = merge.GetDisplayNode().GetColorNode()

    accum = vtk.vtkImageAccumulate()
    if vtk.VTK_MAJOR_VERSION <= 5:
      accum.SetInput(merge.GetImageData())
    else:
      accum.SetInputConnection(merge.GetImageDataConnection())
    accum.Update()
    lo = int(accum.GetMin()[0])
    hi = int(accum.GetMax()[0])

    # TODO: pending resolution of bug 1822, run the thresholding
    # in single threaded mode to avoid data corruption observed on mac release
    # builds
    thresholder = vtk.vtkImageThreshold()
    thresholder.SetNumberOfThreads(1)
    for i in xrange(lo,hi+1):
      self.statusText( "Splitting label %d..."%i )
      if vtk.VTK_MAJOR_VERSION <= 5:
        thresholder.SetInput( merge.GetImageData() )
      else:
        thresholder.SetInputConnection( merge.GetImageDataConnection() )
      thresholder.SetInValue( i )
      thresholder.SetOutValue( 0 )
      thresholder.ReplaceInOn()
      thresholder.ReplaceOutOn()
      thresholder.ThresholdBetween( i, i )
      thresholder.SetOutputScalarType( merge.GetImageData().GetScalarType() )
      thresholder.Update()
      if thresholder.GetOutput().GetScalarRange() != (0.0, 0.0):
        labelName = colorNode.GetColorName(i)
        self.statusText( "Creating structure volume %s..."%labelName )
        structureVolume = self.structureVolume( labelName )
        if not structureVolume:
          self.addStructure( i, "noEdit" )
        structureVolume = self.structureVolume( labelName )
        structureVolume.GetImageData().DeepCopy( thresholder.GetOutput() )
        EditUtil.markVolumeNodeAsModified(structureVolume)

    self.statusText( "Finished splitting." )
Пример #31
0
  def processEvent(self, caller=None, event=None):
    """
    handle events from the render window interactor
    """

    if super(PaintEffectTool,self).processEvent(caller,event):
      return

    # interactor events
    if event == "LeftButtonPressEvent":
      self.actionState = "painting"
      if not self.pixelMode:
        self.cursorOff()
      xy = self.interactor.GetEventPosition()
      if self.smudge:
        EditUtil.setLabel(self.getLabelPixel(xy))
      self.paintAddPoint(xy[0], xy[1])
      self.abortEvent(event)
    elif event == "LeftButtonReleaseEvent":
      self.paintApply()
      self.actionState = None
      self.cursorOn()
    elif event == "MouseMoveEvent":
      self.actor.VisibilityOn()
      if self.actionState == "painting":
        xy = self.interactor.GetEventPosition()
        self.paintAddPoint(xy[0], xy[1])
        self.abortEvent(event)
    elif event == "EnterEvent":
      self.actor.VisibilityOn()
    elif event == "LeaveEvent":
      self.actor.VisibilityOff()
    elif event == "KeyPressEvent":
      key = self.interactor.GetKeySym()
      if key == 'plus' or key == 'equal':
        self.scaleRadius(1.2)
      if key == 'minus' or key == 'underscore':
        self.scaleRadius(0.8)
    else:
      pass

    # events from the slice node
    if caller and caller.IsA('vtkMRMLSliceNode'):
      if hasattr(self,'brush'):
        self.createGlyph(self.brush)

    self.positionActors()
Пример #32
0
    def processEvent(self, caller=None, event=None):
        """
    handle events from the render window interactor
    """

        if super(PaintEffectTool, self).processEvent(caller, event):
            return

        # interactor events
        if event == "LeftButtonPressEvent":
            self.actionState = "painting"
            if not self.pixelMode:
                self.cursorOff()
            xy = self.interactor.GetEventPosition()
            if self.smudge:
                EditUtil.setLabel(self.getLabelPixel(xy))
            self.paintAddPoint(xy[0], xy[1])
            self.abortEvent(event)
        elif event == "LeftButtonReleaseEvent":
            self.paintApply()
            self.actionState = None
            self.cursorOn()
        elif event == "MouseMoveEvent":
            self.actor.VisibilityOn()
            if self.actionState == "painting":
                xy = self.interactor.GetEventPosition()
                self.paintAddPoint(xy[0], xy[1])
                self.abortEvent(event)
        elif event == "EnterEvent":
            self.actor.VisibilityOn()
        elif event == "LeaveEvent":
            self.actor.VisibilityOff()
        elif event == "KeyPressEvent":
            key = self.interactor.GetKeySym()
            if key == 'plus' or key == 'equal':
                self.scaleRadius(1.2)
            if key == 'minus' or key == 'underscore':
                self.scaleRadius(0.8)
        else:
            pass

        # events from the slice node
        if caller and caller.IsA('vtkMRMLSliceNode'):
            if hasattr(self, 'brush'):
                self.createGlyph(self.brush)

        self.positionActors()
Пример #33
0
    def addStructure(self, label=None, options=""):
        """create the segmentation helper box"""

        merge = self.merge
        if not merge:
            return

        if not label:
            # if no label given, prompt the user.  The selectCommand of the colorBox will
            # then re-invoke this method with the label value set and we will continue
            label = self.promptStructure()
            return

        EditUtil.addStructure(self.master, self.merge, label)
        self.updateStructures()

        if options.find("noEdit") < 0:
            self.selectStructure(self.structures.rowCount() - 1)
Пример #34
0
    def create(self):
        super(MakeModelEffectOptions, self).create()

        self.goToModelMaker = qt.QPushButton("Go To Model Maker", self.frame)
        self.goToModelMaker.setToolTip(
            "The Model Maker interface contains a whole range of options for building sets of models and controlling the parameters."
        )
        self.frame.layout().addWidget(self.goToModelMaker)
        self.widgets.append(self.goToModelMaker)

        self.smooth = qt.QCheckBox("Smooth Model", self.frame)
        self.smooth.checked = True
        self.smooth.setToolTip(
            "When smoothed, the model will look better, but some details of the label map will not be visible on the model.  When not smoothed you will see individual voxel boundaries in the model.  Smoothing here corresponds to Decimation of 0.25 and Smooting iterations of 10."
        )
        self.frame.layout().addWidget(self.smooth)
        self.widgets.append(self.smooth)

        #
        # model name
        #
        self.nameFrame = qt.QFrame(self.frame)
        self.nameFrame.setLayout(qt.QHBoxLayout())
        self.frame.layout().addWidget(self.nameFrame)
        self.widgets.append(self.nameFrame)

        self.modelNameLabel = qt.QLabel("Model Name: ", self.nameFrame)
        self.modelNameLabel.setToolTip(
            "Select the name for the newly created model.")
        self.nameFrame.layout().addWidget(self.modelNameLabel)
        self.widgets.append(self.modelNameLabel)

        self.modelName = qt.QLineEdit(self.nameFrame)
        self.modelName.setText(self.getUniqueModelName(
            EditUtil.getLabelName()))
        self.nameFrame.layout().addWidget(self.modelName)
        self.widgets.append(self.modelName)

        self.apply = qt.QPushButton("Apply", self.frame)
        self.apply.objectName = self.__class__.__name__ + 'Apply'
        self.apply.setToolTip(
            "Build a model for the current label value of the label map being edited in the Red slice window.  Model will be created in the background."
        )
        self.frame.layout().addWidget(self.apply)
        self.widgets.append(self.apply)

        HelpButton(
            self.frame,
            "Use this tool build a model.  A subset of model building options is provided here.  Go to the Model Maker module to expose a range of parameters.  Use Merge and Build button in the Advanced... tab to quickly make a model of all defined structures in the merge label map."
        )

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

        self.connections.append((self.apply, 'clicked()', self.onApply))
        self.connections.append(
            (self.goToModelMaker, 'clicked()', self.onGoToModelMaker))
Пример #35
0
  def addStructure(self,label=None, options=""):
    """create the segmentation helper box"""

    merge = self.merge
    if not merge:
      return

    if not label:
      # if no label given, prompt the user.  The selectCommand of the colorBox will
      # then re-invoke this method with the label value set and we will continue
      label = self.promptStructure()
      return

    EditUtil.addStructure(self.master, self.merge, label)
    self.updateStructures()

    if options.find("noEdit") < 0:
      self.selectStructure(self.structures.rowCount()-1)
Пример #36
0
    def select(self, masterVolume=None, mergeVolume=None):
        """select master volume - load merge volume if one with the correct name exists"""

        if masterVolume == None:
            masterVolume = self.masterSelector.currentNode()
        self.master = masterVolume

        self.masterSelector.blockSignals(True)
        self.masterSelector.setCurrentNode(self.master)
        self.masterSelector.blockSignals(False)

        self.mergeSelector.setCurrentNode(mergeVolume)

        if self.master and not self.mergeVolume():
            # the master exists, but there is no merge volume yet
            # bring up dialog to create a merge with a user-selected color node
            self.labelCreateDialog()

        merge = self.mergeVolume()
        if merge:
            if not merge.IsA("vtkMRMLLabelMapVolumeNode"):
                slicer.util.errorDisplay(
                    "Error: selected merge label volume is not a label volume")
            else:
                EditUtil.setActiveVolumes(self.master, merge)
                self.mergeSelector.setCurrentNode(merge)

        self.structureListWidget.master = self.master
        self.structureListWidget.merge = merge
        self.structureListWidget.updateStructures()

        if self.master and merge:
            warnings = self.volumesLogic.CheckForLabelVolumeValidity(
                self.master, merge)
            if warnings != "":
                warnings = "Geometry of master and merge volumes do not match.\n\n" + warnings
                slicer.util.errorDisplay("Warning: %s" % warnings)

        # trigger a modified event on the parameter node so that other parts of the GUI
        # (such as the EditColor) will know to update and enable themselves
        EditUtil.getParameterNode().Modified()

        if self.selectCommand:
            self.selectCommand()
Пример #37
0
 def updateParameterNode(self, caller, event):
   #
   # observe the scene to know when to get the parameter node
   #
   parameterNode = EditUtil.getParameterNode()
   if parameterNode != self.parameterNode:
     if self.parameterNode:
       self.parameterNode.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = parameterNode
     self.parameterNodeTag = self.parameterNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
Пример #38
0
    def percentMaxChanged(self, val):
        labelNode = self.logic.getLabelNode()
        labelImage = EditUtil.getLabelImage()
        spacing = labelNode.GetSpacing()
        dim = labelImage.GetDimensions()
        print dim
        totalVolume = spacing[0] * dim[0] + spacing[1] * dim[1] + spacing[2] * dim[2]

        percentVolumeStr = "%.5f" % (totalVolume * val / 100.0)
        self.percentVolume.text = "(maximum total volume: " + percentVolumeStr + " mL)"
Пример #39
0
  def percentMaxChanged(self, val):
    labelNode = self.logic.getLabelNode()
    labelImage = EditUtil.getLabelImage()
    spacing = labelNode.GetSpacing()
    dim = labelImage.GetDimensions()
    print dim
    totalVolume = spacing[0]*dim[0]+spacing[1]*dim[1]+spacing[2]*dim[2]

    percentVolumeStr = "%.5f" % (totalVolume*val/100.)
    self.percentVolume.text = '(maximum total volume: '+percentVolumeStr+' mL)'
Пример #40
0
 def updateParameterNode(self, caller, event):
   #
   # observe the scene to know when to get the parameter node
   #
   parameterNode = EditUtil.getParameterNode()
   if parameterNode != self.parameterNode:
     if self.parameterNode:
       self.parameterNode.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = parameterNode
     self.parameterNodeTag = self.parameterNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
Пример #41
0
  def select(self, masterVolume=None, mergeVolume=None):
    """select master volume - load merge volume if one with the correct name exists"""

    if masterVolume is None:
        masterVolume = self.masterSelector.currentNode()
    self.master = masterVolume

    self.masterSelector.blockSignals(True)
    self.masterSelector.setCurrentNode(self.master)
    self.masterSelector.blockSignals(False)

    self.mergeSelector.setCurrentNode(mergeVolume)

    if self.master and not self.mergeVolume():
      # the master exists, but there is no merge volume yet
      # bring up dialog to create a merge with a user-selected color node
      self.labelCreateDialog()

    merge = self.mergeVolume()
    if merge:
      if not merge.IsA("vtkMRMLLabelMapVolumeNode"):
        slicer.util.errorDisplay( "Error: selected merge label volume is not a label volume" )
      else:
        EditUtil.setActiveVolumes(self.master, merge)
        self.mergeSelector.setCurrentNode(merge)

    self.structureListWidget.master = self.master
    self.structureListWidget.merge = merge
    self.structureListWidget.updateStructures()

    if self.master and merge:
      warnings = self.volumesLogic.CheckForLabelVolumeValidity(self.master,merge)
      if warnings != "":
        warnings = "Geometry of master and merge volumes do not match.\n\n" + warnings
        slicer.util.errorDisplay( "Warning: %s" % warnings )

    # trigger a modified event on the parameter node so that other parts of the GUI
    # (such as the EditColor) will know to update and enable themselves
    EditUtil.getParameterNode().Modified()

    if self.selectCommand:
      self.selectCommand()
Пример #42
0
 def getBackgroundScalarRange(self):
     success = False
     lo = -1
     hi = -1
     backgroundVolume = EditUtil.getBackgroundVolume()
     if backgroundVolume:
         backgroundImage = backgroundVolume.GetImageData()
         if backgroundImage:
             lo, hi = backgroundImage.GetScalarRange()
             success = True
     return success, lo, hi
Пример #43
0
  def __init__(self, parent=0):
    super(FastMarchingEffectOptions,self).__init__(parent)

    # self.attributes should be tuple of options:
    # 'MouseTool' - grabs the cursor
    # 'Nonmodal' - can be applied while another is active
    # 'Disabled' - not available
    # self.attributes = ('MouseTool')
    self.displayName = 'FastMarchingEffect Effect'

    self.logic = FastMarchingEffectLogic(EditUtil.getSliceLogic())
Пример #44
0
 def getBackgroundScalarRange(self):
   success = False
   lo = -1
   hi = -1
   backgroundVolume = EditUtil.getBackgroundVolume()
   if backgroundVolume:
     backgroundImage = backgroundVolume.GetImageData()
     if backgroundImage:
       lo, hi = backgroundImage.GetScalarRange()
       success = True
   return success, lo, hi
Пример #45
0
    def __init__(self, parent=0):
        super(FastMarchingEffectOptions, self).__init__(parent)

        # self.attributes should be tuple of options:
        # 'MouseTool' - grabs the cursor
        # 'Nonmodal' - can be applied while another is active
        # 'Disabled' - not available
        # self.attributes = ('MouseTool')
        self.displayName = 'FastMarchingEffect Effect'

        self.logic = FastMarchingEffectLogic(EditUtil.getSliceLogic())
Пример #46
0
  def updateGUIFromMRML(self,caller,event):
    if self.parameterNode.GetParameter(self.parameter) == '':
      # parameter does not exist - probably intializing
      return
    label = int(self.parameterNode.GetParameter(self.parameter))

    self.colorNode = EditUtil.getColorNode()
    if self.colorNode:
      self.frame.setDisabled(0)
      self.labelName.setText( self.colorNode.GetColorName( label ) )
      lut = self.colorNode.GetLookupTable()
      rgb = lut.GetTableValue( label )
      self.colorPatch.setStyleSheet(
          "background-color: rgb(%s,%s,%s)" % (rgb[0]*255, rgb[1]*255, rgb[2]*255) )
      self.colorSpin.setMaximum( self.colorNode.GetNumberOfColors()-1 )
    else:
      self.frame.setDisabled(1)

    try:
      self.colorSpin.setValue(label)
      # check to see if there's an associated terminology with this color node
      if self.colorNode:
        terminologyName = self.colorNode.GetAttribute("TerminologyName")
        if terminologyName:
          colorLogic = slicer.modules.colors.logic()
          if colorLogic:
            # enable the terminology widgets
            self.hideTerminology(0)
            region = colorLogic.GetAnatomicRegionCodeMeaning(label, terminologyName)
            regionModifier = colorLogic.GetAnatomicRegionModifierCodeMeaning(label, terminologyName)
            category = colorLogic.GetSegmentedPropertyCategoryCodeMeaning(label, terminologyName)
            categoryType = colorLogic.GetSegmentedPropertyTypeCodeMeaning(label, terminologyName)
            categoryModifier = colorLogic.GetSegmentedPropertyTypeModifierCodeMeaning(label, terminologyName)
            self.terminologyRegion.setText(region)
            self.terminologyRegionModifier.setText(regionModifier)
            self.terminologyCategory.setText(category)
            self.terminologyCategoryType.setText(categoryType)
            self.terminologyCategoryModifier.setText(categoryModifier)
            # if no region information, hide the region panel
            if region is "" and regionModifier is "":
              self.terminologyRegionFrame.setHidden(1)
            else:
              self.terminologyRegionFrame.setHidden(0)
        else:
          self.hideTerminology(1)

    except ValueError:
      # TODO: why does the python class still exist if the widget is destroyed?
      # - this only happens when reloading the module.  The owner of the
      # instance is gone and the widgets are gone, but this instance still
      # has observer on the parameter node - this indicates memory leaks
      # that need to be fixed
      self.cleanup()
      return
Пример #47
0
  def paintApply(self):
    if self.paintCoordinates != []:
      if self.undoRedo:
        self.undoRedo.saveState()

    for xy in self.paintCoordinates:
      if self.pixelMode:
        self.paintPixel(xy[0], xy[1])
      else:
        self.paintBrush(xy[0], xy[1])
    self.paintCoordinates = []
    self.paintFeedback()

    # TODO: workaround for new pipeline in slicer4
    # - editing image data of the calling modified on the node
    #   does not pull the pipeline chain
    # - so we trick it by changing the image data first
    sliceLogic = self.sliceWidget.sliceLogic()
    labelLogic = sliceLogic.GetLabelLayer()
    labelNode = labelLogic.GetVolumeNode()
    EditUtil.markVolumeNodeAsModified(labelNode)
Пример #48
0
 def updateParameterNode(self, caller, event):
   """
   note: this method needs to be implemented exactly as
   defined in the leaf classes in EditOptions.py
   in each leaf subclass so that "self" in the observer
   is of the correct type """
   node = EditUtil.getParameterNode()
   if node != self.parameterNode:
     if self.parameterNode:
       node.RemoveObserver(self.parameterNodeTag)
     self.parameterNode = node
     self.parameterNodeTag = node.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
Пример #49
0
    def paintApply(self):
        if self.paintCoordinates != []:
            if self.undoRedo:
                self.undoRedo.saveState()

        for xy in self.paintCoordinates:
            if self.pixelMode:
                self.paintPixel(xy[0], xy[1])
            else:
                self.paintBrush(xy[0], xy[1])
        self.paintCoordinates = []
        self.paintFeedback()

        # TODO: workaround for new pipeline in slicer4
        # - editing image data of the calling modified on the node
        #   does not pull the pipeline chain
        # - so we trick it by changing the image data first
        sliceLogic = self.sliceWidget.sliceLogic()
        labelLogic = sliceLogic.GetLabelLayer()
        labelNode = labelLogic.GetVolumeNode()
        EditUtil.markVolumeNodeAsModified(labelNode)
Пример #50
0
 def updateParameterNode(self, caller, event):
     """
 note: this method needs to be implemented exactly as
 defined in the leaf classes in EditOptions.py
 in each leaf subclass so that "self" in the observer
 is of the correct type """
     node = EditUtil.getParameterNode()
     if node != self.parameterNode:
         if self.parameterNode:
             node.RemoveObserver(self.parameterNodeTag)
         self.parameterNode = node
         self.parameterNodeTag = node.AddObserver(
             vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)
Пример #51
0
  def create(self):

    self.findEffects()

    self.mainFrame = qt.QFrame(self.parent)
    self.mainFrame.objectName = 'MainFrame'
    vbox = qt.QVBoxLayout()
    self.mainFrame.setLayout(vbox)
    self.parent.layout().addWidget(self.mainFrame)

    #
    # the buttons
    #
    self.rowFrames = []
    self.actions = {}
    self.buttons = {}
    self.icons = {}
    self.callbacks = {}

    # create all of the buttons
    # createButtonRow() ensures that only effects in self.effects are exposed,
    self.createButtonRow( ("DefaultTool", "EraseLabel", "PaintEffect", "DrawEffect", "WandEffect", "LevelTracingEffect", "RectangleEffect", "IdentifyIslandsEffect", "ChangeIslandEffect", "RemoveIslandsEffect", "SaveIslandEffect") )
    self.createButtonRow( ("ErodeEffect", "DilateEffect", "GrowCutEffect", "WatershedFromMarkerEffect", "ThresholdEffect", "ChangeLabelEffect", "MakeModelEffect", "FastMarchingEffect") )

    extensions = []
    for k in slicer.modules.editorExtensions:
      extensions.append(k)
    self.createButtonRow( extensions )

    self.createButtonRow( ("PreviousCheckPoint", "NextCheckPoint"), rowLabel="Undo/Redo: " )

    #
    # the labels
    #
    self.toolsActiveToolFrame = qt.QFrame(self.parent)
    self.toolsActiveToolFrame.setLayout(qt.QHBoxLayout())
    self.parent.layout().addWidget(self.toolsActiveToolFrame)
    self.toolsActiveTool = qt.QLabel(self.toolsActiveToolFrame)
    self.toolsActiveTool.setText( 'Active Tool:' )
    self.toolsActiveTool.setStyleSheet("background-color: rgb(232,230,235)")
    self.toolsActiveToolFrame.layout().addWidget(self.toolsActiveTool)
    self.toolsActiveToolName = qt.QLabel(self.toolsActiveToolFrame)
    self.toolsActiveToolName.setText( '' )
    self.toolsActiveToolName.setStyleSheet("background-color: rgb(232,230,235)")
    self.toolsActiveToolFrame.layout().addWidget(self.toolsActiveToolName)

    vbox.addStretch(1)

    self.updateUndoRedoButtons()
    self._onParameterNodeModified(EditUtil.getParameterNode())
Пример #52
0
  def percentMaxChanged(self, val):
    labelNode = self.logic.getLabelNode()
    labelImage = EditUtil.getLabelImage()
    spacing = labelNode.GetSpacing()
    if vtk.VTK_MAJOR_VERSION <= 5:
      dim = labelImage.GetDimensions()
      totalVolume = spacing[0]*(dim[1]+1)+spacing[1]*(dim[3]+1)+spacing[2]*(dim[5]+1)
    else:
      dim = labelImage.GetDimensions()
      print dim
      totalVolume = spacing[0]*dim[0]+spacing[1]*dim[1]+spacing[2]*dim[2]

      percentVolumeStr = "%.5f" % (totalVolume*val/100.)
    self.percentVolume.text = '(maximum total volume: '+percentVolumeStr+' mL)'
Пример #53
0
  def deleteStructures(self, confirm=True):
    """delete all the structures"""

    #
    # iterate through structures and delete them
    #
    merge = self.merge
    if not merge:
      return

    rows = self.structures.rowCount()

    if confirm:
      if not slicer.util.confirmOkCancelDisplay("Delete %d structure volume(s)?" % rows, windowTitle='Editor'):
        return

    slicer.mrmlScene.SaveStateForUndo()

    volumeNodes = self.structureVolumes()
    for volumeNode in volumeNodes:
      slicer.mrmlScene.RemoveNode( volumeNode )
    self.updateStructures()
    EditUtil.setActiveVolumes(self.master, merge)
    self.edit(0)
Пример #54
0
  def updateLabel(self,value):
    if not self.fm:
      return
    self.fm.show(value)
    self.fm.Modified()
    self.fm.Update()

    EditUtil.getLabelImage().DeepCopy(self.fm.GetOutput())
    EditUtil.getLabelImage().Modified()

    EditUtil.markVolumeNodeAsModified(self.sliceLogic.GetLabelLayer().GetVolumeNode())
Пример #55
0
  def updateLabel(self,value):
    if not self.fm:
      return
    self.fm.show(value)
    self.fm.Modified()
    self.fm.Update()

    EditUtil.getLabelImage().DeepCopy(self.fm.GetOutput())
    EditUtil.getLabelImage().Modified()

    EditUtil.markVolumeNodeAsModified(self.sliceLogic.GetLabelLayer().GetVolumeNode())
Пример #56
0
  def create(self):
    super(MakeModelEffectOptions,self).create()

    self.goToModelMaker = qt.QPushButton("Go To Model Maker", self.frame)
    self.goToModelMaker.setToolTip( "The Model Maker interface contains a whole range of options for building sets of models and controlling the parameters." )
    self.frame.layout().addWidget(self.goToModelMaker)
    self.widgets.append(self.goToModelMaker)

    self.smooth = qt.QCheckBox("Smooth Model", self.frame)
    self.smooth.checked = True
    self.smooth.setToolTip("When smoothed, the model will look better, but some details of the label map will not be visible on the model.  When not smoothed you will see individual voxel boundaries in the model.  Smoothing here corresponds to Decimation of 0.25 and Smooting iterations of 10.")
    self.frame.layout().addWidget(self.smooth)
    self.widgets.append(self.smooth)

    #
    # model name
    #
    self.nameFrame = qt.QFrame(self.frame)
    self.nameFrame.setLayout(qt.QHBoxLayout())
    self.frame.layout().addWidget(self.nameFrame)
    self.widgets.append(self.nameFrame)

    self.modelNameLabel = qt.QLabel("Model Name: ", self.nameFrame)
    self.modelNameLabel.setToolTip( "Select the name for the newly created model." )
    self.nameFrame.layout().addWidget(self.modelNameLabel)
    self.widgets.append(self.modelNameLabel)

    self.modelName = qt.QLineEdit(self.nameFrame)
    self.modelName.setText( self.getUniqueModelName( EditUtil.getLabelName() ) )
    self.nameFrame.layout().addWidget(self.modelName)
    self.widgets.append(self.modelName)

    self.apply = qt.QPushButton("Apply", self.frame)
    self.apply.objectName = self.__class__.__name__ + 'Apply'
    self.apply.setToolTip("Build a model for the current label value of the label map being edited in the Red slice window.  Model will be created in the background." )
    self.frame.layout().addWidget(self.apply)
    self.widgets.append(self.apply)

    HelpButton(self.frame, "Use this tool build a model.  A subset of model building options is provided here.  Go to the Model Maker module to expose a range of parameters.  Use Merge and Build button in the Advanced... tab to quickly make a model of all defined structures in the merge label map.")

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

    self.connections.append( (self.apply, 'clicked()', self.onApply) )
    self.connections.append( (self.goToModelMaker, 'clicked()', self.onGoToModelMaker) )
Пример #57
0
    def __init__(self, sliceWidget):
        super(PaintEffectTool, self).__init__(sliceWidget)
        # create a logic instance to do the non-gui work
        self.logic = PaintEffectLogic(self.sliceWidget.sliceLogic())

        # configuration variables
        self.delayedPaint = True
        self.parameterNode = EditUtil.getParameterNode()
        self.sphere = not (0 == int(
            self.parameterNode.GetParameter("PaintEffect,sphere")))
        self.smudge = not (0 == int(
            self.parameterNode.GetParameter("PaintEffect,smudge")))
        self.pixelMode = not (0 == int(
            self.parameterNode.GetParameter("PaintEffect,pixelMode")))
        self.radius = float(
            self.parameterNode.GetParameter("PaintEffect,radius"))

        # interaction state variables
        self.position = [0, 0, 0]
        self.paintCoordinates = []
        self.feedbackActors = []
        self.lastRadius = 0

        # scratch variables
        self.rasToXY = vtk.vtkMatrix4x4()

        # initialization
        self.brush = vtk.vtkPolyData()
        self.createGlyph(self.brush)
        self.mapper = vtk.vtkPolyDataMapper2D()
        self.actor = vtk.vtkActor2D()
        if vtk.VTK_MAJOR_VERSION <= 5:
            self.mapper.SetInput(self.brush)
        else:
            self.mapper.SetInputData(self.brush)
        self.actor.SetMapper(self.mapper)
        self.actor.VisibilityOff()

        self.renderer.AddActor2D(self.actor)
        self.actors.append(self.actor)

        self.processEvent()
Пример #58
0
 def setQuickieRadius(self,radius):
   labelVolume = EditUtil.getLabelVolume()
   if labelVolume:
     if self.radiusUnitsToggle.text == 'px:':
       spacing = labelVolume.GetSpacing()
       if self.radiusPixelMode == 'diag':
         from math import sqrt
         diag = sqrt(reduce(lambda x,y:x+y, map(lambda x: x**2, spacing)))
         mmRadius = diag * radius
       elif self.radiusPixelMode == 'min':
         mmRadius = min(spacing) * radius
       else:
         print (self,"Unknown pixel mode - using 5mm")
         mmRadius = 5
     else:
       mmRadius = radius
     self.disconnectWidgets()
     self.radiusSpinBox.setValue(mmRadius)
     self.radius.setValue(mmRadius)
     self.connectWidgets()
     self.updateMRMLFromGUI()
Пример #59
0
    def __init__(self, parent=0):

        # get pixel-size-dependent parameters
        # calculate this before calling superclass init
        # so it can be used to set mrml defaults if needed
        labelVolume = EditUtil.getLabelVolume()
        if labelVolume and labelVolume.GetImageData():
            spacing = labelVolume.GetSpacing()
            dimensions = labelVolume.GetImageData().GetDimensions()
            self.minimumRadius = 0.5 * min(spacing)
            bounds = [a * b for a, b in zip(spacing, dimensions)]
            self.maximumRadius = 0.5 * max(bounds)
        else:
            self.minimumRadius = 0.01
            self.maximumRadius = 100

        super(PaintEffectOptions, self).__init__(parent)

        # option to use 'min' or 'diag'
        # - min means pixel radius is min spacing
        # - diag means corner to corner length
        self.radiusPixelMode = 'min'