Esempio n. 1
0
def ReadImageSlicer(FileName):
    mrml = slicer.vtkMRMLScene()
    vl = slicer.vtkSlicerVolumesLogic()
    vl.SetAndObserveMRMLScene(mrml)
    n = vl.AddArchetypeVolume(FileName, 'CTC')
    i = n.GetImageData()
    return i
Esempio n. 2
0
def registerCustomVrPresets(usPresetsScenePath):
    """
  Set volume rendering presets from Resources/VrPresets/US-VrPresets.mrml
  """
    import os

    if not os.path.isfile(usPresetsScenePath):
        logging.warning('Volume rendering presets are not found at {0}'.format(
            usPresetsScenePath))
        return

    # Read scene
    usPresetsScene = slicer.vtkMRMLScene()
    vrPropNode = slicer.vtkMRMLVolumePropertyNode()
    usPresetsScene.RegisterNodeClass(vrPropNode)
    usPresetsScene.SetURL(usPresetsScenePath)
    usPresetsScene.Connect()

    # Add presets to volume rendering logic
    vrLogic = slicer.modules.volumerendering.logic()
    presetsScene = vrLogic.GetPresetsScene()
    vrNodes = usPresetsScene.GetNodesByClass("vtkMRMLVolumePropertyNode")
    vrNodes.UnRegister(None)
    for itemNum in range(vrNodes.GetNumberOfItems()):
        node = vrNodes.GetItemAsObject(itemNum)
        vrLogic.AddPreset(node)
Esempio n. 3
0
  def __init__(self, parent=None):
    ScriptedLoadableModuleLogic.__init__(self,parent)

    self.sceneObservers = [] # (eventtype, observertag)
    self.nodeObservers = {} # (eventtype, observertag) by node

    # a scratch scene to use for generating and parsing xml representations
    # of mrml nodes
    self.helperScene = slicer.vtkMRMLScene()
    self.helperScene.SetSaveToXMLString(1)
    self.helperScene.SetLoadFromXMLString(1)

    self.emitCallback = None
