Ejemplo n.º 1
0
  def loadBinfo(self,filePath):
     filePrefix, fileExtension = os.path.splitext(filePath)
     if not fileExtension == ".binfo":
        print "Error, file not a binfo file: " + filePath
     self.voiComboBox.clear()
     self.motionStateComboBox.clear() 
     binfo = LoadCTXLib.Binfo()
     binfo.readFile(filePath)
     self.binfoList.append(binfo)
     
     #

     #Create segmentation node for this binfo
     segmentationNode = slicer.vtkMRMLSegmentationNode()
     name = slicer.mrmlScene.GenerateUniqueName(os.path.basename(filePrefix))
     segmentationNode.SetName(name)
     slicer.mrmlScene.AddNode(segmentationNode)
     
     binfo.segmentationNode = segmentationNode
     self.selectSegmentation.setCurrentNode(segmentationNode)
     self.setBinfoFile(segmentationNode)
     
     displayNode = slicer.vtkMRMLSegmentationDisplayNode()
     slicer.mrmlScene.AddNode(displayNode)
     segmentationNode.SetAndObserveDisplayNodeID(displayNode.GetID())
     
     displayNode.SetAllSegmentsVisibility2DFill(False)
     displayNode.SetSliceIntersectionThickness(3)
     
     storageNode = slicer.vtkMRMLSegmentationStorageNode()
     slicer.mrmlScene.AddNode(storageNode)
     segmentationNode.SetAndObserveStorageNodeID(storageNode.GetID())
Ejemplo n.º 2
0
  def TestSection_01_GenerateInputData(self):

    self.inputSegmentationNode = slicer.vtkMRMLSegmentationNode()
    slicer.mrmlScene.AddNode(self.inputSegmentationNode)

    # Create new segments
    import random
    for segmentName in ['first', 'second', 'third']:

      sphereSegment = vtkSegmentationCore.vtkSegment()
      sphereSegment.SetName(segmentName)
      sphereSegment.SetColor(random.uniform(0.0,1.0), random.uniform(0.0,1.0), random.uniform(0.0,1.0))

      sphere = vtk.vtkSphereSource()
      sphere.SetCenter(random.uniform(0,100),random.uniform(0,100),random.uniform(0,100))
      sphere.SetRadius(random.uniform(20,30))
      sphere.Update()
      spherePolyData = sphere.GetOutput()
      sphereSegment.AddRepresentation(
        vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName(),
        spherePolyData)

      self.inputSegmentationNode.GetSegmentation().AddSegment(sphereSegment)

    self.assertEqual(self.inputSegmentationNode.GetSegmentation().GetNumberOfSegments(), 3)
  def onSegment(self):
    pluginHandlerSingleton = slicer.qSlicerSubjectHierarchyPluginHandler.instance()
    currentItemID = pluginHandlerSingleton.currentItem()
    if not currentItemID:
      logging.error("Invalid current item")

    shNode = pluginHandlerSingleton.subjectHierarchyNode()
    volumeNode = shNode.GetItemDataNode(currentItemID)

    # Switch to Segment Editor module
    pluginHandlerSingleton.pluginByName('Default').switchToModule('SegmentEditor')
    editorWidget = slicer.modules.segmenteditor.widgetRepresentation().self()

    # Create new segmentation only if there is no segmentation node, or the current segmentation is not empty
    # (switching to the module will create an empty segmentation if there is none in the scene, but not otherwise)
    segmentationNode = editorWidget.parameterSetNode.GetSegmentationNode()
    import vtkSegmentationCorePython as vtkSegmentationCore
    if segmentationNode is None or segmentationNode.GetSegmentation().GetNumberOfSegments() > 0:
      segmentationNode = slicer.vtkMRMLSegmentationNode()
      slicer.mrmlScene.AddNode(segmentationNode)
      editorWidget.parameterSetNode.SetAndObserveSegmentationNode(segmentationNode)
    # Name segmentation node based on the volume
    segmentationNode.SetName(volumeNode.GetName() + '_Segmentation')

    # Set master volume
    editorWidget.parameterSetNode.SetAndObserveMasterVolumeNode(volumeNode)

    # Place segmentation under the master volume in subject hierarchy
    segmentationShItemID = shNode.GetItemByDataNode(segmentationNode)
    shNode.SetItemParent(segmentationShItemID, shNode.GetItemParent(currentItemID))
Ejemplo n.º 4
0
    def enter(self):
        """Runs whenever the module is reopened
    """
        if self.editor.turnOffLightboxes():
            slicer.util.warningDisplay(
                'Segment Editor is not compatible with slice viewers in light box mode.'
                'Views are being reset.',
                windowTitle='Segment Editor')

        # Allow switching between effects and selected segment using keyboard shortcuts
        self.editor.installKeyboardShortcuts()

        # Set parameter set node if absent
        self.selectParameterNode()
        self.editor.updateWidgetFromMRML()

        # If no segmentation node exists then create one so that the user does not have to create one manually
        if not self.editor.segmentationNodeID():
            segmentationNode = slicer.mrmlScene.GetFirstNode(
                None, "vtkMRMLSegmentationNode")
            if not segmentationNode:
                segmentationNode = slicer.vtkMRMLSegmentationNode()
                slicer.mrmlScene.AddNode(segmentationNode)
            self.editor.setSegmentationNode(segmentationNode)
            if not self.editor.masterVolumeNodeID():
                masterVolumeNodeID = self.getDefaultMasterVolumeNodeID()
                self.editor.setMasterVolumeNodeID(masterVolumeNodeID)
    def UpdateSegmentationNode(self):
        SegLogic = slicer.modules.segmentations.logic()
        OldSegmentationNode = self.SegmentationNode
        NewSegmentationNode = slicer.vtkMRMLSegmentationNode()
        NewSegmentationNode.SetName(OldSegmentationNode.GetName())
        # Import working labelmap from interface
        WorkingLabelMap = self.WorkingLabelMapStorage.currentNode()
        if WorkingLabelMap != None:
            LabelMapNodeName = WorkingLabelMap.GetName()

            OldNodeName = LabelMapNodeName[:
                                           -3]  # Assuming all tag names are 3 chars long, the last one will be removed
            # Remove old label map - if present
            #if self.SegmentationNode.GetBinaryLabelmapRepresentation(OldNodeName) != None:
            self.SegmentationNode.RemoveSegment(OldNodeName)

            # Create new label map representation
            SegLogic.ImportLabelmapToSegmentationNode(WorkingLabelMap,
                                                      self.SegmentationNode)
            self.SegmentationNode.CreateBinaryLabelmapRepresentation()

            # Update closed surface representation for visualization
            if self.SegmentationNode.GetClosedSurfaceRepresentation(
                    LabelMapNodeName) == None:
                self.SegmentationNode.CreateClosedSurfaceRepresentation()
                self.SegmentationNode.SetDisplayVisibility(0)

            # Toggle visualization on, if specified
            if self.VisualizeLabelMapButton.isChecked():
                self.SegmentationNode.SetDisplayVisibility(1)
    def OnInputVolumeSelectorChanged(self):

        # First, (re)initialize segmentation node to contain input and working data

        # Check scene for previous segmentation node, remove if present
        SegNodeName = "Seg_" + self.InputVolumeSelector.currentNode().GetName()
        OldSegNode = slicer.util.getNode(SegNodeName)
        if OldSegNode != None:
            OldSegNode.SetSelected(0)
            slicer.mrmlScene.RemoveNode(OldSegNode)

        # Instantiate new segmentation node
        self.SegmentationNode = slicer.vtkMRMLSegmentationNode()
        self.SegmentationNode.SetScene(slicer.mrmlScene)
        slicer.mrmlScene.AddNode(self.SegmentationNode)
        self.SegmentationNode.SetSelected(1)
        self.SegmentationNode.SetName(SegNodeName)

        NewInputVolumeNode = self.InputVolumeSelector.currentNode()

        if NewInputVolumeNode == None:
            self.ThresholdVolumeButton.enabled = False
            return True

        if NewInputVolumeNode.GetClassName() != 'vtkMRMLScalarVolumeNode':
            print "ERROR - Invalid node type in Input Volume combo box"
            self.ThresholdVolumeButton.enabled = False
            return False

        else:

            #self.UpdateSegmentationNode()

            self.ThresholdVolumeButton.enabled = True
    def onSegment(self):
        pluginHandlerSingleton = slicer.qSlicerSubjectHierarchyPluginHandler.instance(
        )
        currentItemID = pluginHandlerSingleton.currentItem()
        if not currentItemID:
            logging.error("Invalid current item")

        shNode = pluginHandlerSingleton.subjectHierarchyNode()
        volumeNode = shNode.GetItemDataNode(currentItemID)

        # Switch to Segment Editor module
        pluginHandlerSingleton.pluginByName('Default').switchToModule(
            'SegmentEditor')
        editorWidget = slicer.modules.segmenteditor.widgetRepresentation(
        ).self()

        # Create new segmentation only if there is no segmentation node, or the current segmentation is not empty
        # (switching to the module will create an empty segmentation if there is none in the scene, but not otherwise)
        segmentationNode = editorWidget.parameterSetNode.GetSegmentationNode()
        import vtkSegmentationCorePython as vtkSegmentationCore
        if segmentationNode is None or segmentationNode.GetSegmentation(
        ).GetNumberOfSegments() > 0:
            segmentationNode = slicer.vtkMRMLSegmentationNode()
            slicer.mrmlScene.AddNode(segmentationNode)
            editorWidget.parameterSetNode.SetAndObserveSegmentationNode(
                segmentationNode)
        # Name segmentation node based on the volume
        segmentationNode.SetName(volumeNode.GetName() + '_Segmentation')

        # Set master volume
        editorWidget.parameterSetNode.SetAndObserveMasterVolumeNode(volumeNode)

        # Place segmentation under the master volume in subject hierarchy
        segmentationShItemID = shNode.GetItemByDataNode(segmentationNode)
        shNode.SetItemParent(segmentationShItemID, currentItemID)
Ejemplo n.º 8
0
    def TestSection_01_GenerateInputData(self):

        self.inputSegmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(self.inputSegmentationNode)

        # Create new segments
        import random
        for segmentName in ['first', 'second', 'third']:

            sphereSegment = vtkSegmentationCore.vtkSegment()
            sphereSegment.SetName(segmentName)
            sphereSegment.SetColor(random.uniform(0.0, 1.0),
                                   random.uniform(0.0, 1.0),
                                   random.uniform(0.0, 1.0))

            sphere = vtk.vtkSphereSource()
            sphere.SetCenter(random.uniform(0, 100), random.uniform(0, 100),
                             random.uniform(0, 100))
            sphere.SetRadius(random.uniform(20, 30))
            sphere.Update()
            spherePolyData = sphere.GetOutput()
            sphereSegment.AddRepresentation(
                vtkSegmentationCore.vtkSegmentationConverter.
                GetSegmentationClosedSurfaceRepresentationName(),
                spherePolyData)

            self.inputSegmentationNode.GetSegmentation().AddSegment(
                sphereSegment)

        self.assertEqual(
            self.inputSegmentationNode.GetSegmentation().GetNumberOfSegments(),
            3)
Ejemplo n.º 9
0
  def test_SegmentStatisticsBasic(self):
    """
    This tests some aspects of the label statistics
    """

    self.delayDisplay("Starting test_SegmentStatisticsBasic")

    import vtkSegmentationCorePython as vtkSegmentationCore
    import SampleData
    from SegmentStatistics import SegmentStatisticsLogic

    self.delayDisplay("Load master volume")

    sampleDataLogic = SampleData.SampleDataLogic()
    masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

    self.delayDisplay("Create segmentation containing a few spheres")

    segmentationNode = slicer.vtkMRMLSegmentationNode()
    slicer.mrmlScene.AddNode(segmentationNode)
    segmentationNode.CreateDefaultDisplayNodes()
    segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

    # Geometry for each segment is defined by: radius, posX, posY, posZ
    segmentGeometries = [[10, -6,30,28], [20, 0,65,32], [15, 1, -14, 30], [12, 0, 28, -7], [5, 0,30,64],
                         [12, 31, 33, 27], [17, -42, 30, 27]]
    for segmentGeometry in segmentGeometries:
      sphereSource = vtk.vtkSphereSource()
      sphereSource.SetRadius(segmentGeometry[0])
      sphereSource.SetCenter(segmentGeometry[1], segmentGeometry[2], segmentGeometry[3])
      sphereSource.Update()
      uniqueSegmentID = segmentationNode.GetSegmentation().GenerateUniqueSegmentID("Test")
      segmentationNode.AddSegmentFromClosedSurfaceRepresentation(sphereSource.GetOutput(), uniqueSegmentID)

    self.delayDisplay("Compute statistics")

    segStatLogic = SegmentStatisticsLogic()
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("ScalarVolume", masterVolumeNode.GetID())
    segStatLogic.computeStatistics()

    self.delayDisplay("Check a few numerical results")
    self.assertEqual( segStatLogic.getStatistics()["Test_2","LabelmapSegmentStatisticsPlugin.voxel_count"], 9807)
    self.assertEqual( segStatLogic.getStatistics()["Test_4","ScalarVolumeSegmentStatisticsPlugin.voxel_count"], 380)

    self.delayDisplay("Export results to table")
    resultsTableNode = slicer.vtkMRMLTableNode()
    slicer.mrmlScene.AddNode(resultsTableNode)
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)

    self.delayDisplay("Export results to string")
    logging.info(segStatLogic.exportToString())

    outputFilename = slicer.app.temporaryPath + '/SegmentStatisticsTestOutput.csv'
    self.delayDisplay("Export results to CSV file: "+outputFilename)
    segStatLogic.exportToCSVFile(outputFilename)

    self.delayDisplay('test_SegmentStatisticsBasic passed!')
    def _loadMaskNode(self, root, fname, ref_im=None):
        ma_path = self._buildPath(root, fname)
        if ma_path is None:
            return None

        # Check if the file actually exists
        if not os.path.isfile(ma_path):
            self.logger.warning(
                'Segmentation file %s does not exist, skipping...', fname)
            return None

        # Determine if file is segmentation based on extension
        isSegmentation = os.path.splitext(ma_path)[0].endswith('.seg')
        # Try to load the mask
        if isSegmentation:
            self.logger.debug('Loading segmentation')
            load_success, ma_node = slicer.util.loadSegmentation(
                ma_path, returnNode=True)
        else:
            self.logger.debug(
                'Loading labelmap and converting to segmentation')
            # If not segmentation, then load as labelmap then convert to segmentation
            load_success, ma_node = slicer.util.loadLabelVolume(
                ma_path, returnNode=True)
            if load_success:
                # Only try to make a segmentation node if Slicer was able to load the label map
                seg_node = slicer.vtkMRMLSegmentationNode()
                slicer.mrmlScene.AddNode(seg_node)
                seg_node.SetReferenceImageGeometryParameterFromVolumeNode(
                    ref_im)
                load_success = slicer.modules.segmentations.logic(
                ).ImportLabelmapToSegmentationNode(ma_node, seg_node)
                slicer.mrmlScene.RemoveNode(ma_node)
                ma_node = seg_node

                # Add a storage node for this segmentation node
                file_base, ext = os.path.splitext(ma_path)
                store_node = seg_node.CreateDefaultStorageNode()
                slicer.mrmlScene.AddNode(store_node)
                seg_node.SetAndObserveStorageNodeID(store_node.GetID())

                store_node.SetFileName('%s.seg%s' % (file_base, ext))

                # UnRegister the storage node to prevent a memory leak
                store_node.UnRegister(None)

        if not load_success:
            self.logger.warning('Failed to load ' + ma_path)
            return None

        # Use the file basename as the name for the newly loaded segmentation node
        file_base = os.path.splitext(os.path.basename(ma_path))[0]
        if isSegmentation:
            # split off .seg
            file_base = os.path.splitext(file_base)[0]
        ma_node.SetName(file_base)

        return ma_node
Ejemplo n.º 11
0
    def test_Segmentation(self):
        """ Test the GetRASBounds & GetBounds method on a segmentation.
    """
        #self.delayDisplay("Starting test_Segmentation")
        cubeSource = vtk.vtkCubeSource()
        cubeSource.SetXLength(500)
        cubeSource.SetYLength(200)
        cubeSource.SetZLength(300)
        cubeSource.SetCenter(10, -85, 0.7)

        rotation = vtk.vtkTransform()
        rotation.RotateX(15.0)
        rotation.RotateZ(78)

        applyTransform = vtk.vtkTransformPolyDataFilter()
        applyTransform.SetTransform(rotation)
        applyTransform.SetInputConnection(cubeSource.GetOutputPort())
        applyTransform.Update()

        modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode())
        modelNode.SetPolyDataConnection(applyTransform.GetOutputPort())

        segmentationNode = slicer.mrmlScene.AddNode(
            slicer.vtkMRMLSegmentationNode())
        segmentationLogic = slicer.modules.segmentations.logic()
        segmentationLogic.ImportModelToSegmentationNode(
            modelNode, segmentationNode)

        # Testing
        bounds = range(6)
        segmentationNode.GetRASBounds(bounds)
        untransformedBounds = [
            -65.4164152220677, 237.23434621664234, -305.4495706784099,
            289.7072339384947, -217.46321203583187, 213.68731403607347
        ]
        self.assertListAlmostEquals(bounds, untransformedBounds)

        segmentationNode.GetBounds(bounds)
        self.assertListAlmostEquals(bounds, untransformedBounds)

        transform = vtk.vtkTransform()
        transform.Translate([-5.0, +42.0, -0.1])
        transform.RotateWXYZ(41, 0.7, 0.6, 75)
        transform.Scale(2, 3, 10)
        transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode())
        transformNode.ApplyTransform(transform)

        segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID())
        transformedBounds = [
            -690.2701685073098, 970.3186946284741, -744.3124542486084,
            1018.260811721817, -2183.4639807718822, 2144.107746300856
        ]
        segmentationNode.GetRASBounds(bounds)
        self.assertListAlmostEquals(bounds, transformedBounds)

        segmentationNode.GetBounds(bounds)
        self.assertListAlmostEquals(bounds, untransformedBounds)
  def TestSection_2_MergeLabelmapWithDifferentGeometries(self):
    # Merge labelmap when segments containing labelmaps with different geometries (both same directions, different directions)
    logging.info('Test section 2: Merge labelmap with different geometries')

    self.assertIsNotNone(self.sphereSegment)
    self.sphereSegment.RemoveRepresentation(self.binaryLabelmapReprName)
    self.assertIsNone(self.sphereSegment.GetRepresentation(self.binaryLabelmapReprName))

    # Create new segmentation with sphere segment
    self.secondSegmentationNode = slicer.vtkMRMLSegmentationNode()
    self.secondSegmentationNode.SetName('Second')
    self.secondSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    slicer.mrmlScene.AddNode(self.secondSegmentationNode)

    self.secondSegmentationNode.GetSegmentation().AddSegment(self.sphereSegment)

    # Check automatically converted labelmap. It is supposed to have the default geometry
    # (which is different than the one in the input segmentation)
    sphereLabelmap = self.sphereSegment.GetRepresentation(self.binaryLabelmapReprName)
    self.assertIsNotNone(sphereLabelmap)
    sphereLabelmapSpacing = sphereLabelmap.GetSpacing()
    self.assertTrue(sphereLabelmapSpacing[0] == 1.0 and sphereLabelmapSpacing[1] == 1.0 and sphereLabelmapSpacing[2] == 1.0)

    # Create binary labelmap in segmentation that will create the merged labelmap from
    # different geometries so that labelmap is not removed from sphere segment when adding
    self.inputSegmentationNode.GetSegmentation().CreateRepresentation(self.binaryLabelmapReprName)

    # Copy segment to input segmentation
    self.inputSegmentationNode.GetSegmentation().CopySegmentFromSegmentation(self.secondSegmentationNode.GetSegmentation(), self.sphereSegmentName)
    self.assertEqual(self.inputSegmentationNode.GetSegmentation().GetNumberOfSegments(), 3)

    # Check merged labelmap
    # Reference geometry has the tiny patient spacing, and it is oversampled to have smimilar
    # voxel size as the sphere labelmap with the uniform 1mm spacing
    mergedLabelmap = vtkSegmentationCore.vtkOrientedImageData()
    self.inputSegmentationNode.GenerateMergedLabelmapForAllSegments(mergedLabelmap, 0)
    mergedLabelmapSpacing = mergedLabelmap.GetSpacing()
    self.assertAlmostEqual(mergedLabelmapSpacing[0], 1.2894736842, 8)
    self.assertAlmostEqual(mergedLabelmapSpacing[1], 1.2894736842, 8)
    self.assertAlmostEqual(mergedLabelmapSpacing[2], 0.6052631578, 8)

    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(mergedLabelmap)
    imageStat.SetComponentExtent(0,5,0,0,0,0)
    imageStat.SetComponentOrigin(0,0,0)
    imageStat.SetComponentSpacing(1,1,1)
    imageStat.Update()
    self.assertEqual(imageStat.GetVoxelCount(), 54872000)
    imageStatResult = imageStat.GetOutput()
    for i in range(5):
      logging.info("Volume {0}: {1}".format(i, imageStatResult.GetScalarComponentAsDouble(i,0,0,0)))
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(0,0,0,0), 43573723)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(1,0,0,0), 10601312)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(2,0,0,0), 251476)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(3,0,0,0), 445489)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(4,0,0,0), 0)  # Built from color table and color four is removed in previous test section
Ejemplo n.º 13
0
    def setupNeedleAndSegModelNode(self):
        self.clearOldNodesByName(self.NEEDLE_NAME)
        self.setupFiducialWidgetAndTableWidget()
        self.setupSegmentationWidget()
        if self.needleModelNode is None:
            self.needleModelNode = ModuleLogicMixin.createModelNode(
                self.NEEDLE_NAME)
        if (self.needleModelNode.GetScene() is None) or (
                not self.needleModelNode.GetScene() == slicer.mrmlScene):
            slicer.mrmlScene.AddNode(self.needleModelNode)
        if self.needleModelNode.GetDisplayNode() is None:
            ModuleLogicMixin.createAndObserveDisplayNode(
                self.needleModelNode,
                displayNodeClass=slicer.vtkMRMLModelDisplayNode)
            self.needleModelNode.GetDisplayNode().SetColor(1.0, 0.0, 0.0)

        if self.affectedAreaModelNode is None:
            self.affectedAreaModelNode = ModuleLogicMixin.createModelNode(
                self.AFFECTEDAREA_NAME)
        if (self.affectedAreaModelNode.GetScene() is None) or (
                not self.affectedAreaModelNode.GetScene() == slicer.mrmlScene):
            slicer.mrmlScene.AddNode(self.affectedAreaModelNode)
        if self.affectedAreaModelNode.GetDisplayNode() is None:
            ModuleLogicMixin.createAndObserveDisplayNode(
                self.affectedAreaModelNode,
                displayNodeClass=slicer.vtkMRMLModelDisplayNode)
            self.affectedAreaModelNode.GetDisplayNode().SetOpacity(0.5)
            self.affectedAreaModelNode.GetDisplayNode().SetColor(0.0, 1.0, 0.0)

        if self.data.segmentModelNode is None:
            # Create segmentation
            self.data.segmentModelNode = slicer.vtkMRMLSegmentationNode()
            slicer.mrmlScene.AddNode(self.data.segmentModelNode)
            self.data.segmentModelNode.CreateDefaultDisplayNodes(
            )  # only needed for display
            self.data.segmentModelNode.CreateDefaultStorageNode()
            self.data.segmentModelNode.SetName("IntraOpSegmentation")
        if (self.data.segmentModelNode.GetScene() is None) or (
                not self.data.segmentModelNode.GetScene() == slicer.mrmlScene):
            slicer.mrmlScene.AddNode(self.data.segmentModelNode)
        if self.data.segmentModelNode.GetDisplayNode() is None:
            ModuleLogicMixin.createAndObserveDisplayNode(
                self.data.segmentModelNode,
                displayNodeClass=slicer.vtkMRMLSegmentationDisplayNode)
        if self.segmentEditorNode is None:
            self.segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
            slicer.mrmlScene.AddNode(self.segmentEditorNode)
        if (self.segmentEditorNode.GetScene() is None) or (
                not self.segmentEditorNode.GetScene() == slicer.mrmlScene):
            slicer.mrmlScene.AddNode(self.segmentEditorNode)
        self.segmentationEditor.setMRMLScene(slicer.mrmlScene)
        self.segmentationEditor.setMRMLSegmentEditorNode(
            self.segmentEditorNode)
        self.segmentationEditorMaskOverWriteCombox.setCurrentIndex(
            self.segmentationEditorMaskOverWriteCombox.findText('None'))
Ejemplo n.º 14
0
    def buildSegment(self,
                     inputVolme,
                     masterSegment=None,
                     segmentationNode=None,
                     name='airway'):
        if (segmentationNode == None):
            segmentationNode = slicer.vtkMRMLSegmentationNode()
            slicer.mrmlScene.AddNode(segmentationNode)
            segmentationNode.CreateDefaultDisplayNodes()

        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolme)
        segmentID = segmentationNode.GetSegmentation().AddEmptySegment(name)

        segmentationEditor = slicer.qMRMLSegmentEditorWidget()
        segmentationEditor.setMRMLScene(slicer.mrmlScene)
        segmentationEditor.setMRMLSegmentEditorNode(
            slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentEditorNode'))
        segmentationEditor.setSegmentationNode(segmentationNode)
        #//segmentationEditor.ad    & test &
        # ? What was this line supposed to be? I can't remember but it doesn't seem to be causing problems for now
        segmentationEditor.setMasterVolumeNode(inputVolme)

        #import qSlicerSegmentationEditorEffectsPythonQt as effects

        segmentationEditor.setActiveEffectByName('Threshold')
        effect = segmentationEditor.activeEffect()
        effect.setParameter('MinimumThreshold', '-1024')
        effect.setParameter('MaximumThreshold', AIR_DENSITY_THRESHOLD)
        effect.self().onApply()

        # FIXME: part of the fix for handling out of bounds air - currently broken
        #if masterSegment is not None:
        #segmentationEditor.setActiveEffectByName('Logical operators')
        #effect = segmentationEditor.activeEffect()
        #effect.setParameter('ModifierSegmentID', masterSegment.GetName())
        #effect.setParameter('Operation', 'INTERSECT')
        #effect.self().onApply()

        segmentationEditor.setActiveEffectByName('Islands')
        effect = segmentationEditor.activeEffect()
        effect.setParameter('KeepLargestIsland', True)
        effect.self().onApply()

        segmentationNode.CreateClosedSurfaceRepresentation()
        surfaceMesh = segmentationNode.GetClosedSurfaceRepresentation(
            segmentID)
        normals = vtk.vtkPolyDataNormals()
        normals.ConsistencyOn()
        normals.SetInputData(surfaceMesh)
        normals.Update()
        surfaceMesh = normals.GetOutput()

        return segmentationNode
  def test_Autoscroll(self):
    """
    Basic automated test of the segmentation method:
    - Create segmentation by placing sphere-shaped seeds
    - Run segmentation
    - Verify results using segment statistics
    The test can be executed from SelfTests module (test name: SegmentEditorAutoscroll)
    """

    self.delayDisplay("Starting test_Autoscroll")

    import vtkSegmentationCorePython as vtkSegmentationCore
    import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
    import SampleData
    from SegmentStatistics import SegmentStatisticsLogic

    ##################################
    self.delayDisplay("Load master volume")

    import SampleData
    sampleDataLogic = SampleData.SampleDataLogic()
    masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

    ##################################
    self.delayDisplay("Create segmentation with an empty segment")

    segmentationNode = slicer.vtkMRMLSegmentationNode()
    slicer.mrmlScene.AddNode(segmentationNode)
    segmentationNode.CreateDefaultDisplayNodes()
    segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)
    segment = vtkSegmentationCore.vtkSegment()
    segmentationNode.GetSegmentation().AddSegment(segment)

    ##################################
    self.delayDisplay("Create segment editor")

    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    segmentEditorWidget.show()
    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
    segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
    slicer.mrmlScene.AddNode(segmentEditorNode)
    segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
    segmentEditorWidget.setSegmentationNode(segmentationNode)
    segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

    ##################################
    self.delayDisplay("Run autoscroll for 10 seconds")
    segmentEditorWidget.setActiveEffectByName("Autoscroll")
    effect = segmentEditorWidget.activeEffect()

    qt.QTimer.singleShot(10000, effect.self().onApply)
    effect.self().onApply()
    self.delayDisplay('test_Autoscroll passed')
Ejemplo n.º 16
0
    def load_data_to_placeholders(self, subject_dir):
        self.image_root = subject_dir
        images = {
            'pre_T1_pre': 0,
            'pre_T1_EA': 1,
            'pre_T1_EA_sub': 2,
            'pre_T1_LA': 3,
            'pre_T1_LA_sub': 4,
            'pre_T1_PV': 5,
            'pre_T1_PV_sub': 6,
            'pre_ADC': 7,
            'post_T1_pre': 8,
            'post_T1_EA': 9,
            'post_T1_EA_sub': 10,
            'post_T1_LA': 11,
            'post_T1_LA_sub': 12,
            'post_T1_PV': 13,
            'post_T1_PV_sub': 14,
            'post_ADC': 15,
            'post_ADC_Eq_1': 16,
            'pre_ADC_Eq_1': 17
        }

        raws = list()
        labels = list()
        for i in os.listdir(subject_dir):
            file_name = i.lower()
            for j, count in images.items():
                if j.lower() + ".nii.gz" in file_name:
                    #print (j+" is found! Corresponding to filepath:"+str(i)+"And is given a count of "+str(count))
                    img = slicer.util.loadVolume(os.path.join(subject_dir, i),
                                                 returnNode=True)[1]
                    raws.append([img, count])
                if j.lower() + "_tumor_" + self.reader_name.lower(
                ) + ".nii.gz" in file_name:
                    #print (j+" is found! Corresponding to filepath:"+str(i)+"And is given a count of "+str(count))
                    print("Reader Name: " + self.reader_name)
                    load_success, ma_node = slicer.util.loadLabelVolume(
                        os.path.join(subject_dir, i), returnNode=True)
                    seg_node = slicer.vtkMRMLSegmentationNode()
                    slicer.mrmlScene.AddNode(seg_node)
                    load_success = slicer.modules.segmentations.logic(
                    ).ImportLabelmapToSegmentationNode(ma_node,
                                                       seg_node) & load_success
                    slicer.mrmlScene.RemoveNode(ma_node)
                    seg_node.SetName(j + "_segment")
                    segmentationDisplayNode = seg_node.GetDisplayNode()
                    segmentationDisplayNode.VisibilityOff()
                    labels.append([seg_node, count])
                    #print (seg_node,count)

        return raws, labels
    def OnSmoothLabelMapButtonClicked(self):
        # Get working polydata
        WorkingNodeName = self.WorkingLabelMapStorage.currentNode().GetName()
        if self.SegmentationNode.GetClosedSurfaceRepresentation(
                WorkingNodeName) == None:
            self.SegmentationNode.CreateClosedSurfaceRepresentation()

        WorkingPolyData = self.SegmentationNode.GetClosedSurfaceRepresentation(
            WorkingNodeName)

        # Smooth working polydata
        logic = UsSurfaceToLandmarksLogic()
        SmoothedPolyData = logic.SmoothPolyData(
            WorkingPolyData, self.SmoothingConvergenceSlider.value,
            self.SmoothingIterationsSlider.value)

        # Convert polydata to labelmap via segmentation and vtkmodel
        SmoothedModelNode = slicer.vtkMRMLModelNode()
        SmoothedModelNode.SetName(WorkingNodeName)
        SmoothedModelNode.SetAndObservePolyData(SmoothedPolyData)
        #SmoothedModelNode

        ConvSeg = slicer.vtkMRMLSegmentationNode()
        ConvSeg.SetScene(slicer.mrmlScene)
        SegLogic = slicer.modules.segmentations.logic()
        SegLogic.ImportModelToSegmentationNode(SmoothedModelNode, ConvSeg)
        ConvSeg.CreateBinaryLabelmapRepresentation()
        ConvSeg.SetMasterRepresentationToBinaryLabelmap()

        # Clear mrmlScene of old labelmap node before exporting the new one
        #OldLabelMapNode = self.WorkingLabelMapStorage.currentNode()
        #OldLabelMapNode = slicer.util.getNode(WorkingNodeName)
        #if OldLabelMapNode != None:
        #  slicer.mrmlScene.RemoveNode(OldLabelMapNode)

        # Export segmentation label map representation to mrml node for storage in interface
        SmoothedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        SmoothedLabelMapNode.SetName(WorkingNodeName + self.SmoothTag)

        LabelMapName = vtk.vtkStringArray()
        LabelMapName.InsertNextValue(WorkingNodeName)
        slicer.mrmlScene.AddNode(SmoothedLabelMapNode)
        SegLogic.ExportSegmentsToLabelmapNode(ConvSeg, LabelMapName,
                                              SmoothedLabelMapNode)
        #SmoothedLabelMapNode.SetOrigin(self.InputVolumeSelector.currentNode().GetOrigin())
        # Update working polydata in UI
        # Add new smoothed label map node to mrmlScene
        self.WorkingLabelMapStorage.setCurrentNode(SmoothedLabelMapNode)
        self.UpdateSegmentationNode()

        return True
Ejemplo n.º 18
0
  def test_Segmentation(self):
    """ Test the GetRASBounds & GetBounds method on a segmentation.
    """
    #self.delayDisplay("Starting test_Segmentation")
    cubeSource = vtk.vtkCubeSource()
    cubeSource.SetXLength(500)
    cubeSource.SetYLength(200)
    cubeSource.SetZLength(300)
    cubeSource.SetCenter(10, -85, 0.7)

    rotation = vtk.vtkTransform()
    rotation.RotateX(15.0)
    rotation.RotateZ(78)

    applyTransform = vtk.vtkTransformPolyDataFilter()
    applyTransform.SetTransform(rotation)
    applyTransform.SetInputConnection(cubeSource.GetOutputPort())
    applyTransform.Update()

    modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode())
    modelNode.SetPolyDataConnection(applyTransform.GetOutputPort())

    segmentationNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLSegmentationNode())
    segmentationLogic = slicer.modules.segmentations.logic()
    segmentationLogic.ImportModelToSegmentationNode(modelNode, segmentationNode)

    # Testing
    bounds = range(6)
    segmentationNode.GetRASBounds(bounds)
    untransformedBounds = [-65.0710220336914, 235.9289779663086, -304.413391113281, 288.586608886719, -216.427032470703, 213.572967529297]
    self.assertListAlmostEquals(bounds, untransformedBounds)

    segmentationNode.GetBounds(bounds)
    self.assertListAlmostEquals(bounds, untransformedBounds)

    transform = vtk.vtkTransform()
    transform.Translate([-5.0, +42.0, -0.1])
    transform.RotateWXYZ(41, 0.7, 0.6, 75)
    transform.Scale(2, 3, 10)
    transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode())
    transformNode.ApplyTransform(transform)

    segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID())
    transformedBounds = [-200.70776329131795, 479.54290966330126, -723.6172978253361, 996.0765602877555, -2171.2883672792996, 2141.1537548033725]
    segmentationNode.GetRASBounds(bounds)
    self.assertListAlmostEquals(bounds, transformedBounds)

    segmentationNode.GetBounds(bounds)
    self.assertListAlmostEquals(bounds, untransformedBounds)