Esempio n. 4
0
class PETTumorSegmentationEffectLogic(LabelEffect.LabelEffectLogic):
    """
  This class contains helper methods for a given effect
  type.  It can be instanced as needed by an PETTumorSegmentationEffectTool
  or PETTumorSegmentationEffectOptions instance in order to compute intermediate
  results (say, for user feedback) or to implement the final
  segmentation editing operation.  This class is split
  from the PETTumorSegmentationEffectTool so that the operations can be used
  by other code without the need for a view context.
  """

    scene = slicer.vtkMRMLScene()
    vtkSegmentationLogic = None
    segmentationParameters = None
    options = None
    showDebugInfoOn = False
    undoDeficit = 0

    #Tested these as class static variables, but they weren't being appropriately static; they were inconsistent across views.
    #As such, I'm leaving them attached to the parameter node for now.
    #imageStashUndoQueue = []
    #imageStashRedoQueue = []

    def __init__(self, sliceLogic):
        super(PETTumorSegmentationEffectLogic, self).__init__(sliceLogic)
        self.sliceLogic = sliceLogic

        #undo deficit tracks undone actions of other tools, or the same tool on another stretch
        #allows matching undos whent he scene undo list fails to match the volume undo list
        #self.

        self.scene.SetUndoOn()

        #set the helper logic if needed.
        if not PETTumorSegmentationEffectLogic.vtkSegmentationLogic:
            PETTumorSegmentationEffectLogic.vtkSegmentationLogic = slicer.vtkSlicerPETTumorSegmentationLogic(
            )
        if not PETTumorSegmentationEffectLogic.segmentationParameters:
            PETTumorSegmentationEffectLogic.segmentationParameters = self.getPETTumorSegmentationParameterNode(
            )

        #undo/redo queue to recall the vtkImageStash.  vtkImageStash is a difficult class to set
        #up in C++, so it's handled in Python.  Maybe not the most elegant solution, but sufficient for now.
        if not hasattr(PETTumorSegmentationEffectLogic.segmentationParameters,
                       'imageStashUndoQueue'):
            PETTumorSegmentationEffectLogic.segmentationParameters.imageStashUndoQueue = []
        if not hasattr(PETTumorSegmentationEffectLogic.segmentationParameters,
                       'imageStashRedoQueue'):
            PETTumorSegmentationEffectLogic.segmentationParameters.imageStashRedoQueue = []

    # Safely return parameter node
    def getPETTumorSegmentationParameterNode(self):
        """Get the Editor parameter node - a singleton in the scene"""
        node = self._findPETTumorSegmentationParameterNodeInScene()
        if not node:
            node = self._createPETTumorSegmentationParameterNode()
        return node

    # Finds existing parameter node, if it exits
    def _findPETTumorSegmentationParameterNodeInScene(self):
        node = None
        size = self.scene.GetNumberOfNodesByClass(
            "vtkMRMLPETTumorSegmentationParametersNode")
        if (size > 0):
            node = self.scene.GetNthNodeByClass(
                0, "vtkMRMLPETTumorSegmentationParametersNode")
        return node

    # Generates parameter node it nonexistant
    # Also adds it and the fiducial nodes to the scene
    def _createPETTumorSegmentationParameterNode(self):
        """create the PETTumorSegmentation parameter node - a singleton in the scene
    This is used internally by getPETTumorSegmentationParameterNode - shouldn't really
    be called for any other reason.
    """
        node = slicer.vtkMRMLPETTumorSegmentationParametersNode()
        self.scene.AddNode(node)
        # Since we are a singleton, the scene won't add our node into the scene,
        # but will instead insert a copy, so we find that and return it
        node = self._findPETTumorSegmentationParameterNodeInScene()

        centerFiducialList = slicer.vtkMRMLFiducialListNode()
        self.scene.AddNode(centerFiducialList)
        node.SetCenterPointIndicatorListReference(centerFiducialList.GetID())

        globalRefinementFiducialList = slicer.vtkMRMLFiducialListNode()
        self.scene.AddNode(globalRefinementFiducialList)
        node.SetGlobalRefinementIndicatorListReference(
            globalRefinementFiducialList.GetID())

        localRefinementFiducialList = slicer.vtkMRMLFiducialListNode()
        self.scene.AddNode(localRefinementFiducialList)
        node.SetLocalRefinementIndicatorListReference(
            localRefinementFiducialList.GetID())

        return node

    # Clears out all queues of data.
    # Removes all fiducials from personal scene.
    def reset(self):
        # On reset, act as if all existing labels and such are now just products of other tools.
        self.scene.ClearUndoStack()
        self.scene.ClearRedoStack()

        self.segmentationParameters.Clear()
        self.segmentationParameters.imageStashUndoQueue = []
        self.segmentationParameters.imageStashRedoQueue = []

        centerPointFiducialsNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetCenterPointIndicatorListReference()))
        centerPointFiducials = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            centerPointFiducialsNode)
        centerPointFiducials.RemoveAllFiducials()
        globalRefinementFiducialNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetGlobalRefinementIndicatorListReference()))
        globalRefinementFiducial = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            globalRefinementFiducialNode)
        globalRefinementFiducial.RemoveAllFiducials()
        localRefinementFiducialNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetLocalRefinementIndicatorListReference()))
        localRefinementFiducial = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            localRefinementFiducialNode)
        localRefinementFiducial.RemoveAllFiducials()
        self.undoDeficit = 0

    #Calls standard save state for label map and includes our scene save state.
    #Would include image stash save state here, but this gets called by the editor itself on Apply, so it can't take another argument.
    #So, the image stash queue is updated in line instead.
    def saveStateForUndo(self):
        if self.options and self.options.undoRedoRegistered == False:
            self.options.registerEditorUndoRedo()
        if self.undoRedo:
            self.undoRedo.saveState()
            #capture reference to the vtkImageStash used when saving the state

        self.scene.SaveStateForUndo()

    #Calls scene undo if available and handles stash queue undo.  Increments undo deficit if needed.
    def undo(self):
        #if scene has levels to undo, then undo queue is still on this tool's results
        if (self.scene.GetNumberOfUndoLevels() > 0):
            self.scene.Undo()
            #move top of stash undo queue to top of stash redo queue
            self.segmentationParameters.imageStashRedoQueue.append(
                self.segmentationParameters.imageStashUndoQueue[-1])
            self.segmentationParameters.imageStashUndoQueue.pop()
        #otherwise, it is undoing other tool's results, so use deficit as buffer
        else:
            self.undoDeficit += 1

    #Calls scene redo if available and handles stash queue redo.  Decrements undo deficit if needed.
    def redo(self):
        #if scene has levels to redo, then redo queue is still on this tool's results
        if (self.undoDeficit == 0):
            self.scene.Redo()
            #move top of stash redo queue to top of stash undo queue
            self.segmentationParameters.imageStashUndoQueue.append(
                self.segmentationParameters.imageStashRedoQueue[-1])
            self.segmentationParameters.imageStashRedoQueue.pop()
        #otherwise, it is redoing other tool's results, so use deficit as buffer
        else:
            self.undoDeficit -= 1

    def applyXY(self, xy, volumeID, labelVolumeID):
        #Convert the mouse point to a point in 3D space
        ras = self.xyToRAS(xy)
        self.apply(ras, volumeID, labelVolumeID)

    #Use the tool with a mouse click location
    #Handles all variants of refinement
    def apply(self, ras, volumeID, labelVolumeID):
        #Avoid undos across volumes by checking if the volume has changed and resetting if so
        newLabel = self.editUtil.getLabel()
        newVolumeID = volumeID
        newLabelVolumeID = labelVolumeID
        oldLabel = self.segmentationParameters.GetLabel()
        oldVolumeID = self.segmentationParameters.GetPETVolumeReference()
        oldLabelVolumeID = self.segmentationParameters.GetSegmentationVolumeReference(
        )
        #Do so before saving the state
        if (newVolumeID != oldVolumeID
                or newLabelVolumeID != oldLabelVolumeID):
            self.reset()

        #State is saved at other points, but the stash only needs to be acquired when placing a center point,
        #so it's fine to leave out it's state save equivalent from saveStateForUndo.
        self.saveStateForUndo()
        if (self.options):
            self.options.updateMRMLFromGUI()

        #Get the fiducial nodes
        centerPointFiducialsNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetCenterPointIndicatorListReference()))
        centerPointFiducials = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            centerPointFiducialsNode)
        globalRefinementFiducialNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetGlobalRefinementIndicatorListReference()))
        globalRefinementFiducial = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            globalRefinementFiducialNode)
        localRefinementFiducialNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetLocalRefinementIndicatorListReference()))
        localRefinementFiducial = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            localRefinementFiducialNode)

        #Set the current label and volumes
        self.segmentationParameters.SetLabel(self.editUtil.getLabel())
        self.segmentationParameters.SetPETVolumeReference(volumeID)
        self.segmentationParameters.SetSegmentationVolumeReference(
            labelVolumeID)

        #If there are no center points, then the click should make a new center point and segmentation.
        #If the label has changed, go with this and remove center points to start a new segmentation.
        #If no refinement mode is on, remove points and start a new segmentation.
        if (centerPointFiducials.GetNumberOfFiducials() == 0
                or newLabel != oldLabel
                or self.segmentationParameters.GetNoRefinementOn()
            ):  # initialize segmentation
            #clear old fiducials if applying new due to No Refinement or new label
            if (centerPointFiducials.GetNumberOfFiducials() != 0):
                globalRefinementFiducial.RemoveAllFiducials()
                localRefinementFiducial.RemoveAllFiducials()
                centerPointFiducials.RemoveAllFiducials()
            #add the new center point
            centerPointFiducials.AddFiducialWithXYZ(ras[0], ras[1], ras[2],
                                                    False)

            #Pre-tool state is directly previous in the Editor's label map queue.
            imageStash = self.undoRedo.undoList[-1].stash

            #Copy it as current pre-tool state into the stash undo queue
            self.segmentationParameters.imageStashUndoQueue.append(imageStash)
            self.segmentationParameters.imageStashRedoQueue = []

            #Decompress if for use.  Waiting loop required to check that previous Stash action complete.
            while (imageStash.GetStashing() != 0):
                pass
            imageStash.Unstash()

            #Apply new segmentation with parameters and pre-tool label image state
            self.vtkSegmentationLogic.Apply(self.segmentationParameters,
                                            imageStash.GetStashImage())

            #Re-compress stashed image in queues
            imageStash.ThreadedStash()
        #Otherwise, refining, either globally or locally.
        else:
            #Pre-tool state is the same as it was for the previous use of the tool, so it's at the top of the stash undo queue.
            imageStash = self.segmentationParameters.imageStashUndoQueue[-1]

            #Copy it as current pre-tool state into the stash undo queue
            self.segmentationParameters.imageStashUndoQueue.append(imageStash)
            self.segmentationParameters.imageStashRedoQueue = []

            #Decompress if for use.  Waiting loop required to check that previous Stash action complete.
            while (imageStash.GetStashing() != 0):
                pass
            imageStash.Unstash()

            #If global refinement is active, then the existing segmentation should be refined globally.
            if (self.segmentationParameters.GetGlobalRefinementOn()
                ):  # perform global refinement, unless new label
                #Only one global refinement point at a time
                globalRefinementFiducial.RemoveAllFiducials()
                globalRefinementFiducial.AddFiducialWithXYZ(
                    ras[0], ras[1], ras[2], False)
                self.vtkSegmentationLogic.ApplyGlobalRefinement(
                    self.segmentationParameters, imageStash.GetStashImage())
            #If local refinement is active, then the existing segmentation should be refined localy.
            elif (self.segmentationParameters.GetLocalRefinementOn()
                  ):  # perform local refinement, unless new label
                localRefinementFiducial.AddFiducialWithXYZ(
                    ras[0], ras[1], ras[2], False)
                self.vtkSegmentationLogic.ApplyLocalRefinement(
                    self.segmentationParameters, imageStash.GetStashImage())
            #end refinement choice

            #Re-compress stashed image in queues
            imageStash.ThreadedStash()
        #end check if new point is new segmentation or a refinement point

        #clear any undo deficit due to cutting off redo queues
        self.undoDeficit = 0

        #This is already done in the C++ logic, so it is left out here.
        #labelVolumeNode = slicer.mrmlScene.GetNodeByID(str(labelVolumeID))
        #labelVolume = slicer.vtkMRMLScalarVolumeNode.SafeDownCast(labelVolumeNode)
        #labelVolume.GetImageData().Modified()
        #labelVolume.Modified()
        self.showDebugInfo()

    def applyParameters(self):
        #saveStateForUndo() # this has to be called by editor before the MRML node is updated

        centerPointFiducialsNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetCenterPointIndicatorListReference()))
        centerPointFiducials = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            centerPointFiducialsNode)

        self.segmentationParameters.SetLabel(self.editUtil.getLabel())
        self.segmentationParameters.SetPETVolumeReference(
            self.editUtil.getBackgroundID())
        self.segmentationParameters.SetSegmentationVolumeReference(
            self.editUtil.getLabelID())

        # Apply from button acts like refinement, so it shares the same pre-tool state, on top of the stash undo queue
        imageStash = self.segmentationParameters.imageStashUndoQueue[-1]

        #Copy it as current pre-tool state into the stash undo queue
        self.segmentationParameters.imageStashUndoQueue.append(imageStash)
        self.segmentationParameters.imageStashRedoQueue = []

        #Decompress if for use.  Waiting loop required to check that previous Stash action complete.
        while (imageStash.GetStashing() != 0):
            pass
        imageStash.Unstash()

        # start segmention with updated parameters
        self.vtkSegmentationLogic.Apply(self.segmentationParameters,
                                        imageStash.GetStashImage())

        #Re-compress stashed image in queues
        imageStash.ThreadedStash()

        #This is already done in the C++ logic, so it is left out here.
        #labelVolumeNode = slicer.mrmlScene.GetNodeByID(str(self.editUtil.getLabelID()))
        #labelVolume = slicer.vtkMRMLScalarVolumeNode.SafeDownCast(labelVolumeNode)
        #labelVolume.GetImageData().Modified()
        #labelVolume.Modified()
        self.showDebugInfo()

    #Shows the center point and refinement points of the current scene state.
    #Creates a unique fiducials node for it.
    def showDebugInfo(self):
        if (not self.showDebugInfoOn):
            return False

        #Check for existance of our fiducial list.  If it exists, use it as is.
        #Possible bug: If someone generates a list by this name, it could conflict with ours.
        #...Need to make it static and delete it on destruction of our tool object to be safe.
        #It doesn't properly hide from editors
        osfDebugFiducialsNodes = slicer.mrmlScene.GetNodesByName(
            "OSFDebugFiducials")
        osfDebugFiducialsNodes.SetReferenceCount(
            osfDebugFiducialsNodes.GetReferenceCount() -
            1)  #Prevents memory leaks from GetNodesByName
        osfDebugFiducialsNode = osfDebugFiducialsNodes.GetItemAsObject(0)
        osfDebugFiducials = None
        if (osfDebugFiducialsNode):
            osfDebugFiducials = slicer.vtkMRMLMarkupsFiducialNode.SafeDownCast(
                osfDebugFiducialsNode)
            osfDebugFiducials.RemoveAllMarkups()
        else:
            markupsLogic = slicer.modules.markups.logic()
            osfDebugFiducialsID = markupsLogic.AddNewFiducialNode(
                "OSFDebugFiducials", slicer.mrmlScene)
            osfDebugFiducials = slicer.mrmlScene.GetNodeByID(
                osfDebugFiducialsID)
        osfDebugFiducials.SetHideFromEditors(True)

        centerPointFiducialsNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetCenterPointIndicatorListReference()))
        centerPointFiducials = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            centerPointFiducialsNode)
        globalRefinementFiducialNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetGlobalRefinementIndicatorListReference()))
        globalRefinementFiducial = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            globalRefinementFiducialNode)
        localRefinementFiducialNode = self.scene.GetNodeByID(
            str(self.segmentationParameters.
                GetLocalRefinementIndicatorListReference()))
        localRefinementFiducial = slicer.vtkMRMLFiducialListNode.SafeDownCast(
            localRefinementFiducialNode)
        if (centerPointFiducials.GetNumberOfFiducials() > 0):
            centerXYZ = [
                self.segmentationParameters.GetCenterpointX(),
                self.segmentationParameters.GetCenterpointY(),
                self.segmentationParameters.GetCenterpointZ()
            ]
            centerXYZ[0] = -centerXYZ[0]
            centerXYZ[1] = -centerXYZ[1]
            centerInt = osfDebugFiducials.AddFiducialFromArray(centerXYZ)
            osfDebugFiducials.SetNthFiducialLabel(centerInt, "C")
            osfDebugFiducials.SetNthMarkupLocked(centerInt, True)
            osfDebugFiducials.SetNthFiducialVisibility(centerInt, True)
        if (globalRefinementFiducial.GetNumberOfFiducials() > 0):
            thresholdInt = osfDebugFiducials.AddFiducialFromArray(
                globalRefinementFiducial.GetNthFiducialXYZ(
                    globalRefinementFiducial.GetNumberOfFiducials() - 1))
            osfDebugFiducials.SetNthFiducialLabel(thresholdInt, "Th")
            osfDebugFiducials.SetNthMarkupLocked(thresholdInt, True)
            osfDebugFiducials.SetNthFiducialVisibility(thresholdInt, True)
        if (localRefinementFiducial.GetNumberOfFiducials() > 0):
            for i in range(localRefinementFiducial.GetNumberOfFiducials()):
                edgeInt = osfDebugFiducials.AddFiducialFromArray(
                    localRefinementFiducial.GetNthFiducialXYZ(i))
                osfDebugFiducials.SetNthFiducialLabel(edgeInt, "Ed" + str(i))
                osfDebugFiducials.SetNthMarkupLocked(edgeInt, True)
                osfDebugFiducials.SetNthFiducialVisibility(edgeInt, True)

    #DEBUG ONLY
    def clearDebugInfo(self):
        if (not self.showDebugInfoOn):
            return False
        osfDebugFiducialsNodes = slicer.mrmlScene.GetNodesByName(
            "OSFDebugFiducials")
        osfDebugFiducialsNodes.SetReferenceCount(
            osfDebugFiducialsNodes.GetReferenceCount() - 1)
        osfDebugFiducialsNode = osfDebugFiducialsNodes.GetItemAsObject(0)
        osfDebugFiducials = None
        if (osfDebugFiducialsNode):
            osfDebugFiducials = slicer.vtkMRMLMarkupsFiducialNode.SafeDownCast(
                osfDebugFiducialsNode)
            osfDebugFiducials.RemoveAllMarkups()