Ejemplo n.º 19
0
  def test_Segmentation(self):
    """ Test the GetRASBounds & GetBounds method on a segmentation.
    """
    #self.delayDisplay("Starting test_Segmentation")
    cubeSource = vtk.vtkCubeSource()
    cubeSource.SetXLength(500)
    cubeSource.SetYLength(200)
    cubeSource.SetZLength(300)
    cubeSource.SetCenter(10, -85, 0.7)

    rotation = vtk.vtkTransform()
    rotation.RotateX(15.0)
    rotation.RotateZ(78)

    applyTransform = vtk.vtkTransformPolyDataFilter()
    applyTransform.SetTransform(rotation)
    applyTransform.SetInputConnection(cubeSource.GetOutputPort())
    applyTransform.Update()

    modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode())
    modelNode.SetPolyDataConnection(applyTransform.GetOutputPort())

    segmentationNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLSegmentationNode())
    segmentationLogic = slicer.modules.segmentations.logic()
    segmentationLogic.ImportModelToSegmentationNode(modelNode, segmentationNode)

    # Testing
    bounds = range(6)
    segmentationNode.GetRASBounds(bounds)
    untransformedBounds = [-65.4164152220677, 237.23434621664234, -305.4495706784099, 289.7072339384947, -217.46321203583187, 213.68731403607347]
    self.assertListAlmostEquals(bounds, untransformedBounds)

    segmentationNode.GetBounds(bounds)
    self.assertListAlmostEquals(bounds, untransformedBounds)

    transform = vtk.vtkTransform()
    transform.Translate([-5.0, +42.0, -0.1])
    transform.RotateWXYZ(41, 0.7, 0.6, 75)
    transform.Scale(2, 3, 10)
    transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode())
    transformNode.ApplyTransform(transform)

    segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID())
    transformedBounds = [-690.2701685073098, 970.3186946284741, -744.3124542486084, 1018.260811721817, -2183.4639807718822, 2144.107746300856]
    segmentationNode.GetRASBounds(bounds)
    self.assertListAlmostEquals(bounds, transformedBounds)

    segmentationNode.GetBounds(bounds)
    self.assertListAlmostEquals(bounds, untransformedBounds)
Ejemplo n.º 20
0
  def test_Segmentation(self):
    """ Test the GetRASBounds & GetBounds method on a segmentation.
    """
    #self.delayDisplay("Starting test_Segmentation")
    cubeSource = vtk.vtkCubeSource()
    cubeSource.SetXLength(500)
    cubeSource.SetYLength(200)
    cubeSource.SetZLength(300)
    cubeSource.SetCenter(10, -85, 0.7)

    rotation = vtk.vtkTransform()
    rotation.RotateX(15.0)
    rotation.RotateZ(78)

    applyTransform = vtk.vtkTransformPolyDataFilter()
    applyTransform.SetTransform(rotation)
    applyTransform.SetInputConnection(cubeSource.GetOutputPort())
    applyTransform.Update()

    modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode())
    modelNode.SetPolyDataConnection(applyTransform.GetOutputPort())

    segmentationNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLSegmentationNode())
    segmentationLogic = slicer.modules.segmentations.logic()
    segmentationLogic.ImportModelToSegmentationNode(modelNode, segmentationNode)

    # Testing
    bounds = range(6)
    segmentationNode.GetRASBounds(bounds)
    untransformedBounds = [-65.0710220336914, 235.9289779663086, -304.413391113281, 288.586608886719, -216.427032470703, 213.572967529297]
    self.assertListAlmostEquals(bounds, untransformedBounds)

    segmentationNode.GetBounds(bounds)
    self.assertListAlmostEquals(bounds, untransformedBounds)

    transform = vtk.vtkTransform()
    transform.Translate([-5.0, +42.0, -0.1])
    transform.RotateWXYZ(41, 0.7, 0.6, 75)
    transform.Scale(2, 3, 10)
    transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode())
    transformNode.ApplyTransform(transform)

    segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID())
    transformedBounds = [-687.4653523284665, 966.3004987004498, -741.50842882335, 1013.9676912857693, -2173.06971199151, 2142.935099515583]
    segmentationNode.GetRASBounds(bounds)
    self.assertListAlmostEquals(bounds, transformedBounds)

    segmentationNode.GetBounds(bounds)
    self.assertListAlmostEquals(bounds, untransformedBounds)
    def AddSegmentNode(self, modelNode, volumeLabel):
        #This function creates a segmentation from the output model (ie cropped breast models)
        # and computed the volume of the segmentation, this is done to ensure the volume is computed correctly

        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)

        displayNode = slicer.mrmlScene.GetNthNodeByClass(1, 'vtkMRMLScalarVolumeDisplayNode')
        if displayNode == None:
            displayNode = slicer.vtkMRMLScalarVolumeDisplayNode()

        segmentationNode.SetAndObserveDisplayNodeID(displayNode.GetID())
        segmentationNode.SetName("Model Segmentation Node")

        slicer.modules.segmentations.logic().ImportModelToSegmentationNode(modelNode, segmentationNode)
        segment = segmentationNode.GetSegmentation().GetNthSegment(0)
        segBinaryLabelName = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationBinaryLabelmapRepresentationName()
        segmentLabelmap = segment.GetRepresentation(segBinaryLabelName)
        # We need to know exactly the value of the segment voxels, apply threshold to make force the selected label value
        labelValue = 1
        backgroundValue = 0
        thresh = vtk.vtkImageThreshold()
        thresh.SetInputData(segmentLabelmap)
        thresh.ThresholdByLower(0)
        thresh.SetInValue(backgroundValue)
        thresh.SetOutValue(labelValue)
        thresh.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
        thresh.Update()

        #  Use binary labelmap as a stencil
        stencil = vtk.vtkImageToImageStencil()
        stencil.SetInputData(thresh.GetOutput())
        stencil.ThresholdByUpper(labelValue)
        stencil.Update()

        stat = vtk.vtkImageAccumulate()
        stat.SetInputData(thresh.GetOutput())
        stat.SetStencilData(stencil.GetOutput())
        stat.Update()

        # Add data to statistics list
        cubicMMPerVoxel = reduce(lambda x, y: x * y, segmentLabelmap.GetSpacing())
        ccPerCubicMM = 0.001
        stats = {}
        volume = round(stat.GetVoxelCount() * cubicMMPerVoxel * ccPerCubicMM, 0)
        volumeLabel.setText(volume)
        slicer.mrmlScene.RemoveNode(segmentationNode)
        return volume
Ejemplo n.º 22
0
    def enter(self):
        """Runs whenever the module is reopened
    """
        self.turnOffLightboxes()
        self.installShortcutKeys()

        # Set parameter set node if absent
        self.selectParameterNode()
        self.editor.updateWidgetFromMRML()

        # If no segmentation node exists then create one so that the user does not have to create one manually
        if not self.editor.segmentationNodeID():
            newSegmentationNode = slicer.vtkMRMLSegmentationNode()
            slicer.mrmlScene.AddNode(newSegmentationNode)
            self.editor.setSegmentationNode(newSegmentationNode)
            masterVolumeNodeID = self.getDefaultMasterVolumeNodeID()
            self.editor.setMasterVolumeNodeID(masterVolumeNodeID)
Ejemplo n.º 23
0
  def enter(self):
    """Runs whenever the module is reopened
    """
    self.turnOffLightboxes()
    self.installShortcutKeys()

    # Set parameter set node if absent
    self.selectParameterNode()
    self.editor.updateWidgetFromMRML()

    # If no segmentation node exists then create one so that the user does not have to create one manually
    if not self.editor.segmentationNodeID():
      newSegmentationNode = slicer.vtkMRMLSegmentationNode()
      slicer.mrmlScene.AddNode(newSegmentationNode)
      self.editor.setSegmentationNode(newSegmentationNode)
      masterVolumeNodeID = self.getDefaultMasterVolumeNodeID()
      self.editor.setMasterVolumeNodeID(masterVolumeNodeID)
Ejemplo n.º 24
0
    def importFiles(self, filePaths):

        for path in filePaths:
            # load each file
            pathPair = os.path.split(path)
            directory = pathPair[0]
            fileName = pathPair[1]

            self.testCaseDict[fileName] = MRMLUtility.loadMRMLNode(
                fileName, directory, fileName, 'LabelMap')
            if self.testCaseDict[fileName] is None:
                print 'ERROR: Failed to load ' + fileName + 'as a labelmap'
                # make sure each one is a labelmap
                continue

            # Create segmentation representations.
            self.segmentationDict[fileName] = MRMLUtility.createNewMRMLNode(
                fileName + '_allSegments', slicer.vtkMRMLSegmentationNode())
            slicer.modules.segmentations.logic(
            ).ImportLabelmapToSegmentationNode(self.testCaseDict[fileName],
                                               self.segmentationDict[fileName])
            t = self.segmentationDict[
                fileName].CreateClosedSurfaceRepresentation()
            if t == False:
                print 'ERROR: Failed to create closed surface representation'
                continue

            self.segmentationDict[fileName].SetDisplayVisibility(False)

            # find how many labels each file has..
            labelRange = self.testCaseDict[fileName].GetImageData(
            ).GetScalarRange()
            if self.labelRangeInCohort != (
                    -1, -1) and labelRange != self.labelRangeInCohort:
                print 'ERROR: Number of labels do not match in the cohort'
                return False

            self.labelRangeInCohort = labelRange

        print 'Cohort label range is: ' + str(self.labelRangeInCohort)
        # given labels, and current mode populate the structures slider
        self.labelRangeInCohort = (int(self.labelRangeInCohort[0]),
                                   int(self.labelRangeInCohort[1]))
        return True
Ejemplo n.º 25
0
def duplicateProbeNode(fidPairs, probeNode):
    #print("Copying: ", probeNode)
    numDuplicates = int(fidPairs)
    nodeIds = []
    #nodeIds.append(probeNode.GetID())
    if (numDuplicates > 0):
        for i in range(0, numDuplicates):

            mergedImage = vtk.vtkPolyData()
            probeNode.GetClosedSurfaceRepresentation(
                probeNode.GetSegmentation().GetNthSegmentID(0), mergedImage)

            segmentationNode = slicer.vtkMRMLSegmentationNode()
            slicer.mrmlScene.AddNode(segmentationNode)

            slicer.app.processEvents(
            )  #force update as occasionally the follow steps cause slicer to crash
            time.sleep(0.1)

            segmentationNode.CreateDefaultDisplayNodes(
            )  # only needed for display
            segmentationNode.AddSegmentFromClosedSurfaceRepresentation(
                mergedImage, "duplicate_node", [0, 1, 0])
            segmentationNode.GetSegmentation().CreateRepresentation(
                "Closed surface")
            segmentationNode.GetSegmentation().SetMasterRepresentationName(
                "Binary labelmap")

            segDisplayNode = probeNode.GetDisplayNode()
            segDisplayNode.SetOpacity(0.3)
            segDisplayNode = segmentationNode.GetDisplayNode()
            segDisplayNode.SetOpacity(0.3)

            slicer.app.processEvents()
            time.sleep(0.1)

            nodeIds.append(segmentationNode.GetID())  #CHANGED THIS
            seg_name = probeNode.GetName()
            new_seg_name = seg_name + "_" + str(i)
            segmentationNode.SetName(new_seg_name)

    #probeNode.GetSegmentation().CreateRepresentation("Binary labelmap")
    #probeNode.GetSegmentation().SetMasterRepresentationName("Binary labelmap")
    return nodeIds
    def OnDecimateLabelMapButtonClicked(self):
        # Get working polydata
        WorkingNodeName = self.WorkingLabelMapStorage.currentNode().GetName()
        if self.SegmentationNode.GetClosedSurfaceRepresentation(
                WorkingNodeName) == None:
            self.SegmentationNode.CreateClosedSurfaceRepresentation()
        WorkingPolyData = self.SegmentationNode.GetClosedSurfaceRepresentation(
            WorkingNodeName)

        # Decimate working polydata
        logic = UsSurfaceToLandmarksLogic()
        DecimatedPolyData = logic.DecimatePolyData(WorkingPolyData)

        # Convert polydata to labelmap via segmentation and vtkmodel
        DecimatedModelNode = slicer.vtkMRMLModelNode()
        DecimatedModelNode.SetName(WorkingNodeName)
        DecimatedModelNode.SetAndObservePolyData(DecimatedPolyData)

        ConvSeg = slicer.vtkMRMLSegmentationNode()
        ConvSeg.SetScene(slicer.mrmlScene)
        SegLogic = slicer.modules.segmentations.logic()
        SegLogic.ImportModelToSegmentationNode(DecimatedModelNode, ConvSeg)
        ConvSeg.CreateBinaryLabelmapRepresentation()
        ConvSeg.SetMasterRepresentationToBinaryLabelmap()

        LabelMapName = vtk.vtkStringArray()
        LabelMapName.InsertNextValue(WorkingNodeName)

        DecimatedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        DecimatedLabelMapNode.SetName(WorkingNodeName)
        slicer.mrmlScene.AddNode(DecimatedLabelMapNode)

        SegLogic.ExportSegmentsToLabelmapNode(ConvSeg, LabelMapName,
                                              DecimatedLabelMapNode)
        #SmoothedOrientedImageData = ConvSeg.GetBinaryLabelmapRepresentation(WorkingNodeName)
        #DecimatedLabelMapNode.SetAndObserveImageData(SmoothedOrientedImageData)
        # Update working polydata in UI
        self.WorkingLabelMapStorage.setCurrentNode(DecimatedLabelMapNode)
        self.UpdateSegmentationNode()

        return True
    def OnRemoveIslandsButtonClicked(self):
        logic = UsSurfaceToLandmarksLogic()
        WorkingLabelMap = self.WorkingLabelMapStorage.currentNode()
        WorkingImageData = WorkingLabelMap.GetImageData()

        # Clear mrmlScene of old labelmap node before exporting the new one
        OldLabelMapNode = self.WorkingLabelMapStorage.currentNode()
        if OldLabelMapNode != None:
            slicer.mrmlScene.RemoveNode(OldLabelMapNode)

        print "DEBUG - About to remove islands"

        LabelMapIslandsRemoved = logic.RemoveCoronalIslands(
            WorkingImageData, self.IslandSizeThresholdSlider.value)
        LabelMapIslandsRemoved.SetName(WorkingLabelMap.GetName())
        print "DEBUG - Islands removed"

        ConvSeg = slicer.vtkMRMLSegmentationNode()
        ConvSeg.SetScene(slicer.mrmlScene)
        SegLogic = slicer.modules.segmentations.logic()
        SegLogic.ImportLabelmapToSegmentationNode(LabelMapIslandsRemoved,
                                                  ConvSeg)
        ConvSeg.CreateBinaryLabelmapRepresentation()
        ConvSeg.SetMasterRepresentationToBinaryLabelmap()

        LabelMapName = vtk.vtkStringArray()
        LabelMapName.InsertNextValue(WorkingLabelMap.GetName())
        DeislandedLabelMapNode = slicer.vtkMRMLLabelMapVolumeNode()
        DeislandedLabelMapNode.SetName(WorkingLabelMap.GetName())
        slicer.mrmlScene.AddNode(DeislandedLabelMapNode)
        SegLogic.ExportSegmentsToLabelmapNode(ConvSeg, LabelMapName,
                                              DeislandedLabelMapNode)

        # Update mrmlScene and UI
        #slicer.mrmlScene.AddNode(LabelMapIslandsRemoved)
        self.WorkingLabelMapStorage.setCurrentNode(DeislandedLabelMapNode)
        self.UpdateSegmentationNode()

        return True
Ejemplo n.º 28
0
  def enter(self):
    """Runs whenever the module is reopened
    """
    if self.editor.turnOffLightboxes():
      slicer.util.warningDisplay('Segment Editor is not compatible with slice viewers in light box mode.'
        'Views are being reset.', windowTitle='Segment Editor')

    # Allow switching between effects and selected segment using keyboard shortcuts
    self.editor.installKeyboardShortcuts()

    # Set parameter set node if absent
    self.selectParameterNode()
    self.editor.updateWidgetFromMRML()

    # If no segmentation node exists then create one so that the user does not have to create one manually
    if not self.editor.segmentationNodeID():
      segmentationNode = slicer.mrmlScene.GetFirstNode(None, "vtkMRMLSegmentationNode")
      if not segmentationNode:
        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
      self.editor.setSegmentationNode(segmentationNode)
      if not self.editor.masterVolumeNodeID():
        masterVolumeNodeID = self.getDefaultMasterVolumeNodeID()
        self.editor.setMasterVolumeNodeID(masterVolumeNodeID)
Ejemplo n.º 29
0
    def generateMask(self):
        #masterVolumeNode = slicer.util.getNode('1*')
        try:
            slicer.mrmlScene.RemoveNode(slicer.util.getNode("*masked"))
        except slicer.util.MRMLNodeNotFoundException:
            pass
        try:
            slicer.mrmlScene.RemoveNode(slicer.util.getNode("*masked*"))
        except slicer.util.MRMLNodeNotFoundException:
            pass
        # Create segmentation if mesh objects are present/selected
        if not self.selectedModelsList == []:
            for model in self.selectedModelsList:
                if model.currentNode() is not None:

                    try:
                        masterVolumeNode = slicer.util.getNode("*masked")
                    except slicer.util.MRMLNodeNotFoundException:
                        masterVolumeNode = slicer.util.getNode('1*')
                    try:
                        masterVolumeNode = slicer.util.getNode("*masked*")
                    except slicer.util.MRMLNodeNotFoundException:
                        masterVolumeNode = slicer.util.getNode('1*')

                    segmentationNode = slicer.vtkMRMLSegmentationNode()
                    slicer.mrmlScene.AddNode(segmentationNode)
                    #segmentationNode.CreateDefaultDisplayNodes() # only needed for display

                    slicer.vtkSlicerSegmentationsModuleLogic.ImportModelToSegmentationNode(
                        model.currentNode(), segmentationNode)
                    segmentationNode.CreateBinaryLabelmapRepresentation()

                    # Create segment editor to get access to effects
                    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
                    # To show segment editor widget (useful for debugging): segmentEditorWidget.show()
                    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
                    segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
                    slicer.mrmlScene.AddNode(segmentEditorNode)
                    segmentEditorWidget.setMRMLSegmentEditorNode(
                        segmentEditorNode)
                    segmentEditorWidget.setSegmentationNode(segmentationNode)
                    segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

                    # Set up masking parameters
                    segmentEditorWidget.setActiveEffectByName("Mask volume")
                    effect = segmentEditorWidget.activeEffect()
                    # set fill value to be outside the valid intensity range
                    effect.setParameter("FillValue", str(20000))
                    # Blank out voxels that are outside the segment
                    effect.setParameter("Operation", "FILL_INSIDE")
                    for segmentIndex in range(segmentationNode.GetSegmentation(
                    ).GetNumberOfSegments()):
                        # Set active segment
                        segmentID = segmentationNode.GetSegmentation(
                        ).GetNthSegmentID(segmentIndex)
                        segmentEditorWidget.setCurrentSegmentID(segmentID)
                        # Apply mask
                        effect.self().onApply()

                    if "masked" in masterVolumeNode.GetName():
                        slicer.mrmlScene.RemoveNode(masterVolumeNode)
    def test_Engrave1(self):
        """
    Basic automated test of the segmentation method:
    - Create segmentation by placing fiducials around tumor
    - Apply
    - Verify results using segment statistics
    The test can be executed from SelfTests module (test name: SegmentEditorEngrave)
    """

        self.delayDisplay("Starting test_Engrave1")

        ##################################
        self.delayDisplay("Load master volume")

        import SampleData
        sampleDataLogic = SampleData.SampleDataLogic()
        masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

        ##################################
        self.delayDisplay("Create tumor segmentation")

        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            masterVolumeNode)

        segmentName = "Tumor"
        import vtkSegmentationCorePython as vtkSegmentationCore

        segment = vtkSegmentationCore.vtkSegment()
        segment.SetName(
            segmentationNode.GetSegmentation().GenerateUniqueSegmentID(
                segmentName))
        segmentationNode.GetSegmentation().AddSegment(segment)

        ##################################
        self.delayDisplay("Create segment editor")

        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.show()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

        ##################################
        self.delayDisplay("Run segmentation")

        segmentEditorWidget.setActiveEffectByName("ENgrave")
        effect = segmentEditorWidget.activeEffect()

        # effect.self().fiducialPlacementToggle.placeButton().click()

        # points =[[2.589283578714074, 44.60536690073953, 27.299999999999997], [8.515228351086698, 35.22262101114956, 27.299999999999997],
        #          [13.700430026912741, 25.099132025013006, 27.299999999999997], [5.799170330415919, 19.17318725264039, 27.299999999999997],
        #          [2.589283578714074, 9.296612632019361, 27.299999999999997], [-10.250263428093263, 12.25958501820567, 27.299999999999997],
        #          [-16.17620820046588, 18.185529790578286, 27.299999999999997], [-20.373752414229813, 27.568275680168263, 27.299999999999997],
        #          [-15.929293834950343, 38.679422128366916, 27.299999999999997], [-11.484835255670887, 44.11153816970849, 27.299999999999997],
        #          [6.539913426962492, 33.49422045254088, 31.499999999999993], [1.354711751136449, 42.383137611099805, 31.499999999999993],
        #          [-8.768777235000101, 44.35845253522401, 31.499999999999993], [-14.200893276341674, 36.70410720424271, 31.499999999999993],
        #          [-18.398437490105607, 27.07444694913721, 31.499999999999993], [-12.719407083248512, 16.704043597485132, 31.499999999999993],
        #          [-7.534205407422476, 11.765756287174618, 31.499999999999993], [0.12013992355882408, 12.25958501820567, 31.499999999999993],
        #          [5.799170330415919, 16.21021486645408, 31.499999999999993], [8.268313985571176, 21.642330907795646, 31.499999999999993],
        #          [13.947344392428263, 26.827532583621682, 31.499999999999993], [-3.0897468281430065, 32.50656299047878, 45.49999999999998],
        #          [2.589283578714074, 27.32136131465274, 45.49999999999998], [-5.3119761177827485, 21.642330907795646, 45.49999999999998],
        #          [-8.02803413845352, 27.32136131465274, 45.49999999999998], [-14.694722007372718, 30.778162431870093, 38.499999999999986],
        #          [-8.02803413845352, 12.01267065269014, 38.499999999999986], [-3.583575559174065, 39.66707959042902, 11.900000000000007],
        #          [3.576941040776184, 31.765819893932196, 11.900000000000007], [0.12013992355882408, 20.901587811249065, 11.900000000000007],
        #          [-9.26260596603116, 28.555933142230366, 11.900000000000007], [6.046084695931441, 38.432507762851394, 17.500000000000007],
        #          [-17.163865662527982, 33.7411348180564, 17.500000000000007], [-14.200893276341674, 21.889245273311168, 17.500000000000007]]

        # for p in points:
        #   effect.self().segmentMarkupNode.AddControlPoint(p)

        # effect.self().onApply()

        # ##################################
        # self.delayDisplay("Make segmentation results nicely visible in 3D")
        # segmentationDisplayNode = segmentationNode.GetDisplayNode()
        # segmentationDisplayNode.SetSegmentVisibility(segmentName, True)
        # slicer.util.findChild(segmentEditorWidget, "Show3DButton").checked = True
        # segmentationDisplayNode.SetSegmentOpacity3D("Background",0.5)

        # ##################################
        # self.delayDisplay("Compute statistics")

        # from SegmentStatistics import SegmentStatisticsLogic

        # segStatLogic = SegmentStatisticsLogic()

        # segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
        # segStatLogic.getParameterNode().SetParameter("ScalarVolume", masterVolumeNode.GetID())
        # segStatLogic.getParameterNode().SetParameter("visibleSegmentsOnly", "False")

        # segStatLogic.computeStatistics()

        # # Export results to table (just to see all results)
        # resultsTableNode = slicer.vtkMRMLTableNode()
        # slicer.mrmlScene.AddNode(resultsTableNode)
        # segStatLogic.exportToTable(resultsTableNode)
        # segStatLogic.showTable(resultsTableNode)

        # self.delayDisplay("Check a few numerical results")

        # stats = segStatLogic.getStatistics()
        # self.assertEqual( round(stats['Tumor', 'LabelmapSegmentStatisticsPlugin.volume_mm3']), 19498.0)

        self.delayDisplay('test_Engrave1 passed')
    def test_SegmentEditorFloodFilling1(self):
        """
    Basic automated test of the segmentation method:
    - Create segmentation by placing sphere-shaped seeds
    - Run segmentation
    - Verify results using segment statistics
    The test can be executed from SelfTests module (test name: SegmentEditorFloodFilling)
    """

        self.delayDisplay("Starting test_SegmentEditorFloodFilling1")

        import vtkSegmentationCorePython as vtkSegmentationCore
        import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
        import SampleData
        from SegmentStatistics import SegmentStatisticsLogic

        ##################################
        self.delayDisplay("Load master volume")

        import SampleData
        sampleDataLogic = SampleData.SampleDataLogic()
        masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

        ##################################
        self.delayDisplay("Create segmentation containing a few spheres")

        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            masterVolumeNode)

        # Segments are defined by a list of: name and a list of sphere [radius, posX, posY, posZ]
        segmentGeometries = [['Tumor', [[10, -6, 30, 28]]],
                             [
                                 'Background',
                                 [[10, 0, 65, 22], [15, 1, -14, 30],
                                  [12, 0, 28, -7], [5, 0, 30, 54],
                                  [12, 31, 33, 27], [17, -42, 30, 27],
                                  [6, -2, -17, 71]]
                             ], ['Air', [[10, 76, 73, 0], [15, -70, 74, 0]]]]
        for segmentGeometry in segmentGeometries:
            segmentName = segmentGeometry[0]
            appender = vtk.vtkAppendPolyData()
            for sphere in segmentGeometry[1]:
                sphereSource = vtk.vtkSphereSource()
                sphereSource.SetRadius(sphere[0])
                sphereSource.SetCenter(sphere[1], sphere[2], sphere[3])
                appender.AddInputConnection(sphereSource.GetOutputPort())
            segment = vtkSegmentationCore.vtkSegment()
            segment.SetName(
                segmentationNode.GetSegmentation().GenerateUniqueSegmentID(
                    segmentName))
            appender.Update()
            segment.AddRepresentation(
                vtkSegmentationCore.vtkSegmentationConverter.
                GetSegmentationClosedSurfaceRepresentationName(),
                appender.GetOutput())
            segmentationNode.GetSegmentation().AddSegment(segment)

        ##################################
        self.delayDisplay("Create segment editor")

        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.show()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

        ##################################
        self.delayDisplay("Run segmentation")
        segmentEditorWidget.setActiveEffectByName("SegmentEditorFloodFilling")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("ObjectScaleMm", 3.0)
        effect.self().onApply()

        ##################################
        self.delayDisplay("Make segmentation results nicely visible in 3D")
        segmentationDisplayNode = segmentationNode.GetDisplayNode()
        segmentationDisplayNode.SetSegmentVisibility("Air", False)
        segmentationDisplayNode.SetSegmentOpacity3D("Background", 0.5)

        ##################################
        self.delayDisplay("Compute statistics")

        segStatLogic = SegmentStatisticsLogic()
        segStatLogic.computeStatistics(segmentationNode, masterVolumeNode)

        # Export results to table (just to see all results)
        resultsTableNode = slicer.vtkMRMLTableNode()
        slicer.mrmlScene.AddNode(resultsTableNode)
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)

        self.delayDisplay("Check a few numerical results")
        self.assertEqual(
            round(segStatLogic.statistics["Tumor", "LM volume cc"]), 16)
        self.assertEqual(
            round(segStatLogic.statistics["Background", "LM volume cc"]), 3010)

        self.delayDisplay('test_SegmentEditorFloodFilling1 passed')
Ejemplo n.º 32
0
    def run(self, inputVolume, Index):

        logging.info('Processing started')

        DosiFilmImage = inputVolume

        logging.info(DosiFilmImage)
        date = datetime.datetime.now()
        savepath = u"//s-grp/grp/RADIOPHY/Personnel/Aurélien Corroyer-Dulmont/3dSlicer/Field_Center_vs_Jaw_setting_TOMOTHERAPY_QC_Results/Results_" + str(
            date.day) + str(date.month) + str(date.year) + ".txt"

        logging.info(savepath)
        logging.info(Index)

        #### To get background intensity for the thershold value of the bloc
        # Create segmentation
        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            DosiFilmImage)

        # Create segment
        backgroundSeed = vtk.vtkSphereSource()
        backgroundSeed.SetCenter(-40, -30, 0)
        backgroundSeed.SetRadius(5)
        backgroundSeed.Update()
        segmentationNode.AddSegmentFromClosedSurfaceRepresentation(
            backgroundSeed.GetOutput(), "Segment A", [1.0, 0.0, 0.0])

        mergedLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
        slicer.mrmlScene.AddNode(mergedLabelmapNode)
        sa = vtk.vtkStringArray()
        sa.InsertNextValue("Segment A")
        slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentsToLabelmapNode(
            segmentationNode, sa, mergedLabelmapNode, DosiFilmImage)

        label = su.PullVolumeFromSlicer("LabelMapVolume")
        image = su.PullVolumeFromSlicer(DosiFilmImage)
        stat_filter_backgroundSeed = sitk.LabelIntensityStatisticsImageFilter()
        stat_filter_backgroundSeed.Execute(label, image)  #attention à l'ordre
        meanBackground = stat_filter_backgroundSeed.GetMean(1)
        print(meanBackground)

        # Stockage du nom de la machine en utilisant le choix de l'utilisateur dans la class Widget
        if Index == 0:
            machineName = 'Tomotherapy 1'
        else:
            machineName = 'Tomotherapy 2'

        # Création de la segmentation
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            DosiFilmImage)

        logging.info(segmentationNode)

        # Création des segments editors temporaires
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(DosiFilmImage)

        # Création d'un segment après seuillage
        addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(
            "IrradiatedBlocks")
        segmentEditorNode.SetSelectedSegmentID(addedSegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        #effect.setParameter("MinimumThreshold",str(22000))
        #effect.setParameter("MaximumThreshold",str(55000))
        effect.setParameter("MinimumThreshold", str(meanBackground / 5))
        effect.setParameter("MaximumThreshold", str(meanBackground / 1.2))
        effect.self().onApply()

        # Passage en mode closed surface pour calcul des centres
        n = slicer.util.getNode('Segmentation_1')
        s = n.GetSegmentation()
        ss = s.GetSegment('IrradiatedBlocks')
        ss.AddRepresentation('Closed surface', vtk.vtkPolyData())

        # Division du segment en plusieurs segments (un par bloc d'irradiation)
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", str("SPLIT_ISLANDS_TO_SEGMENTS"))
        effect.setParameter("MinimumSize", 1000)
        effect.self().onApply()

        ######### Initialisation des variables fixes d'intérêt###########
        Segmentation_Name = 'Segmentation_1'
        Segment_Name = [
            "IrradiatedBlocks", "IrradiatedBlocks -_1", "IrradiatedBlocks -_2",
            "IrradiatedBlocks -_3", "IrradiatedBlocks -_4",
            "IrradiatedBlocks -_5", "IrradiatedBlocks -_6"
        ]
        ListYaxisCenterOfBlock = [
            0, 0, 0, 0, 0, 0, 0
        ]  # initialisation de la liste contenant les valeurs Y centrales des blocs

        # Boucle de calcul des centres pour les 7 blocs (segment)
        i = 0
        while i < len(Segment_Name):
            n = slicer.util.getNode(Segmentation_Name)
            s = n.GetSegmentation()
            ss = s.GetSegment(Segment_Name[i])
            pd = ss.GetRepresentation('Closed surface')
            com = vtk.vtkCenterOfMass()
            com.SetInputData(pd)
            com.Update()
            com.GetCenter()  # A voir mais je pense que cette ligne est inutile
            CenterOfBlock = com.GetCenter(
            )  # CenterOfBlock est alors un tuple avec plusieurs variables (coordonées x,y,z)
            YaxisCenterOfBlock = (
                CenterOfBlock[1]
            )  # Sélection de la 2ème valeur du tuple (indice 1) qui est la valeur dans l'axe Y qui est l'unique valeure d'intérêt
            YaxisCenterOfBlock = abs(
                YaxisCenterOfBlock)  # On passe en valeur absolue
            ListYaxisCenterOfBlock[i] = YaxisCenterOfBlock
            i += 1

        logging.info(ListYaxisCenterOfBlock)

        ######### Calcul de la différence en Y entre les centres des différents blocs###########
        MaxYaxisCenter = max(ListYaxisCenterOfBlock)
        MinYaxisCenter = min(ListYaxisCenterOfBlock)
        DifferenceMaxInPixelYCenters = MaxYaxisCenter - MinYaxisCenter
        DifferenceMaxInMmYCenters = float(DifferenceMaxInPixelYCenters)
        DifferenceMaxInMmYCenters = DifferenceMaxInMmYCenters * 0.3528  # Pas élégant mais si je ne fais pas ça, il initialise DifferenceMaxInMmYCenters en tuple et pas en variable...

        ### Enonciation des résultats ###
        logging.info("Coordonnee Max en Y : " + str(MaxYaxisCenter))
        logging.info("Coordonnee Min en Y : " + str(MinYaxisCenter))
        logging.info("Difference maximale entre les blocs (en pixel) : " +
                     str(DifferenceMaxInPixelYCenters))
        logging.info("Difference maximale entre les blocs (en mm) : " +
                     str(DifferenceMaxInMmYCenters))

        ######### Création et remplissage fichier text pour stocker les résultats###########
        file = open(savepath, 'w')

        ### encodage du fichier pour écriture incluant les "é" ###
        file = codecs.open(savepath, encoding='utf-8')
        txt = file.read()
        file = codecs.open(savepath, "w", encoding='mbcs')

        date = datetime.datetime.now()
        file.write(u"Résultats test -Field Center vs Jaw setting-")
        file.write("\n\n")
        file.write("Machine : " + str(machineName))
        file.write("\n\n")
        file.write("Date : " + str(date.day) + "/" + str(date.month) + "/" +
                   str(date.year))
        file.write("\n\n")
        file.write("\n\n")
        i = 0

        for i in range(
                len(ListYaxisCenterOfBlock)
        ):  # Boucle pour obtenir les coordonées Y des centres des 7 blocs
            file.write(u"Coordonnée Y du centre du bloc n°" + str(i + 1) +
                       ": ")
            file.write(str(ListYaxisCenterOfBlock[i]))
            file.write("\n\n")

        file.write("\n\n")
        file.write(u"Coordonnée Max en Y : " + str(MaxYaxisCenter))
        file.write("\n\n")
        file.write(u"Coordonnée Min en Y : " + str(MinYaxisCenter))
        file.write("\n\n")
        file.write(u"Différence maximale entre les blocs (en pixel) : " +
                   str(DifferenceMaxInPixelYCenters))
        file.write("\n\n")
        file.write(u"Différence maximale entre les blocs (en mm) : " +
                   str(DifferenceMaxInMmYCenters))

        ######### Calcul de la conformité et mention dans le fichier résultats###########
        if 0 <= DifferenceMaxInMmYCenters < 0.5:
            Result = "Conforme"
        elif DifferenceMaxInMmYCenters > 0.5:
            Result = "Hors tolerance"
        else:
            Result = "Limite"  #car si pas < ou > à 0.5 alors = à 0.5

        if DifferenceMaxInMmYCenters < 0:
            logging.info(
                u"Valeur de la différence négative, problème dans l'image ou dans le programme, contactez Aurélien Corroyer-Dulmont tel : 5768"
            )

        logging.info(Result)

        file.write("\n\n")
        file.write("\n\n")
        file.write(u"Résultat : " + str(Result))
        file.close()

        logging.info('Processing completed')
        logging.info('\n\nResults are in the following file : ' + savepath)
        return True
Ejemplo n.º 33
0
  def TestSection_2_qMRMLSegmentationGeometryWidget(self):
    logging.info('Test section 2: qMRMLSegmentationGeometryWidget')

    import vtkSegmentationCore
    binaryLabelmapReprName = vtkSegmentationCore.vtkSegmentationConverter.GetBinaryLabelmapRepresentationName()
    closedSurfaceReprName = vtkSegmentationCore.vtkSegmentationConverter.GetClosedSurfaceRepresentationName()

    # Use MRHead and Tinypatient for testing
    import SampleData
    sampleDataLogic = SampleData.SampleDataLogic()
    mrVolumeNode = sampleDataLogic.downloadMRHead()
    [tinyVolumeNode, tinySegmentationNode] = sampleDataLogic.downloadSample('TinyPatient')

    # Convert MRHead to oriented image data
    import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
    mrOrientedImageData = vtkSlicerSegmentationsModuleLogic.vtkSlicerSegmentationsModuleLogic.CreateOrientedImageDataFromVolumeNode(mrVolumeNode)
    mrOrientedImageData.UnRegister(None)

    # Create segmentation node with binary labelmap master and one segment with MRHead geometry
    segmentationNode = slicer.vtkMRMLSegmentationNode()
    segmentationNode.GetSegmentation().SetMasterRepresentationName(binaryLabelmapReprName)
    geometryStr = vtkSegmentationCore.vtkSegmentationConverter.SerializeImageGeometry(mrOrientedImageData)
    segmentationNode.GetSegmentation().SetConversionParameter(
      vtkSegmentationCore.vtkSegmentationConverter.GetReferenceImageGeometryParameterName(), geometryStr)
    slicer.mrmlScene.AddNode(segmentationNode)
    threshold = vtk.vtkImageThreshold()
    threshold.SetInputData(mrOrientedImageData)
    threshold.ThresholdByUpper(16.0)
    threshold.SetInValue(1)
    threshold.SetOutValue(0)
    threshold.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
    threshold.Update()
    segmentOrientedImageData = vtkSegmentationCore.vtkOrientedImageData()
    segmentOrientedImageData.DeepCopy(threshold.GetOutput())
    mrImageToWorldMatrix = vtk.vtkMatrix4x4()
    mrOrientedImageData.GetImageToWorldMatrix(mrImageToWorldMatrix)
    segmentOrientedImageData.SetImageToWorldMatrix(mrImageToWorldMatrix)
    segment = vtkSegmentationCore.vtkSegment()
    segment.SetName('Brain')
    segment.SetColor(0.0,0.0,1.0)
    segment.AddRepresentation(binaryLabelmapReprName, segmentOrientedImageData)
    segmentationNode.GetSegmentation().AddSegment(segment)

    # Create geometry widget
    geometryWidget = slicer.qMRMLSegmentationGeometryWidget()
    geometryWidget.setSegmentationNode(segmentationNode)
    geometryWidget.editEnabled = True
    geometryImageData = vtkSegmentationCore.vtkOrientedImageData() # To contain the output later

    # Volume source with no transforms
    geometryWidget.setSourceNode(tinyVolumeNode)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (49,49,23), (248.8439, 248.2890, -123.75),
        [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 92)

    # Transformed volume source
    translationTransformMatrix = vtk.vtkMatrix4x4()
    translationTransformMatrix.SetElement(0,3,24.5)
    translationTransformMatrix.SetElement(1,3,24.5)
    translationTransformMatrix.SetElement(2,3,11.5)
    translationTransformNode = slicer.vtkMRMLLinearTransformNode()
    translationTransformNode.SetName('TestTranslation')
    slicer.mrmlScene.AddNode(translationTransformNode)
    translationTransformNode.SetMatrixTransformToParent(translationTransformMatrix)

    tinyVolumeNode.SetAndObserveTransformNodeID(translationTransformNode.GetID())
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (49,49,23), (224.3439, 223.7890, -135.25),
        [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 94)

    # Volume source with isotropic spacing
    tinyVolumeNode.SetAndObserveTransformNodeID(None)
    geometryWidget.setIsotropicSpacing(True)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (23,23,23), (248.8439, 248.2890, -123.75),
        [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 414)

    # Volume source with oversampling
    geometryWidget.setIsotropicSpacing(False)
    geometryWidget.setOversamplingFactor(2.0)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (24.5, 24.5, 11.5), (261.0939, 260.5390, -129.5),
        [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 751)
    slicer.util.delayDisplay('Volume source cases - OK')

    # Segmentation source with binary labelmap master
    geometryWidget.setOversamplingFactor(1.0)
    geometryWidget.setSourceNode(tinySegmentationNode)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (49,49,23), (248.8439, 248.2890, -123.75),
        [[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 92)

    # Segmentation source with closed surface master
    tinySegmentationNode.GetSegmentation().SetConversionParameter('Smoothing factor', '0.0')
    self.assertTrue(tinySegmentationNode.GetSegmentation().CreateRepresentation(closedSurfaceReprName))
    tinySegmentationNode.GetSegmentation().SetMasterRepresentationName(closedSurfaceReprName)
    tinySegmentationNode.Modified() # Trigger re-calculation of geometry (only generic Modified event is observed)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (1,1,1), (-167.156, -217.711, -135.75),
        [[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5223846)
    slicer.util.delayDisplay('Segmentation source cases - OK')

    # Model source with no transform
    outputModelHierarchy = slicer.vtkMRMLModelHierarchyNode()
    slicer.mrmlScene.AddNode(outputModelHierarchy)
    success = vtkSlicerSegmentationsModuleLogic.vtkSlicerSegmentationsModuleLogic.ExportVisibleSegmentsToModelHierarchy(
      tinySegmentationNode, outputModelHierarchy )
    self.assertTrue(success)
    modelNode = slicer.util.getNode('Body_Contour')
    geometryWidget.setSourceNode(modelNode)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (1,1,1), (-167.156, -217.711, -135.75),
        [[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5223846)

    # Transformed model source
    rotationTransform = vtk.vtkTransform()
    rotationTransform.RotateX(45)
    rotationTransformMatrix = vtk.vtkMatrix4x4()
    rotationTransform.GetMatrix(rotationTransformMatrix)
    rotationTransformNode = slicer.vtkMRMLLinearTransformNode()
    rotationTransformNode.SetName('TestRotation')
    slicer.mrmlScene.AddNode(rotationTransformNode)
    rotationTransformNode.SetMatrixTransformToParent(rotationTransformMatrix)

    modelNode.SetAndObserveTransformNodeID(rotationTransformNode.GetID())
    modelNode.Modified()
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (1,1,1), (-167.156, -58.6623, -249.228),
        [[0.0, 0.0, 1.0], [-0.7071, -0.7071, 0.0], [0.7071, -0.7071, 0.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5221241)

    # ROI source
    roiNode = slicer.vtkMRMLAnnotationROINode()
    roiNode.SetName('SourceROI')
    slicer.mrmlScene.AddNode(roiNode)
    roiNode.UnRegister(None)
    xyz = [0]*3
    center = [0]*3
    slicer.vtkMRMLSliceLogic.GetVolumeRASBox(tinyVolumeNode, xyz, center)
    radius = map(lambda x: x/2.0, xyz)
    roiNode.SetXYZ(center)
    roiNode.SetRadiusXYZ(radius)
    geometryWidget.setSourceNode(roiNode)
    geometryWidget.geometryImageData(geometryImageData)
    self.assertTrue(self.compareOutputGeometry(geometryImageData,
        (1,1,1), (-216.156, -217.711, -135.75),
        [[0.0, 0.0, 1.0], [-1.0, 0.0, 0.0], [0.0, -1.0, 0.0]]))
    vtkSegmentationCore.vtkOrientedImageDataResample.ResampleOrientedImageToReferenceOrientedImage(
      segmentOrientedImageData, geometryImageData, geometryImageData, False, True)
    self.assertEqual(self.getForegroundVoxelCount(geometryImageData), 5223846)
    slicer.util.delayDisplay('Model and ROI source cases - OK')

    slicer.util.delayDisplay('Segmentation geometry widget test passed')
Ejemplo n.º 34
0
    def TestSection_3_ImportExportSegment(self):
        # Import/export, both one label and all labels
        logging.info('Test section 3: Import/export segment')

        # Export single segment to model node
        bodyModelNode = slicer.vtkMRMLModelNode()
        bodyModelNode.SetName('BodyModel')
        slicer.mrmlScene.AddNode(bodyModelNode)

        bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment(
            'Body_Contour')
        result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(
            bodySegment, bodyModelNode)
        self.assertTrue(result)
        self.assertIsNotNone(bodyModelNode.GetPolyData())
        #TODO: Number of points increased to 1677 due to end-capping, need to investigate!
        #self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfPoints(), 302)
        #TODO: On Linux and Windows it is 588, on Mac it is 580. Need to investigate
        # self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfCells(), 588)
        #self.assertTrue(bodyModelNode.GetPolyData().GetNumberOfCells() == 588 or bodyModelNode.GetPolyData().GetNumberOfCells() == 580)

        # Export single segment to volume node
        bodyLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
        bodyLabelmapNode.SetName('BodyLabelmap')
        slicer.mrmlScene.AddNode(bodyLabelmapNode)
        result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(
            bodySegment, bodyLabelmapNode)
        self.assertTrue(result)
        bodyImageData = bodyLabelmapNode.GetImageData()
        self.assertIsNotNone(bodyImageData)
        imageStat = vtk.vtkImageAccumulate()
        imageStat.SetInputData(bodyImageData)
        imageStat.Update()
        self.assertEqual(imageStat.GetVoxelCount(), 792)
        self.assertEqual(imageStat.GetMin()[0], 0)
        self.assertEqual(imageStat.GetMax()[0], 1)

        # Export multiple segments to volume node
        allSegmentsLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
        allSegmentsLabelmapNode.SetName('AllSegmentsLabelmap')
        slicer.mrmlScene.AddNode(allSegmentsLabelmapNode)
        result = slicer.vtkSlicerSegmentationsModuleLogic.ExportAllSegmentsToLabelmapNode(
            self.inputSegmentationNode, allSegmentsLabelmapNode)
        self.assertTrue(result)
        allSegmentsImageData = allSegmentsLabelmapNode.GetImageData()
        self.assertIsNotNone(allSegmentsImageData)
        imageStat = vtk.vtkImageAccumulate()
        imageStat.SetInputData(allSegmentsImageData)
        imageStat.SetComponentExtent(0, 5, 0, 0, 0, 0)
        imageStat.SetComponentOrigin(0, 0, 0)
        imageStat.SetComponentSpacing(1, 1, 1)
        imageStat.Update()
        self.assertEqual(imageStat.GetVoxelCount(), 24198552)
        imageStatResult = imageStat.GetOutput()
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(0, 0, 0, 0), 12900275)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(1, 0, 0, 0), 10601312)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(2, 0, 0, 0), 251476)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(3, 0, 0, 0), 445489)

        # Import model to segment
        modelImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
        modelImportSegmentationNode.SetName('ModelImport')
        modelImportSegmentationNode.GetSegmentation(
        ).SetMasterRepresentationName(self.closedSurfaceReprName)
        slicer.mrmlScene.AddNode(modelImportSegmentationNode)
        modelSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(
            bodyModelNode)
        modelSegment.UnRegister(None)  # Need to release ownership
        self.assertIsNotNone(modelSegment)
        self.assertIsNotNone(
            modelSegment.GetRepresentation(self.closedSurfaceReprName))

        # Import multi-label labelmap to segmentation
        multiLabelImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
        multiLabelImportSegmentationNode.SetName('MultiLabelImport')
        multiLabelImportSegmentationNode.GetSegmentation(
        ).SetMasterRepresentationName(self.binaryLabelmapReprName)
        slicer.mrmlScene.AddNode(multiLabelImportSegmentationNode)
        result = slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(
            allSegmentsLabelmapNode, multiLabelImportSegmentationNode)
        self.assertTrue(result)
        self.assertEqual(
            multiLabelImportSegmentationNode.GetSegmentation().
            GetNumberOfSegments(), 3)

        # Import labelmap into single segment
        singleLabelImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
        singleLabelImportSegmentationNode.SetName('SingleLabelImport')
        singleLabelImportSegmentationNode.GetSegmentation(
        ).SetMasterRepresentationName(self.binaryLabelmapReprName)
        slicer.mrmlScene.AddNode(singleLabelImportSegmentationNode)
        # Should not import multi-label labelmap to segment
        nullSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(
            allSegmentsLabelmapNode)
        self.assertIsNone(nullSegment)
        logging.info(
            '(This error message tests an impossible scenario, it is supposed to appear)'
        )
        # Make labelmap single-label and import again
        threshold = vtk.vtkImageThreshold()
        threshold.SetInValue(0)
        threshold.SetOutValue(1)
        threshold.ReplaceInOn()
        threshold.ThresholdByLower(0)
        threshold.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
        if vtk.VTK_MAJOR_VERSION <= 5:
            threshold.SetInput(allSegmentsLabelmapNode.GetImageData())
        else:
            threshold.SetInputData(allSegmentsLabelmapNode.GetImageData())
        threshold.Update()
        allSegmentsLabelmapNode.GetImageData().ShallowCopy(
            threshold.GetOutput())
        labelSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(
            allSegmentsLabelmapNode)
        labelSegment.UnRegister(None)  # Need to release ownership
        self.assertIsNotNone(labelSegment)
        self.assertIsNotNone(
            labelSegment.GetRepresentation(self.binaryLabelmapReprName))

        # Import/export with transforms
        logging.info('Test section 4/2: Import/export with transforms')

        # Create transform node that will be used to transform the tested nodes
        bodyModelTransformNode = slicer.vtkMRMLLinearTransformNode()
        slicer.mrmlScene.AddNode(bodyModelTransformNode)
        bodyModelTransform = vtk.vtkTransform()
        bodyModelTransform.Translate(1000.0, 0.0, 0.0)
        bodyModelTransformNode.ApplyTransformMatrix(
            bodyModelTransform.GetMatrix())

        # Set transform as parent to input segmentation node
        self.inputSegmentationNode.SetAndObserveTransformNodeID(
            bodyModelTransformNode.GetID())

        # Export single segment to model node from transformed segmentation
        bodyModelNodeTransformed = slicer.vtkMRMLModelNode()
        bodyModelNodeTransformed.SetName('BodyModelTransformed')
        slicer.mrmlScene.AddNode(bodyModelNodeTransformed)
        bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment(
            'Body_Contour')
        result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(
            bodySegment, bodyModelNodeTransformed)
        self.assertTrue(result)
        self.assertIsNotNone(bodyModelNodeTransformed.GetParentTransformNode())

        # Export single segment to volume node from transformed segmentation
        bodyLabelmapNodeTransformed = slicer.vtkMRMLLabelMapVolumeNode()
        bodyLabelmapNodeTransformed.SetName('BodyLabelmapTransformed')
        slicer.mrmlScene.AddNode(bodyLabelmapNodeTransformed)
        result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(
            bodySegment, bodyLabelmapNodeTransformed)
        self.assertTrue(result)
        self.assertIsNotNone(
            bodyLabelmapNodeTransformed.GetParentTransformNode())

        # Create transform node that will be used to transform the tested nodes
        modelTransformedImportSegmentationTransformNode = slicer.vtkMRMLLinearTransformNode(
        )
        slicer.mrmlScene.AddNode(
            modelTransformedImportSegmentationTransformNode)
        modelTransformedImportSegmentationTransform = vtk.vtkTransform()
        modelTransformedImportSegmentationTransform.Translate(-500.0, 0.0, 0.0)
        modelTransformedImportSegmentationTransformNode.ApplyTransformMatrix(
            modelTransformedImportSegmentationTransform.GetMatrix())

        # Import transformed model to segment in transformed segmentation
        modelTransformedImportSegmentationNode = slicer.vtkMRMLSegmentationNode(
        )
        modelTransformedImportSegmentationNode.SetName(
            'ModelImportTransformed')
        modelTransformedImportSegmentationNode.GetSegmentation(
        ).SetMasterRepresentationName(self.closedSurfaceReprName)
        slicer.mrmlScene.AddNode(modelTransformedImportSegmentationNode)
        modelTransformedImportSegmentationNode.SetAndObserveTransformNodeID(
            modelTransformedImportSegmentationTransformNode.GetID())
        modelSegmentTranformed = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(
            bodyModelNodeTransformed, modelTransformedImportSegmentationNode)
        modelSegmentTranformed.UnRegister(None)  # Need to release ownership
        self.assertIsNotNone(modelSegmentTranformed)
        modelSegmentTransformedPolyData = modelSegmentTranformed.GetRepresentation(
            self.closedSurfaceReprName)
        self.assertIsNotNone(modelSegmentTransformedPolyData)
        self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[0]),
                         1332)
        self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[1]),
                         1675)

        # Clean up temporary nodes
        slicer.mrmlScene.RemoveNode(bodyModelNode)
        slicer.mrmlScene.RemoveNode(bodyLabelmapNode)
        slicer.mrmlScene.RemoveNode(allSegmentsLabelmapNode)
        slicer.mrmlScene.RemoveNode(modelImportSegmentationNode)
        slicer.mrmlScene.RemoveNode(multiLabelImportSegmentationNode)
        slicer.mrmlScene.RemoveNode(singleLabelImportSegmentationNode)
        slicer.mrmlScene.RemoveNode(bodyModelTransformNode)
        slicer.mrmlScene.RemoveNode(bodyModelNodeTransformed)
        slicer.mrmlScene.RemoveNode(bodyLabelmapNodeTransformed)
        slicer.mrmlScene.RemoveNode(modelTransformedImportSegmentationNode)
Ejemplo n.º 35
0
  def test_TemplateKey1(self):
    """
    Basic automated test of the segmentation method:
    - Create segmentation by placing sphere-shaped seeds
    - Run segmentation
    - Verify results using segment statistics
    The test can be executed from SelfTests module (test name: SegmentEditorTemplateKey)
    """

    self.delayDisplay("Starting test_TemplateKey1")

    import vtkSegmentationCorePython as vtkSegmentationCore
    import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
    import SampleData
    from SegmentStatistics import SegmentStatisticsLogic

    ##################################
    self.delayDisplay("Load master volume")

    import SampleData
    sampleDataLogic = SampleData.SampleDataLogic()
    masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

    ##################################
    self.delayDisplay("Create segmentation containing a few spheres")

    segmentationNode = slicer.vtkMRMLSegmentationNode()
    slicer.mrmlScene.AddNode(segmentationNode)
    segmentationNode.CreateDefaultDisplayNodes()
    segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

    # Segments are defined by a list of: name and a list of sphere [radius, posX, posY, posZ]
    segmentGeometries = [
      ['Tumor', [[10, -6,30,28]]],
      ['Background', [[10, 0,65,22], [15, 1, -14, 30], [12, 0, 28, -7], [5, 0,30,54], [12, 31, 33, 27], [17, -42, 30, 27], [6, -2,-17,71]]],
      ['Air', [[10, 76,73,0], [15, -70,74,0]]] ]
    for segmentGeometry in segmentGeometries:
      segmentName = segmentGeometry[0]
      appender = vtk.vtkAppendPolyData()
      for sphere in segmentGeometry[1]:
        sphereSource = vtk.vtkSphereSource()
        sphereSource.SetRadius(sphere[0])
        sphereSource.SetCenter(sphere[1], sphere[2], sphere[3])
        appender.AddInputConnection(sphereSource.GetOutputPort())
      segment = vtkSegmentationCore.vtkSegment()
      segment.SetName(segmentationNode.GetSegmentation().GenerateUniqueSegmentID(segmentName))
      appender.Update()
      segment.AddRepresentation(vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName(), appender.GetOutput())
      segmentationNode.GetSegmentation().AddSegment(segment)

    ##################################
    self.delayDisplay("Create segment editor")

    segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    segmentEditorWidget.show()
    segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
    segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
    slicer.mrmlScene.AddNode(segmentEditorNode)
    segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
    segmentEditorWidget.setSegmentationNode(segmentationNode)
    segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

    ##################################
    self.delayDisplay("Run segmentation")
    segmentEditorWidget.setActiveEffectByName("TemplateKey")
    effect = segmentEditorWidget.activeEffect()
    effect.setParameter("ObjectScaleMm", 3.0)
    effect.self().onApply()

    ##################################
    self.delayDisplay("Make segmentation results nicely visible in 3D")
    segmentationDisplayNode = segmentationNode.GetDisplayNode()
    segmentationDisplayNode.SetSegmentVisibility("Air", False)
    segmentationDisplayNode.SetSegmentOpacity3D("Background",0.5)

    ##################################
    self.delayDisplay("Compute statistics")

    segStatLogic = SegmentStatisticsLogic()
    segStatLogic.computeStatistics(segmentationNode, masterVolumeNode)

    # Export results to table (just to see all results)
    resultsTableNode = slicer.vtkMRMLTableNode()
    slicer.mrmlScene.AddNode(resultsTableNode)
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)

    self.delayDisplay("Check a few numerical results")
    self.assertEqual( round(segStatLogic.statistics["Tumor","LM volume cc"]), 16)
    self.assertEqual( round(segStatLogic.statistics["Background","LM volume cc"]), 3010)

    self.delayDisplay('test_TemplateKey1 passed')
Ejemplo n.º 36
0
    def TestSection_2_MergeLabelmapWithDifferentGeometries(self):
        # Merge labelmap when segments containing labelmaps with different geometries (both same directions, different directions)
        logging.info(
            'Test section 2: Merge labelmap with different geometries')

        self.assertIsNotNone(self.sphereSegment)
        self.sphereSegment.RemoveRepresentation(self.binaryLabelmapReprName)
        self.assertIsNone(
            self.sphereSegment.GetRepresentation(self.binaryLabelmapReprName))

        # Create new segmentation with sphere segment
        self.secondSegmentationNode = slicer.vtkMRMLSegmentationNode()
        self.secondSegmentationNode.SetName('Second')
        self.secondSegmentationNode.GetSegmentation(
        ).SetMasterRepresentationName(self.binaryLabelmapReprName)
        slicer.mrmlScene.AddNode(self.secondSegmentationNode)

        self.secondSegmentationNode.GetSegmentation().AddSegment(
            self.sphereSegment)

        # Check automatically converted labelmap. It is supposed to have the default geometry
        # (which is different than the one in the input segmentation)
        sphereLabelmap = self.sphereSegment.GetRepresentation(
            self.binaryLabelmapReprName)
        self.assertIsNotNone(sphereLabelmap)
        sphereLabelmapSpacing = sphereLabelmap.GetSpacing()
        self.assertTrue(sphereLabelmapSpacing[0] == 1.0
                        and sphereLabelmapSpacing[1] == 1.0
                        and sphereLabelmapSpacing[2] == 1.0)

        # Create binary labelmap in segmentation that will create the merged labelmap from
        # different geometries so that labelmap is not removed from sphere segment when adding
        self.inputSegmentationNode.GetSegmentation().CreateRepresentation(
            self.binaryLabelmapReprName)

        # Copy segment to input segmentation
        self.inputSegmentationNode.GetSegmentation(
        ).CopySegmentFromSegmentation(
            self.secondSegmentationNode.GetSegmentation(),
            self.sphereSegmentName)
        self.assertEqual(
            self.inputSegmentationNode.GetSegmentation().GetNumberOfSegments(),
            3)

        # Check merged labelmap
        # Reference geometry has the tiny patient spacing, and it is oversampled to have smimilar
        # voxel size as the sphere labelmap with the uniform 1mm spacing
        mergedLabelmap = vtkSegmentationCore.vtkOrientedImageData()
        self.inputSegmentationNode.GenerateMergedLabelmapForAllSegments(
            mergedLabelmap, 0)
        mergedLabelmapSpacing = mergedLabelmap.GetSpacing()
        self.assertAlmostEqual(mergedLabelmapSpacing[0], 1.2894736842, 8)
        self.assertAlmostEqual(mergedLabelmapSpacing[1], 1.2894736842, 8)
        self.assertAlmostEqual(mergedLabelmapSpacing[2], 0.6052631578, 8)

        imageStat = vtk.vtkImageAccumulate()
        imageStat.SetInputData(mergedLabelmap)
        imageStat.SetComponentExtent(0, 5, 0, 0, 0, 0)
        imageStat.SetComponentOrigin(0, 0, 0)
        imageStat.SetComponentSpacing(1, 1, 1)
        imageStat.Update()
        self.assertEqual(imageStat.GetVoxelCount(), 54872000)
        imageStatResult = imageStat.GetOutput()
        for i in range(5):
            logging.info("Volume {0}: {1}".format(
                i, imageStatResult.GetScalarComponentAsDouble(i, 0, 0, 0)))
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(0, 0, 0, 0), 43573723)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(1, 0, 0, 0), 10601312)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(2, 0, 0, 0), 251476)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(3, 0, 0, 0), 445489)
        self.assertEqual(
            imageStatResult.GetScalarComponentAsDouble(4, 0, 0, 0), 0
        )  # Built from color table and color four is removed in previous test section
  def TestSection_3_ImportExportSegment(self):
    # Import/export, both one label and all labels
    logging.info('Test section 3: Import/export segment')

    # Export single segment to model node
    bodyModelNode = slicer.vtkMRMLModelNode()
    bodyModelNode.SetName('BodyModel')
    slicer.mrmlScene.AddNode(bodyModelNode)

    bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment('Body_Contour')
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyModelNode)
    self.assertTrue(result)
    self.assertIsNotNone(bodyModelNode.GetPolyData())
    #TODO: Number of points increased to 1677 due to end-capping, need to investigate!
    #self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfPoints(), 302)
    #TODO: On Linux and Windows it is 588, on Mac it is 580. Need to investigate
    # self.assertEqual(bodyModelNode.GetPolyData().GetNumberOfCells(), 588)
    #self.assertTrue(bodyModelNode.GetPolyData().GetNumberOfCells() == 588 or bodyModelNode.GetPolyData().GetNumberOfCells() == 580)

    # Export single segment to volume node
    bodyLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    bodyLabelmapNode.SetName('BodyLabelmap')
    slicer.mrmlScene.AddNode(bodyLabelmapNode)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyLabelmapNode)
    self.assertTrue(result)
    bodyImageData = bodyLabelmapNode.GetImageData()
    self.assertIsNotNone(bodyImageData)
    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(bodyImageData)
    imageStat.Update()
    self.assertEqual(imageStat.GetVoxelCount(), 792)
    self.assertEqual(imageStat.GetMin()[0], 0)
    self.assertEqual(imageStat.GetMax()[0], 1)

    # Export multiple segments to volume node
    allSegmentsLabelmapNode = slicer.vtkMRMLLabelMapVolumeNode()
    allSegmentsLabelmapNode.SetName('AllSegmentsLabelmap')
    slicer.mrmlScene.AddNode(allSegmentsLabelmapNode)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportAllSegmentsToLabelmapNode(self.inputSegmentationNode, allSegmentsLabelmapNode)
    self.assertTrue(result)
    allSegmentsImageData = allSegmentsLabelmapNode.GetImageData()
    self.assertIsNotNone(allSegmentsImageData)
    imageStat = vtk.vtkImageAccumulate()
    imageStat.SetInputData(allSegmentsImageData)
    imageStat.SetComponentExtent(0,5,0,0,0,0)
    imageStat.SetComponentOrigin(0,0,0)
    imageStat.SetComponentSpacing(1,1,1)
    imageStat.Update()
    self.assertEqual(imageStat.GetVoxelCount(), 24198552)
    imageStatResult = imageStat.GetOutput()
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(0,0,0,0), 12900275)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(1,0,0,0), 10601312)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(2,0,0,0), 251476)
    self.assertEqual(imageStatResult.GetScalarComponentAsDouble(3,0,0,0), 445489)

    # Import model to segment
    modelImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
    modelImportSegmentationNode.SetName('ModelImport')
    modelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.closedSurfaceReprName)
    slicer.mrmlScene.AddNode(modelImportSegmentationNode)
    modelSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(bodyModelNode)
    modelSegment.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(modelSegment)
    self.assertIsNotNone(modelSegment.GetRepresentation(self.closedSurfaceReprName))

    # Import multi-label labelmap to segmentation
    multiLabelImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
    multiLabelImportSegmentationNode.SetName('MultiLabelImport')
    multiLabelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    slicer.mrmlScene.AddNode(multiLabelImportSegmentationNode)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ImportLabelmapToSegmentationNode(allSegmentsLabelmapNode, multiLabelImportSegmentationNode)
    self.assertTrue(result)
    self.assertEqual(multiLabelImportSegmentationNode.GetSegmentation().GetNumberOfSegments(), 3)

    # Import labelmap into single segment
    singleLabelImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
    singleLabelImportSegmentationNode.SetName('SingleLabelImport')
    singleLabelImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.binaryLabelmapReprName)
    slicer.mrmlScene.AddNode(singleLabelImportSegmentationNode)
    # Should not import multi-label labelmap to segment
    nullSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(allSegmentsLabelmapNode)
    self.assertIsNone(nullSegment)
    logging.info('(This error message tests an impossible scenario, it is supposed to appear)')
    # Make labelmap single-label and import again
    threshold = vtk.vtkImageThreshold()
    threshold.SetInValue(0)
    threshold.SetOutValue(1)
    threshold.ReplaceInOn()
    threshold.ThresholdByLower(0)
    threshold.SetOutputScalarType(vtk.VTK_UNSIGNED_CHAR)
    if vtk.VTK_MAJOR_VERSION <= 5:
      threshold.SetInput(allSegmentsLabelmapNode.GetImageData())
    else:
      threshold.SetInputData(allSegmentsLabelmapNode.GetImageData())
    threshold.Update()
    allSegmentsLabelmapNode.GetImageData().ShallowCopy(threshold.GetOutput())
    labelSegment = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromLabelmapVolumeNode(allSegmentsLabelmapNode)
    labelSegment.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(labelSegment)
    self.assertIsNotNone(labelSegment.GetRepresentation(self.binaryLabelmapReprName))

    # Import/export with transforms
    logging.info('Test section 4/2: Import/export with transforms')

    # Create transform node that will be used to transform the tested nodes
    bodyModelTransformNode = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(bodyModelTransformNode)
    bodyModelTransform = vtk.vtkTransform()
    bodyModelTransform.Translate(1000.0, 0.0, 0.0)
    bodyModelTransformNode.ApplyTransformMatrix(bodyModelTransform.GetMatrix())

    # Set transform as parent to input segmentation node
    self.inputSegmentationNode.SetAndObserveTransformNodeID(bodyModelTransformNode.GetID())

    # Export single segment to model node from transformed segmentation
    bodyModelNodeTransformed = slicer.vtkMRMLModelNode()
    bodyModelNodeTransformed.SetName('BodyModelTransformed')
    slicer.mrmlScene.AddNode(bodyModelNodeTransformed)
    bodySegment = self.inputSegmentationNode.GetSegmentation().GetSegment('Body_Contour')
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyModelNodeTransformed)
    self.assertTrue(result)
    self.assertIsNotNone(bodyModelNodeTransformed.GetParentTransformNode())

    # Export single segment to volume node from transformed segmentation
    bodyLabelmapNodeTransformed = slicer.vtkMRMLLabelMapVolumeNode()
    bodyLabelmapNodeTransformed.SetName('BodyLabelmapTransformed')
    slicer.mrmlScene.AddNode(bodyLabelmapNodeTransformed)
    result = slicer.vtkSlicerSegmentationsModuleLogic.ExportSegmentToRepresentationNode(bodySegment, bodyLabelmapNodeTransformed)
    self.assertTrue(result)
    self.assertIsNotNone(bodyLabelmapNodeTransformed.GetParentTransformNode())

    # Create transform node that will be used to transform the tested nodes
    modelTransformedImportSegmentationTransformNode = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(modelTransformedImportSegmentationTransformNode)
    modelTransformedImportSegmentationTransform = vtk.vtkTransform()
    modelTransformedImportSegmentationTransform.Translate(-500.0, 0.0, 0.0)
    modelTransformedImportSegmentationTransformNode.ApplyTransformMatrix(modelTransformedImportSegmentationTransform.GetMatrix())

    # Import transformed model to segment in transformed segmentation
    modelTransformedImportSegmentationNode = slicer.vtkMRMLSegmentationNode()
    modelTransformedImportSegmentationNode.SetName('ModelImportTransformed')
    modelTransformedImportSegmentationNode.GetSegmentation().SetMasterRepresentationName(self.closedSurfaceReprName)
    slicer.mrmlScene.AddNode(modelTransformedImportSegmentationNode)
    modelTransformedImportSegmentationNode.SetAndObserveTransformNodeID(modelTransformedImportSegmentationTransformNode.GetID())
    modelSegmentTranformed = slicer.vtkSlicerSegmentationsModuleLogic.CreateSegmentFromModelNode(bodyModelNodeTransformed, modelTransformedImportSegmentationNode)
    modelSegmentTranformed.UnRegister(None) # Need to release ownership
    self.assertIsNotNone(modelSegmentTranformed)
    modelSegmentTransformedPolyData = modelSegmentTranformed.GetRepresentation(self.closedSurfaceReprName)
    self.assertIsNotNone(modelSegmentTransformedPolyData)
    self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[0]), 1332)
    self.assertEqual(int(modelSegmentTransformedPolyData.GetBounds()[1]), 1675)

    # Clean up temporary nodes
    slicer.mrmlScene.RemoveNode(bodyModelNode)
    slicer.mrmlScene.RemoveNode(bodyLabelmapNode)
    slicer.mrmlScene.RemoveNode(allSegmentsLabelmapNode)
    slicer.mrmlScene.RemoveNode(modelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(multiLabelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(singleLabelImportSegmentationNode)
    slicer.mrmlScene.RemoveNode(bodyModelTransformNode)
    slicer.mrmlScene.RemoveNode(bodyModelNodeTransformed)
    slicer.mrmlScene.RemoveNode(bodyLabelmapNodeTransformed)
    slicer.mrmlScene.RemoveNode(modelTransformedImportSegmentationNode)
Ejemplo n.º 38
0
    def test_SegmentStatisticsPlugins(self):
        """
    This tests some aspects of the segment statistics plugins
    """

        self.delayDisplay("Starting test_SegmentStatisticsPlugins")

        import vtkSegmentationCorePython as vtkSegmentationCore
        import SampleData
        from SegmentStatistics import SegmentStatisticsLogic

        self.delayDisplay("Load master volume")

        sampleDataLogic = SampleData.SampleDataLogic()
        masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

        self.delayDisplay("Create segmentation containing a few spheres")

        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            masterVolumeNode)

        # Geometry for each segment is defined by: radius, posX, posY, posZ
        segmentGeometries = [[10, -6, 30, 28], [20, 0, 65, 32],
                             [15, 1, -14, 30], [12, 0, 28, -7], [5, 0, 30, 64],
                             [12, 31, 33, 27], [17, -42, 30, 27]]
        for segmentGeometry in segmentGeometries:
            sphereSource = vtk.vtkSphereSource()
            sphereSource.SetRadius(segmentGeometry[0])
            sphereSource.SetCenter(segmentGeometry[1], segmentGeometry[2],
                                   segmentGeometry[3])
            sphereSource.Update()
            segment = vtkSegmentationCore.vtkSegment()
            uniqueSegmentID = segmentationNode.GetSegmentation(
            ).GenerateUniqueSegmentID("Test")
            segmentationNode.AddSegmentFromClosedSurfaceRepresentation(
                sphereSource.GetOutput(), uniqueSegmentID)

        # test calculating only measurements for selected segments
        self.delayDisplay(
            "Test calculating only measurements for individual segments")
        segStatLogic = SegmentStatisticsLogic()
        segStatLogic.getParameterNode().SetParameter("Segmentation",
                                                     segmentationNode.GetID())
        segStatLogic.getParameterNode().SetParameter("ScalarVolume",
                                                     masterVolumeNode.GetID())
        segStatLogic.updateStatisticsForSegment('Test_2')
        resultsTableNode = slicer.vtkMRMLTableNode()
        slicer.mrmlScene.AddNode(resultsTableNode)
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        self.assertEqual(
            segStatLogic.getStatistics()[
                "Test_2", "LabelmapSegmentStatisticsPlugin.voxel_count"], 9807)
        with self.assertRaises(KeyError):
            segStatLogic.getStatistics()[
                "Test_4", "ScalarVolumeSegmentStatisticsPlugin.voxel count"]
        # assert there are no result for this segment
        segStatLogic.updateStatisticsForSegment('Test_4')
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        self.assertEqual(
            segStatLogic.getStatistics()[
                "Test_2", "LabelmapSegmentStatisticsPlugin.voxel_count"], 9807)
        self.assertEqual(
            segStatLogic.getStatistics()[
                "Test_4", "LabelmapSegmentStatisticsPlugin.voxel_count"], 380)
        with self.assertRaises(KeyError):
            segStatLogic.getStatistics()[
                "Test_5", "ScalarVolumeSegmentStatisticsPlugin.voxel count"]
        # assert there are no result for this segment

        # calculate measurements for all segments
        segStatLogic.computeStatistics()
        self.assertEqual(
            segStatLogic.getStatistics()[
                "Test", "LabelmapSegmentStatisticsPlugin.voxel_count"], 2948)
        self.assertEqual(
            segStatLogic.getStatistics()
            ["Test_1", "LabelmapSegmentStatisticsPlugin.voxel_count"], 23281)

        # test updating measurements for segments one by one
        self.delayDisplay("Update some segments in the segmentation")
        segmentGeometriesNew = [[5, -6, 30, 28], [21, 0, 65, 32]]
        for i in range(len(segmentGeometriesNew)):
            segmentGeometry = segmentGeometriesNew[i]
            sphereSource = vtk.vtkSphereSource()
            sphereSource.SetRadius(segmentGeometry[0])
            sphereSource.SetCenter(segmentGeometry[1], segmentGeometry[2],
                                   segmentGeometry[3])
            sphereSource.Update()
            segment = segmentationNode.GetSegmentation().GetNthSegment(i)
            segment.RemoveAllRepresentations()
            closedSurfaceName = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName(
            )
            segment.AddRepresentation(closedSurfaceName,
                                      sphereSource.GetOutput())
        self.assertEqual(
            segStatLogic.getStatistics()[
                "Test", "LabelmapSegmentStatisticsPlugin.voxel_count"], 2948)
        self.assertEqual(
            segStatLogic.getStatistics()
            ["Test_1", "LabelmapSegmentStatisticsPlugin.voxel_count"], 23281)
        segStatLogic.updateStatisticsForSegment('Test_1')
        self.assertEqual(
            segStatLogic.getStatistics()[
                "Test", "LabelmapSegmentStatisticsPlugin.voxel_count"], 2948)
        self.assertTrue(segStatLogic.getStatistics()[
            "Test_1", "LabelmapSegmentStatisticsPlugin.voxel_count"] != 23281)
        segStatLogic.updateStatisticsForSegment('Test')
        self.assertTrue(segStatLogic.getStatistics()[
            "Test", "LabelmapSegmentStatisticsPlugin.voxel_count"] != 2948)
        self.assertTrue(segStatLogic.getStatistics()[
            "Test_1", "LabelmapSegmentStatisticsPlugin.voxel_count"] != 23281)

        # test enabling/disabling of individual measurements
        self.delayDisplay("Test disabling of individual measurements")
        segStatLogic = SegmentStatisticsLogic()
        segStatLogic.getParameterNode().SetParameter("Segmentation",
                                                     segmentationNode.GetID())
        segStatLogic.getParameterNode().SetParameter("ScalarVolume",
                                                     masterVolumeNode.GetID())
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.voxel_count.enabled", str(False))
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.volume_cm3.enabled", str(False))
        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        columnHeaders = [
            resultsTableNode.GetColumnName(i)
            for i in range(resultsTableNode.GetNumberOfColumns())
        ]
        self.assertFalse('Number of voxels [voxels] (1)' in columnHeaders)
        self.assertTrue('Volume [mm3] (1)' in columnHeaders)
        self.assertFalse('Volume [cm3] (3)' in columnHeaders)

        self.delayDisplay("Test re-enabling of individual measurements")
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.voxel_count.enabled", str(True))
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.volume_cm3.enabled", str(True))
        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        columnHeaders = [
            resultsTableNode.GetColumnName(i)
            for i in range(resultsTableNode.GetNumberOfColumns())
        ]
        self.assertTrue('Number of voxels [voxels] (1)' in columnHeaders)
        self.assertTrue('Volume [mm3] (1)' in columnHeaders)
        self.assertTrue('Volume [cm3] (1)' in columnHeaders)

        # test enabling/disabling of individual plugins
        self.delayDisplay("Test disabling of plugin")
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.enabled", str(False))
        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        columnHeaders = [
            resultsTableNode.GetColumnName(i)
            for i in range(resultsTableNode.GetNumberOfColumns())
        ]
        self.assertFalse('Number of voxels [voxels] (3)' in columnHeaders)
        self.assertFalse('Volume [mm3] (3)' in columnHeaders)
        self.assertTrue('Volume [mm3] (2)' in columnHeaders)

        self.delayDisplay("Test re-enabling of plugin")
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.enabled", str(True))
        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        columnHeaders = [
            resultsTableNode.GetColumnName(i)
            for i in range(resultsTableNode.GetNumberOfColumns())
        ]
        self.assertTrue('Number of voxels [voxels] (2)' in columnHeaders)
        self.assertTrue('Volume [mm3] (3)' in columnHeaders)

        # test unregistering/registering of plugins
        self.delayDisplay("Test of removing all registered plugins")
        SegmentStatisticsLogic.registeredPlugins = [
        ]  # remove all registered plugins
        segStatLogic = SegmentStatisticsLogic()
        segStatLogic.getParameterNode().SetParameter("Segmentation",
                                                     segmentationNode.GetID())
        segStatLogic.getParameterNode().SetParameter("ScalarVolume",
                                                     masterVolumeNode.GetID())
        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        columnHeaders = [
            resultsTableNode.GetColumnName(i)
            for i in range(resultsTableNode.GetNumberOfColumns())
        ]
        self.assertEqual(len(columnHeaders),
                         1)  # only header element should be "Segment"
        self.assertEqual(columnHeaders[0],
                         "Segment")  # only header element should be "Segment"

        self.delayDisplay("Test registering plugins")
        SegmentStatisticsLogic.registerPlugin(
            LabelmapSegmentStatisticsPlugin())
        SegmentStatisticsLogic.registerPlugin(
            ScalarVolumeSegmentStatisticsPlugin())
        SegmentStatisticsLogic.registerPlugin(
            ClosedSurfaceSegmentStatisticsPlugin())
        segStatLogic = SegmentStatisticsLogic()
        segStatLogic.getParameterNode().SetParameter("Segmentation",
                                                     segmentationNode.GetID())
        segStatLogic.getParameterNode().SetParameter("ScalarVolume",
                                                     masterVolumeNode.GetID())
        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        segStatLogic.showTable(resultsTableNode)
        columnHeaders = [
            resultsTableNode.GetColumnName(i)
            for i in range(resultsTableNode.GetNumberOfColumns())
        ]
        self.assertTrue('Number of voxels [voxels] (1)' in columnHeaders)
        self.assertTrue('Number of voxels [voxels] (2)' in columnHeaders)
        self.assertTrue('Surface area [mm2]' in columnHeaders)

        self.delayDisplay('test_SegmentStatisticsPlugins passed!')
Ejemplo n.º 39
0
class VertebraSegmentation()

  # Load master volume
  sampleDataLogic = SampleData.SampleDataLogic()
  masterVolumeNode = sampleDataLogic.downloadCTACardio()

  ##gets the node coordinates to run the grow cut from later
  hierarchy = slicer.vtkMMRLSubjectHierarchyNode(slicer.mmrlScene)
  sceneItemID = hierarchy.GetSceneItemID()
  subjectItemID = hierarchy.GetItemChildWithName(sceneItemID,'Fiducial Nodes')
  fidList = slicer.util.getNode('FiducialNodes')


  # Create segmentation
  segmentationNode = slicer.vtkMRMLSegmentationNode()
  slicer.mrmlScene.AddNode(segmentationNode)
  segmentationNode.CreateDefaultDisplayNodes() # only needed for display
  segmentationNode.name = 'Lumbar'
  segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

  # Create seed segment inside lumbar and name
  lumbarSeed = fidList[0]
  lumbarSeed.SetRadius(3)
  lumbarSeed.Update()
  segmentationNode.AddSegmentFromClosedSurfaceRepresentation(lumbarSeed.GetOutput(), "Lumbar Vertebra", [1.0,0.0,0.0])


  def __init__(self, scriptedEffect):
    SegmentEditorThresholdEffect.__init__(self, scriptedEffect)
    scriptedEffect.name = 'Local Threshold'
    self.previewSteps = 4

  def updateMRMLFromGUI(self): ## sets the parameters for local threshold - grow cut at 6mm for feature size and 265.00 to 1009.00 for threshold range
    SegmentEditorThresholdEffect.updateMRMLFromGUI(self)
    featureSizeMm = 6.000 ##self.minimumMinimumFeatureSize.value
    self.scriptedEffect.setParameter(MINIMUM_FEATURE_MM_PARAMETER_NAME, featureSizeMm)

    segmentationAlgorithm = "GrowCut" ##self.segmentationAlgorithmSelector.currentText
    self.scriptedEffect.setParameter(SEGMENTATION_ALGORITHM_PARAMETER_NAME, segmentationAlgorithm)


  def runGrowCut(self, masterImageData, seedLabelmap, outputLabelmap): ## runs the grow cut - local threshold on the segment

    self.clippedMaskImageData = slicer.vtkOrientedImageData()
    intensityBasedMasking = self.scriptedEffect.parameterSetNode().GetMasterVolumeIntensityMask()
    segmentationNode = self.scriptedEffect.parameterSetNode().GetSegmentationNode()
    success = segmentationNode.GenerateEditMask(self.clippedMaskImageData,
      self.scriptedEffect.parameterSetNode().GetMaskMode(),
      masterImageData, # reference geometry
      "", # edited segment ID
      self.scriptedEffect.parameterSetNode().GetMaskSegmentID() if self.scriptedEffect.parameterSetNode().GetMaskSegmentID() else "",
      masterImageData if intensityBasedMasking else None,
      self.scriptedEffect.parameterSetNode().GetMasterVolumeIntensityMaskRange() if intensityBasedMasking else None)

    import vtkSlicerSegmentationsModuleLogicPython as vtkSlicerSegmentationsModuleLogic
    self.growCutFilter = vtkSlicerSegmentationsModuleLogic.vtkImageGrowCutSegment()
    self.growCutFilter.SetIntensityVolume(masterImageData)
    self.growCutFilter.SetSeedLabelVolume(seedLabelmap)
    self.growCutFilter.SetMaskVolume(self.clippedMaskImageData)
    self.growCutFilter.Update()
    outputLabelmap.ShallowCopy(self.growCutFilter.GetOutput())

  
  def apply(self, ijkPoints):
    kernelSizePixel = self.getKernelSizePixel()
    if kernelSizePixel[0]<=0 and kernelSizePixel[1]<=0 and kernelSizePixel[2]<=0:
      return

    qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor)

    # Get parameter set node
    parameterSetNode = self.scriptedEffect.parameterSetNode()

    # Get parameters
    minimumThreshold = self.scriptedEffect.doubleParameter("MinimumThreshold")
    maximumThreshold = self.scriptedEffect.doubleParameter("MaximumThreshold")

    # Get modifier labelmap
    modifierLabelmap = self.scriptedEffect.defaultModifierLabelmap()

    # Get master volume image data
    masterImageData = self.scriptedEffect.masterVolumeImageData()

    # Set intensity range
    oldMasterVolumeIntensityMask = parameterSetNode.GetMasterVolumeIntensityMask()
    parameterSetNode.MasterVolumeIntensityMaskOn()
    oldIntensityMaskRange = parameterSetNode.GetMasterVolumeIntensityMaskRange()
    intensityRange = [265.00, 1009.00]
    if oldMasterVolumeIntensityMask:
      intensityRange = [max(oldIntensityMaskRange[0], minimumThreshold), min(oldIntensityMaskRange[1], maximumThreshold)]
    parameterSetNode.SetMasterVolumeIntensityMaskRange(intensityRange)

    roiNode = lumbarSeed ##self.roiSelector.currentNode()
    clippedMasterImageData = masterImageData
    if roiNode is not None:
      worldToImageMatrix = vtk.vtkMatrix4x4()
      masterImageData.GetWorldToImageMatrix(worldToImageMatrix)

      bounds = [0,0,0,0,0,0]
      roiNode.GetRASBounds(bounds)
      corner1RAS = [bounds[0], bounds[2], bounds[4], 1]
      corner1IJK = [0, 0, 0, 0]
      worldToImageMatrix.MultiplyPoint(corner1RAS, corner1IJK)

      corner2RAS = [bounds[1], bounds[3], bounds[5], 1]
      corner2IJK = [0, 0, 0, 0]
      worldToImageMatrix.MultiplyPoint(corner2RAS, corner2IJK)

      extent = [0, -1, 0, -1, 0, -1]
      for i in range(3):
          lowerPoint = min(corner1IJK[i], corner2IJK[i])
          upperPoint = max(corner1IJK[i], corner2IJK[i])
          extent[2*i] = int(math.floor(lowerPoint))
          extent[2*i+1] = int(math.ceil(upperPoint))

      imageToWorldMatrix = vtk.vtkMatrix4x4()
      masterImageData.GetImageToWorldMatrix(imageToWorldMatrix)
      clippedMasterImageData = slicer.vtkOrientedImageData()
      self.padder = vtk.vtkImageConstantPad()
      self.padder.SetInputData(masterImageData)
      self.padder.SetOutputWholeExtent(extent)
      self.padder.Update()
      clippedMasterImageData.ShallowCopy(self.padder.GetOutput())
      clippedMasterImageData.SetImageToWorldMatrix(imageToWorldMatrix)

    # Pipeline
    self.thresh = vtk.vtkImageThreshold()
    self.thresh.SetInValue(LABEL_VALUE)
    self.thresh.SetOutValue(BACKGROUND_VALUE)
    self.thresh.SetInputData(clippedMasterImageData)
    self.thresh.ThresholdBetween(minimumThreshold, maximumThreshold)
    self.thresh.SetOutputScalarTypeToUnsignedChar()
    self.thresh.Update()

    self.erode = vtk.vtkImageDilateErode3D()
    self.erode.SetInputConnection(self.thresh.GetOutputPort())
    self.erode.SetDilateValue(BACKGROUND_VALUE)
    self.erode.SetErodeValue(LABEL_VALUE)
    self.erode.SetKernelSize(
      kernelSizePixel[0],
      kernelSizePixel[1],
      kernelSizePixel[2])

    self.erodeCast = vtk.vtkImageCast()
    self.erodeCast.SetInputConnection(self.erode.GetOutputPort())
    self.erodeCast.SetOutputScalarTypeToUnsignedInt()
    self.erodeCast.Update()

    # Remove small islands
    self.islandMath = vtkITK.vtkITKIslandMath()
    self.islandMath.SetInputConnection(self.erodeCast.GetOutputPort())
    self.islandMath.SetFullyConnected(False)
    self.islandMath.SetMinimumSize(125)  # remove regions smaller than 5x5x5 voxels

    self.islandThreshold = vtk.vtkImageThreshold()
    self.islandThreshold.SetInputConnection(self.islandMath.GetOutputPort())
    self.islandThreshold.ThresholdByLower(BACKGROUND_VALUE)
    self.islandThreshold.SetInValue(BACKGROUND_VALUE)
    self.islandThreshold.SetOutValue(LABEL_VALUE)
    self.islandThreshold.SetOutputScalarTypeToUnsignedChar()
    self.islandThreshold.Update()

    # Points may be outside the region after it is eroded.
    # Snap the points to LABEL_VALUE voxels,
    snappedIJKPoints = self.snapIJKPointsToLabel(ijkPoints, self.islandThreshold.GetOutput())
    if snappedIJKPoints.GetNumberOfPoints() == 0:
      qt.QApplication.restoreOverrideCursor()
      return

    # Convert points to real data coordinates. Required for vtkImageThresholdConnectivity.
    seedPoints = vtk.vtkPoints()
    origin = masterImageData.GetOrigin()
    spacing = masterImageData.GetSpacing()
    for i in range(snappedIJKPoints.GetNumberOfPoints()):
      ijkPoint = snappedIJKPoints.GetPoint(i)
      seedPoints.InsertNextPoint(
        origin[0]+ijkPoint[0]*spacing[0],
        origin[1]+ijkPoint[1]*spacing[1],
        origin[2]+ijkPoint[2]*spacing[2])

    segmentationAlgorithm = self.scriptedEffect.parameter(SEGMENTATION_ALGORITHM_PARAMETER_NAME)
    if segmentationAlgorithm == SEGMENTATION_ALGORITHM_MASKING:
      self.runMasking(seedPoints, self.islandThreshold.GetOutput(), modifierLabelmap)

    else:
      self.floodFillingFilterIsland = vtk.vtkImageThresholdConnectivity()
      self.floodFillingFilterIsland.SetInputConnection(self.islandThreshold.GetOutputPort())
      self.floodFillingFilterIsland.SetInValue(SELECTED_ISLAND_VALUE)
      self.floodFillingFilterIsland.ReplaceInOn()
      self.floodFillingFilterIsland.ReplaceOutOff()
      self.floodFillingFilterIsland.ThresholdBetween(265.00, 1009.00)
      self.floodFillingFilterIsland.SetSeedPoints(seedPoints)
      self.floodFillingFilterIsland.Update()

      self.maskCast = vtk.vtkImageCast()
      self.maskCast.SetInputData(self.thresh.GetOutput())
      self.maskCast.SetOutputScalarTypeToUnsignedChar()
      self.maskCast.Update()

      self.imageMask = vtk.vtkImageMask()
      self.imageMask.SetInputConnection(self.floodFillingFilterIsland.GetOutputPort())
      self.imageMask.SetMaskedOutputValue(OUTSIDE_THRESHOLD_VALUE)
      self.imageMask.SetMaskInputData(self.maskCast.GetOutput())
      self.imageMask.Update()

      imageMaskOutput = slicer.vtkOrientedImageData()
      imageMaskOutput.ShallowCopy(self.imageMask.GetOutput())
      imageMaskOutput.CopyDirections(clippedMasterImageData)

      imageToWorldMatrix = vtk.vtkMatrix4x4()
      imageMaskOutput.GetImageToWorldMatrix(imageToWorldMatrix)

      segmentOutputLabelmap = slicer.vtkOrientedImageData()
      if segmentationAlgorithm == SEGMENTATION_ALGORITHM_GROWCUT:
        self.runGrowCut(clippedMasterImageData, imageMaskOutput, segmentOutputLabelmap)
      elif segmentationAlgorithm == SEGMENTATION_ALGORITHM_WATERSHED:
        self.runWatershed(clippedMasterImageData, imageMaskOutput, segmentOutputLabelmap)
      else:
        logging.error("Unknown segmentation algorithm: \"" + segmentationAlgorithm + "\"")

      segmentOutputLabelmap.SetImageToWorldMatrix(imageToWorldMatrix)

      self.selectedSegmentThreshold = vtk.vtkImageThreshold()
      self.selectedSegmentThreshold.SetInputData(segmentOutputLabelmap)
      self.selectedSegmentThreshold.ThresholdBetween(SELECTED_ISLAND_VALUE, SELECTED_ISLAND_VALUE)
      self.selectedSegmentThreshold.SetInValue(LABEL_VALUE)
      self.selectedSegmentThreshold.SetOutValue(BACKGROUND_VALUE)
      self.selectedSegmentThreshold.SetOutputScalarType(modifierLabelmap.GetScalarType())
      self.selectedSegmentThreshold.Update()
      modifierLabelmap.ShallowCopy(self.selectedSegmentThreshold.GetOutput())

    self.scriptedEffect.saveStateForUndo()
    self.scriptedEffect.modifySelectedSegmentByLabelmap(modifierLabelmap, slicer.qSlicerSegmentEditorAbstractEffect.ModificationModeAdd)

    parameterSetNode.SetMasterVolumeIntensityMask(oldMasterVolumeIntensityMask)
    parameterSetNode.SetMasterVolumeIntensityMaskRange(oldIntensityMaskRange)

    qt.QApplication.restoreOverrideCursor()
Ejemplo n.º 40
0
  def test_SegmentStatisticsPlugins(self):
    """
    This tests some aspects of the segment statistics plugins
    """

    self.delayDisplay("Starting test_SegmentStatisticsPlugins")

    import vtkSegmentationCorePython as vtkSegmentationCore
    import SampleData
    from SegmentStatistics import SegmentStatisticsLogic

    self.delayDisplay("Load master volume")

    sampleDataLogic = SampleData.SampleDataLogic()
    masterVolumeNode = sampleDataLogic.downloadMRBrainTumor1()

    self.delayDisplay("Create segmentation containing a few spheres")

    segmentationNode = slicer.vtkMRMLSegmentationNode()
    slicer.mrmlScene.AddNode(segmentationNode)
    segmentationNode.CreateDefaultDisplayNodes()
    segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

    # Geometry for each segment is defined by: radius, posX, posY, posZ
    segmentGeometries = [[10, -6,30,28], [20, 0,65,32], [15, 1, -14, 30], [12, 0, 28, -7], [5, 0,30,64],
                         [12, 31, 33, 27], [17, -42, 30, 27]]
    for segmentGeometry in segmentGeometries:
      sphereSource = vtk.vtkSphereSource()
      sphereSource.SetRadius(segmentGeometry[0])
      sphereSource.SetCenter(segmentGeometry[1], segmentGeometry[2], segmentGeometry[3])
      sphereSource.Update()
      segment = vtkSegmentationCore.vtkSegment()
      uniqueSegmentID = segmentationNode.GetSegmentation().GenerateUniqueSegmentID("Test")
      segmentationNode.AddSegmentFromClosedSurfaceRepresentation(sphereSource.GetOutput(), uniqueSegmentID)

    # test calculating only measurements for selected segments
    self.delayDisplay("Test calculating only measurements for individual segments")
    segStatLogic = SegmentStatisticsLogic()
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("ScalarVolume", masterVolumeNode.GetID())
    segStatLogic.updateStatisticsForSegment('Test_2')
    resultsTableNode = slicer.vtkMRMLTableNode()
    slicer.mrmlScene.AddNode(resultsTableNode)
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    self.assertEqual( segStatLogic.getStatistics()["Test_2","LabelmapSegmentStatisticsPlugin.voxel_count"], 9807)
    with self.assertRaises(KeyError): segStatLogic.getStatistics()["Test_4","ScalarVolumeSegmentStatisticsPlugin.voxel count"]
    # assert there are no result for this segment
    segStatLogic.updateStatisticsForSegment('Test_4')
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    self.assertEqual( segStatLogic.getStatistics()["Test_2","LabelmapSegmentStatisticsPlugin.voxel_count"], 9807)
    self.assertEqual( segStatLogic.getStatistics()["Test_4","LabelmapSegmentStatisticsPlugin.voxel_count"], 380)
    with self.assertRaises(KeyError): segStatLogic.getStatistics()["Test_5","ScalarVolumeSegmentStatisticsPlugin.voxel count"]
    # assert there are no result for this segment

    # calculate measurements for all segments
    segStatLogic.computeStatistics()
    self.assertEqual( segStatLogic.getStatistics()["Test","LabelmapSegmentStatisticsPlugin.voxel_count"], 2948)
    self.assertEqual( segStatLogic.getStatistics()["Test_1","LabelmapSegmentStatisticsPlugin.voxel_count"], 23281)

    # test updating measurements for segments one by one
    self.delayDisplay("Update some segments in the segmentation")
    segmentGeometriesNew = [[5, -6,30,28], [21, 0,65,32]]
    for i in range(len(segmentGeometriesNew)):
      segmentGeometry  = segmentGeometriesNew[i]
      sphereSource = vtk.vtkSphereSource()
      sphereSource.SetRadius(segmentGeometry[0])
      sphereSource.SetCenter(segmentGeometry[1], segmentGeometry[2], segmentGeometry[3])
      sphereSource.Update()
      segment = segmentationNode.GetSegmentation().GetNthSegment(i)
      segment.RemoveAllRepresentations()
      closedSurfaceName = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName()
      segment.AddRepresentation(closedSurfaceName,
                                sphereSource.GetOutput())
    self.assertEqual( segStatLogic.getStatistics()["Test","LabelmapSegmentStatisticsPlugin.voxel_count"], 2948)
    self.assertEqual( segStatLogic.getStatistics()["Test_1","LabelmapSegmentStatisticsPlugin.voxel_count"], 23281)
    segStatLogic.updateStatisticsForSegment('Test_1')
    self.assertEqual( segStatLogic.getStatistics()["Test","LabelmapSegmentStatisticsPlugin.voxel_count"], 2948)
    self.assertTrue( segStatLogic.getStatistics()["Test_1","LabelmapSegmentStatisticsPlugin.voxel_count"]!=23281)
    segStatLogic.updateStatisticsForSegment('Test')
    self.assertTrue( segStatLogic.getStatistics()["Test","LabelmapSegmentStatisticsPlugin.voxel_count"]!=2948)
    self.assertTrue( segStatLogic.getStatistics()["Test_1","LabelmapSegmentStatisticsPlugin.voxel_count"]!=23281)

    # test enabling/disabling of individual measurements
    self.delayDisplay("Test disabling of individual measurements")
    segStatLogic = SegmentStatisticsLogic()
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("ScalarVolume", masterVolumeNode.GetID())
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.voxel_count.enabled",str(False))
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.volume_cm3.enabled",str(False))
    segStatLogic.computeStatistics()
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    columnHeaders = [resultsTableNode.GetColumnName(i) for i in range(resultsTableNode.GetNumberOfColumns())]
    self.assertFalse('Number of voxels [voxels] (1)' in columnHeaders)
    self.assertTrue('Volume [mm3] (1)' in columnHeaders)
    self.assertFalse('Volume [cm3] (3)' in columnHeaders)

    self.delayDisplay("Test re-enabling of individual measurements")
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.voxel_count.enabled",str(True))
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.volume_cm3.enabled",str(True))
    segStatLogic.computeStatistics()
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    columnHeaders = [resultsTableNode.GetColumnName(i) for i in range(resultsTableNode.GetNumberOfColumns())]
    self.assertTrue('Number of voxels [voxels] (1)' in columnHeaders)
    self.assertTrue('Volume [mm3] (1)' in columnHeaders)
    self.assertTrue('Volume [cm3] (1)' in columnHeaders)

    # test enabling/disabling of individual plugins
    self.delayDisplay("Test disabling of plugin")
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.enabled",str(False))
    segStatLogic.computeStatistics()
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    columnHeaders = [resultsTableNode.GetColumnName(i) for i in range(resultsTableNode.GetNumberOfColumns())]
    self.assertFalse('Number of voxels [voxels] (3)' in columnHeaders)
    self.assertFalse('Volume [mm3] (3)' in columnHeaders)
    self.assertTrue('Volume [mm3] (2)' in columnHeaders)

    self.delayDisplay("Test re-enabling of plugin")
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.enabled",str(True))
    segStatLogic.computeStatistics()
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    columnHeaders = [resultsTableNode.GetColumnName(i) for i in range(resultsTableNode.GetNumberOfColumns())]
    self.assertTrue('Number of voxels [voxels] (2)' in columnHeaders)
    self.assertTrue('Volume [mm3] (3)' in columnHeaders)

    # test unregistering/registering of plugins
    self.delayDisplay("Test of removing all registered plugins")
    SegmentStatisticsLogic.registeredPlugins = [] # remove all registered plugins
    segStatLogic = SegmentStatisticsLogic()
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("ScalarVolume", masterVolumeNode.GetID())
    segStatLogic.computeStatistics()
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    columnHeaders = [resultsTableNode.GetColumnName(i) for i in range(resultsTableNode.GetNumberOfColumns())]
    self.assertEqual(len(columnHeaders),1) # only header element should be "Segment"
    self.assertEqual(columnHeaders[0],"Segment") # only header element should be "Segment"

    self.delayDisplay("Test registering plugins")
    SegmentStatisticsLogic.registerPlugin(LabelmapSegmentStatisticsPlugin())
    SegmentStatisticsLogic.registerPlugin(ScalarVolumeSegmentStatisticsPlugin())
    SegmentStatisticsLogic.registerPlugin(ClosedSurfaceSegmentStatisticsPlugin())
    segStatLogic = SegmentStatisticsLogic()
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("ScalarVolume", masterVolumeNode.GetID())
    segStatLogic.computeStatistics()
    segStatLogic.exportToTable(resultsTableNode)
    segStatLogic.showTable(resultsTableNode)
    columnHeaders = [resultsTableNode.GetColumnName(i) for i in range(resultsTableNode.GetNumberOfColumns())]
    self.assertTrue('Number of voxels [voxels] (1)' in columnHeaders)
    self.assertTrue('Number of voxels [voxels] (2)' in columnHeaders)
    self.assertTrue('Surface area [mm2]' in columnHeaders)

    self.delayDisplay('test_SegmentStatisticsPlugins passed!')
Ejemplo n.º 41
0
    def test_sceneImport24281(self):
        """ Ideally you should have several levels of tests.  At the lowest level
    tests should exercise the functionality of the logic with different inputs
    (both valid and invalid).  At higher levels your tests should emulate the
    way the user would interact with your code and confirm that it still works
    the way you intended.
    One of the most important features of the tests is that it should alert other
    developers when their changes will have an impact on the behavior of your
    module.  For example, if a developer removes a feature that you depend on,
    your test should break so they know that the feature is needed.
    """

        self.delayDisplay("Starting the test")
        #
        # first, get some data
        #
        self.delayDisplay("Getting Data")
        import SampleData
        head = SampleData.downloadSample("MRHead")

        # Create segmentation
        segmentationNode = slicer.vtkMRMLSegmentationNode()
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(head)

        # Add a few segments
        segments = [["Segment A", [0, 65, 32], 25, [1.0, 0.0, 0.0]],
                    ["Segment B", [1, -14, 30], 30, [1.0, 1.0, 0.0]],
                    ["Segment C", [0, 28, -7], 15, [0.0, 1.0, 1.0]],
                    ["Segment D", [31, 33, 27], 25, [0.0, 0.0, 1.0]]]
        for [name, position, radius, color] in segments:
            seed = vtk.vtkSphereSource()
            seed.SetCenter(position)
            seed.SetRadius(radius)
            seed.Update()
            segmentationNode.AddSegmentFromClosedSurfaceRepresentation(
                seed.GetOutput(), name, color)

        # Export to labelmap volume
        headLabel = slicer.mrmlScene.AddNewNodeByClass(
            'vtkMRMLLabelMapVolumeNode')
        slicer.modules.segmentations.logic(
        ).ExportVisibleSegmentsToLabelmapNode(segmentationNode, headLabel,
                                              head)

        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetActiveVolumeID(head.GetID())
        selectionNode.SetActiveLabelVolumeID(headLabel.GetID())
        slicer.app.applicationLogic().PropagateVolumeSelection(0)

        #
        # now build:
        # create a model using the command line module
        # based on the current editor parameters
        # - make a new hierarchy node
        #

        self.delayDisplay("Building...")

        parameters = {}
        parameters["InputVolume"] = headLabel.GetID()
        # create models for all labels
        parameters["JointSmoothing"] = True
        parameters["StartLabel"] = -1
        parameters["EndLabel"] = -1
        outHierarchy = slicer.vtkMRMLModelHierarchyNode()
        outHierarchy.SetScene(slicer.mrmlScene)
        outHierarchy.SetName("sceneImport2428Hierachy")
        slicer.mrmlScene.AddNode(outHierarchy)
        parameters["ModelSceneFile"] = outHierarchy

        modelMaker = slicer.modules.modelmaker
        self.CLINode = None
        self.CLINode = slicer.cli.runSync(modelMaker,
                                          self.CLINode,
                                          parameters,
                                          delete_temporary_files=False)

        self.delayDisplay("Models built")

        success = self.verifyModels()

        success = success and (
            slicer.mrmlScene.GetNumberOfNodesByClass("vtkMRMLModelNode") > 3)

        self.delayDisplay("Test finished")

        if success:
            self.delayDisplay("Ahh... test passed.")
        else:
            self.delayDisplay("!$!$!#!@#!@!@$%! Test Failed!!")

        self.assertTrue(success)