Ejemplo n.º 1
0
    def startSegmentation(self):
        if self.segmentationStarted:
          # Already started
          return
        self.segmentationStarted = True
        print("Start ." + str(self.detailedAirways) + ".")
        import time
        startTime = time.time()

        # Clear previous segmentation
        if self.outputSegmentation:
            self.outputSegmentation.GetSegmentation().RemoveAllSegments()

        if not self.rightLungFiducials:
            self.rightLungFiducials = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode", "R")
            self.rightLungFiducials.CreateDefaultDisplayNodes()
            self.rightLungFiducials.GetDisplayNode().SetSelectedColor(self.brighterColor(self.rightLungColor))
        if not self.leftLungFiducials:
            self.leftLungFiducials = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode", "L")
            self.leftLungFiducials.CreateDefaultDisplayNodes()
            self.leftLungFiducials.GetDisplayNode().SetSelectedColor(self.brighterColor(self.leftLungColor))
        if not self.tracheaFiducials:
            self.tracheaFiducials = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode", "T")
            self.tracheaFiducials.CreateDefaultDisplayNodes()
            self.tracheaFiducials.GetDisplayNode().SetSelectedColor(self.brighterColor(self.tracheaColor))
        if not self.resampledVolume:
            self.resampledVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", "Resampled Volume")

        # Create resampled volume with fixed 2.0mm spacing (for faster, standardized workflow)
        self.showStatusMessage('Resampling volume, please wait...')
        parameters = {"outputPixelSpacing": "2.0,2.0,2.0", "InputVolume": self.inputVolume, "interpolationType": "linear", "OutputVolume": self.resampledVolume}
        cliParameterNode = slicer.cli.runSync(slicer.modules.resamplescalarvolume, None, parameters)
        slicer.mrmlScene.RemoveNode(cliParameterNode)

        if not self.outputSegmentation:
            self.outputSegmentation = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode", "Lung segmentation")
            self.outputSegmentation.CreateDefaultDisplayNodes()
        # We show the current segmentation using markups, so let's hide the display node (seeds)
        self.rightLungSegmentId = None
        self.leftLungSegmentId = None
        self.tracheaSegmentId = None
        self.outputSegmentation.GetDisplayNode().SetVisibility(False)
        self.outputSegmentation.SetReferenceImageGeometryParameterFromVolumeNode(self.resampledVolume)

        # Create temporary segment editor to get access to effects
        self.segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        self.segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
        self.segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        self.segmentEditorWidget.setSegmentationNode(self.outputSegmentation)
        if self.detailedAirways: 
            self.segmentEditorWidget.setMasterVolumeNode(self.inputVolume)
        else: 
            self.segmentEditorWidget.setMasterVolumeNode(self.resampledVolume)

        self.segmentEditorWidget.mrmlSegmentEditorNode().SetMasterVolumeIntensityMask(True)
        self.segmentEditorWidget.mrmlSegmentEditorNode().SetMasterVolumeIntensityMaskRange(self.lungThresholdMin, self.lungThresholdMax)

        stopTime = time.time()
        logging.info('StartSegmentation completed in {0:.2f} seconds'.format(stopTime-startTime))
Ejemplo n.º 2
0
 def __init__(self, parent=None):
     """
 Called when the user opens the module the first time and the widget is initialized.
 """
     ScriptedLoadableModuleWidget.__init__(self, parent)
     VTKObservationMixin.__init__(
         self)  # needed for parameter node observation
     self.logic = None
     self._parameterNode = None
     # 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)
     if not segmentEditorWidget.effectByName("Wrap Solidify"):
         if slicer.util.confirmOkCancelDisplay(
                 "SegmentEndocranium requires installation of the SurfaceWrapSolidify extension.\nClick OK to install and restart the application."
         ):
             extensionName = 'SurfaceWrapSolidify'
             em = slicer.app.extensionsManagerModel()
             if not em.isExtensionInstalled(extensionName):
                 extensionMetaData = em.retrieveExtensionMetadataByName(
                     extensionName)
                 url = f"{em.serverUrl().toString()}/api/v1/item/{extensionMetaData['_id']}/download"
                 extensionPackageFilename = slicer.app.temporaryPath + '/' + extensionMetaData[
                     '_id']
                 slicer.util.downloadFile(url, extensionPackageFilename)
                 em.interactive = False  # Disable popups (automatically install dependencies)
                 em.installExtension(extensionPackageFilename)
                 slicer.util.restart()
Ejemplo n.º 3
0
def seged(op, op_config, node, node_config, model, model_config):
    """Segment editor processing."""
    sew = slicer.qMRMLSegmentEditorWidget()
    sew.setMRMLScene(slicer.mrmlScene)
    sen = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentEditorNode")
    sew.setMRMLSegmentEditorNode(sen)
    segmentation = node.GetSegmentation()
    sew.setSegmentationNode(node)
    sew.setActiveEffectByName(op["action"])

    if not op["targets"]:
        op["targets"] = range(segmentation.GetNumberOfSegments())

    if "master" in node_config:
        mv = model_config["inputs"][node_config["master"]]["value"]
    else:
        mv = None
    sew.setMasterVolumeNode(mv)

    for n in op["targets"]:
        logging.info("- Applying to segment %d" % n)

        sew.setCurrentSegmentID(segmentation.GetNthSegmentID(n))
        effect = sew.activeEffect()
        if effect is None:
            raise Exception("Unknown seged action: %s" % op["action"])

        for p, v in op_config["params"].items():
            effect.setParameter(p, str(v))

        effect.self().onApply()

    sew.setActiveEffectByName(None)
    slicer.mrmlScene.RemoveNode(sen)
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    def setup(self):
        """
    Called when the user opens the module the first time and the widget is initialized.
    """
        ScriptedLoadableModuleWidget.setup(self)

        # Load widget from .ui file (created by Qt Designer)
        uiWidget = slicer.util.loadUI(self.resourcePath('UI/BreastCalc.ui'))
        self.layout.addWidget(uiWidget)
        self.ui = slicer.util.childWidgetVariables(uiWidget)

        # Set scene in MRML widgets. Make sure that in Qt designer
        # "mrmlSceneChanged(vtkMRMLScene*)" signal in is connected to each MRML widget's.
        # "setMRMLScene(vtkMRMLScene*)" slot.
        uiWidget.setMRMLScene(slicer.mrmlScene)

        # Example of adding widgets dynamically (without Qt designer).
        # This approach is not recommended, but only shown as an illustrative example.
        self.invertedOutputSelector = slicer.qMRMLNodeComboBox()
        self.invertedOutputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.invertedOutputSelector.addEnabled = True
        self.invertedOutputSelector.removeEnabled = True
        self.invertedOutputSelector.noneEnabled = True
        self.invertedOutputSelector.setMRMLScene(slicer.mrmlScene)
        self.invertedOutputSelector.setToolTip(
            "Result with inverted threshold will be written into this volume")

        # Create a new parameterNode
        # This parameterNode stores all user choices in parameter values, node selections, etc.
        # so that when the scene is saved and reloaded, these settings are restored.
        self.logic = BreastCalcLogic()

        # Connections
        #self.ui.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.ui.confirmButton.connect('clicked(bool)', self.onConfirmButton)
        self.ui.imageThresholdSliderWidget.connect('valueChanged(double)',
                                                   self.onThresholdSlider)

        self.segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        self.segmentationNode.CreateDefaultDisplayNodes(
        )  # only needed for display

        # Create temporary segment editor to get access to effects
        self.segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        self.segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        self.segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        self.segmentEditorWidget.setMRMLSegmentEditorNode(
            self.segmentEditorNode)
        self.segmentEditorWidget.setSegmentationNode(self.segmentationNode)

        self.mode = 0
Ejemplo n.º 6
0
 def __init__(self):
     StepBasedSession.__init__(self)
     self.seriesTypeManager = SeriesTypeManager()
     self.seriesTypeManager.addEventObserver(
         self.seriesTypeManager.SeriesTypeManuallyAssignedEvent,
         lambda caller, event: self.invokeEvent(
             self.SeriesTypeManuallyAssignedEvent))
     self.targetingPlugin = TargetsDefinitionPlugin(self)
     self.needlePathCaculator = ZFrameGuidanceComputation(self)
     self.segmentationEditor = slicer.qMRMLSegmentEditorWidget()
     self.resetAndInitializeMembers()
     self.resetAndInitializedTargetsAndSegments()
  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.º 8
0
    def TestSection_04_qMRMLSegmentatEditorWidget(self):
        logging.info('Test section 4: qMRMLSegmentatEditorWidget')

        self.segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            'vtkMRMLSegmentEditorNode')
        self.assertIsNotNone(self.segmentEditorNode)

        displayNode = self.inputSegmentationNode.GetDisplayNode()
        self.assertIsNotNone(displayNode)

        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLSegmentEditorNode(self.segmentEditorNode)
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorWidget.setSegmentationNode(self.inputSegmentationNode)
        segmentEditorWidget.installKeyboardShortcuts(segmentEditorWidget)
        segmentEditorWidget.setFocus(qt.Qt.OtherFocusReason)
        segmentEditorWidget.show()

        self.segmentEditorNode.SetSelectedSegmentID('first')

        segmentEditorWidget.selectNextSegment()
        selectedSegmentID = self.segmentEditorNode.GetSelectedSegmentID()
        self.assertEqual(selectedSegmentID, 'second')

        segmentEditorWidget.selectPreviousSegment()
        selectedSegmentID = self.segmentEditorNode.GetSelectedSegmentID()
        self.assertEqual(selectedSegmentID, 'first')

        displayNode.SetSegmentVisibility('second', False)
        segmentEditorWidget.selectNextSegment()
        selectedSegmentID = self.segmentEditorNode.GetSelectedSegmentID()
        self.assertEqual(selectedSegmentID, 'third')

        # Trying to go out of bounds past first segment
        segmentEditorWidget.selectPreviousSegment()  #First
        selectedSegmentID = self.segmentEditorNode.GetSelectedSegmentID()
        self.assertEqual(selectedSegmentID, 'first')
        segmentEditorWidget.selectPreviousSegment()  #First
        selectedSegmentID = self.segmentEditorNode.GetSelectedSegmentID()
        self.assertEqual(selectedSegmentID, 'first')
        segmentEditorWidget.selectPreviousSegment()  #First
        selectedSegmentID = self.segmentEditorNode.GetSelectedSegmentID()
        self.assertEqual(selectedSegmentID, 'first')

        # Wrap around
        self.segmentEditorNode.SetSelectedSegmentID('third')
        segmentEditorWidget.selectNextSegment()
        self.assertEqual(selectedSegmentID, 'first')
Ejemplo n.º 9
0
  def _setupSegmentEditorWidget(self):
    self._segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
    self._segmentEditorWidget.hide()
    self._segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

    segmentEditorSingletonTag = "SegmentEditor"
    self.segmentEditorNode = slicer.mrmlScene.GetSingletonNode(segmentEditorSingletonTag, "vtkMRMLSegmentEditorNode")
    if not self.segmentEditorNode:
      self.segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
      self.segmentEditorNode.SetSingletonTag(segmentEditorSingletonTag)
      self.segmentEditorNode = slicer.mrmlScene.AddNode(self.segmentEditorNode)

    self._segmentEditorWidget.setMRMLSegmentEditorNode(self.segmentEditorNode)
    self.segmentEditorWidget.setSegmentationNode(self.segmentationNode)
    self.logic.scriptedEffect = self._segmentEditorWidget.effectByName('Surface cut')
    self.layout.addWidget(self._segmentEditorWidget, 1, 0)
Ejemplo n.º 10
0
 def setupSegmentEditor(self):
     self.segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
     self.segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
     self.segmentEditorWidget.visible = False
     self.segmentEditorWidget.setSegmentationNodeSelectorVisible(False)
     self.segmentEditorWidget.setMasterVolumeNodeSelectorVisible(False)
     self.segmentEditorWidget.setSwitchToSegmentationsButtonVisible(False)
     self.segmentEditorWidget.findChild(qt.QPushButton,
                                        "AddSegmentButton").hide()
     self.segmentEditorWidget.findChild(qt.QPushButton,
                                        "RemoveSegmentButton").hide()
     self.segmentEditorWidget.findChild(ctk.ctkMenuButton,
                                        "Show3DButton").hide()
     self.segmentEditorWidget.findChild(
         ctk.ctkExpandableWidget, "SegmentsTableResizableFrame").hide()
     self.segmentEditorWidget.setSizePolicy(qt.QSizePolicy.Maximum,
                                            qt.QSizePolicy.Expanding)
    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')
Ejemplo n.º 12
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.º 13
0
    def run(self, inputVolume, outputSegmentation, smoothingKernelSize=3.0):
        """
    Run the processing algorithm.
    Can be used without GUI widget.
    :param inputVolume: volume to be segmented
    :param outputSegmentation: segmentation to sore the result in
    :param smoothingKernelSize: this is used for closing small holes in the segmentation
    """

        if not inputVolume or not outputSegmentation:
            raise ValueError("Input volume or output segmentation is invalid")

        logging.info('Processing started')

        # Compute bone threshold value automatically
        import vtkITK
        thresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()
        thresholdCalculator.SetInputData(inputVolume.GetImageData())
        thresholdCalculator.SetMethodToOtsu()
        thresholdCalculator.Update()
        boneThresholdValue = thresholdCalculator.GetThreshold()
        volumeScalarRange = inputVolume.GetImageData().GetScalarRange()
        logging.debug(
            "Volume minimum = {0}, maximum = {1}, bone threshold = {2}".format(
                volumeScalarRange[0], volumeScalarRange[1],
                boneThresholdValue))

        # Set up segmentation
        outputSegmentation.CreateDefaultDisplayNodes()
        outputSegmentation.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolume)

        # 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)
        if not segmentEditorWidget.effectByName("Wrap Solidify"):
            raise NotImplementedError(
                "SurfaceWrapSolidify extension is required")

        segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(outputSegmentation)
        segmentEditorWidget.setMasterVolumeNode(inputVolume)

        # Create bone segment by thresholding
        boneSegmentID = outputSegmentation.GetSegmentation().AddEmptySegment(
            "bone")
        segmentEditorNode.SetSelectedSegmentID(boneSegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", str(boneThresholdValue))
        effect.setParameter("MaximumThreshold", str(volumeScalarRange[1]))
        effect.self().onApply()

        # Smooth bone segment (just to reduce solidification computation time)
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING")
        effect.setParameter("KernelSizeMm", str(smoothingKernelSize))
        effect.self().onApply()

        # Solidify bone
        segmentEditorWidget.setActiveEffectByName("Wrap Solidify")
        effect = segmentEditorWidget.activeEffect()
        effect.self().onApply()

        # Create segment for cavity within bone region using thresholding
        segmentEditorNode.SetOverwriteMode(
            slicer.vtkMRMLSegmentEditorNode.OverwriteNone)
        segmentEditorNode.SetMaskMode(
            slicer.vtkMRMLSegmentEditorNode.PaintAllowedInsideAllSegments)
        cavitySegmentID = outputSegmentation.GetSegmentation().AddEmptySegment(
            "cavity")
        segmentEditorNode.SetSelectedSegmentID(cavitySegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", str(volumeScalarRange[0]))
        effect.setParameter("MaximumThreshold", str(boneThresholdValue))
        effect.self().onApply()

        # Cavity shrink
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", str(-smoothingKernelSize))
        effect.self().onApply()

        # Find largest cavity
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameterDefault("Operation", "KEEP_LARGEST_ISLAND")
        effect.self().onApply()

        # Cavity restore
        segmentEditorNode.SetMaskMode(
            slicer.vtkMRMLSegmentEditorNode.PaintAllowedInsideAllSegments
        )  # ensure we don't leak into bone
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", str(smoothingKernelSize))
        effect.self().onApply()

        # Clean up
        slicer.mrmlScene.RemoveNode(segmentEditorNode)
        outputSegmentation.RemoveSegment(boneSegmentID)
        segmentEditorWidget = None

        logging.info('Processing completed')
Ejemplo n.º 14
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)
        # Add margin to the sides
        self.layout.setContentsMargins(8, 0, 8, 0)
        #
        # Pre-Setup
        #
        self.previewImageNodesCollapsibleButton = ctk.ctkCollapsibleButton()
        self.previewImageNodesCollapsibleButton.text = "Image Nodes"
        self.layout.addWidget(self.previewImageNodesCollapsibleButton)
        self.previewImageNodesCollapsibleButton.collapsed = False  #True
        presetPS = qt.QFormLayout(self.previewImageNodesCollapsibleButton)

        self.grayscaleSelectorFrame = qt.QFrame(self.parent)
        self.grayscaleSelectorFrame.setLayout(
            qt.QHBoxLayout())  #qt.QHBoxLayout()
        self.parent.layout().addWidget(self.grayscaleSelectorFrame)

        self.grayscaleSelectorLabel = qt.QLabel("Gray Image: ",
                                                self.grayscaleSelectorFrame)
        self.grayscaleSelectorLabel.setToolTip(
            "Select the grayscale volume (background grayscale scalar volume node) for statistics calculations"
        )

        self.grayscaleSelectorFrame.layout().addWidget(
            self.grayscaleSelectorLabel)

        self.grayscaleSelector = slicer.qMRMLNodeComboBox(
        )  # self.grayscaleSelectorFrame)
        self.grayscaleSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.grayscaleSelector.selectNodeUponCreation = False
        self.grayscaleSelector.addEnabled = False
        self.grayscaleSelector.removeEnabled = False
        self.grayscaleSelector.noneEnabled = True
        self.grayscaleSelector.showHidden = False
        self.grayscaleSelector.showChildNodeTypes = False
        self.grayscaleSelector.setMRMLScene(slicer.mrmlScene)
        self.grayscaleSelector.setToolTip(
            'Setting to pick up as slicer.mrmlScene')
        self.grayscaleSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                       self.onGrayscaleSelect)

        self.grayscaleSelectorFrame.layout().addWidget(self.grayscaleSelector)

        presetPS.addRow(self.grayscaleSelectorFrame)
        # hide this part, no use  . .... aiden 2019.08.13

        #...........................................................................................................................
        self.labelSelectorFrame = qt.QFrame(
            self.parent
        )  # original code: no-definition of parent self.labelSelectorFrame = qt.QFrame()
        self.labelSelectorFrame.setLayout(qt.QHBoxLayout())
        #self.labelSelectorFrame.setToolTip('Where am I? self.labelSelectorFrame')
        self.parent.layout().addWidget(self.labelSelectorFrame)

        self.labelSelectorLabel = qt.QLabel()
        self.labelSelectorLabel.setText("Label Map: ")

        self.labelSelectorFrame.layout().addWidget(self.labelSelectorLabel)

        self.labelSelector = slicer.qMRMLNodeComboBox()
        self.labelSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.labelSelector.selectNodeUponCreation = False
        self.labelSelector.addEnabled = False
        self.labelSelector.noneEnabled = True
        self.labelSelector.removeEnabled = False
        self.labelSelector.showHidden = False
        self.labelSelector.showChildNodeTypes = True
        self.labelSelector.setMRMLScene(slicer.mrmlScene)
        self.labelSelector.setToolTip("Pick the label map to edit")
        self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onLabelSelect)

        self.labelSelectorFrame.layout().addWidget(self.labelSelector)

        # Load label into segmentation
        self.applyLabelMapToSegmentationButton = qt.QPushButton(
            'Labels to Segments')
        self.applyLabelMapToSegmentationButton.setToolTip(
            'Pick up a label-map and convert to segments')
        self.applyLabelMapToSegmentationButton.connect(
            'clicked(bool)', self.onApplyLabels2Segments)
        self.labelSelectorFrame.layout().addWidget(
            self.applyLabelMapToSegmentationButton)
        #...........................................................................................................................
        presetPS.addRow(self.labelSelectorFrame)

        #
        #BeFixed CheckBox
        # under development.............The goal is try to get customized settings to fix some segments during segment-editing
        #
        self.setBeFixedCheckBox = ctk.ctkCollapsibleButton()
        self.setBeFixedCheckBox.text = 'Set up Fixed Segments'
        self.setBeFixedCheckBox.collapsed = False
        self.layout.addWidget(self.setBeFixedCheckBox)

        beFixedFormLayout = qt.QFormLayout(self.setBeFixedCheckBox)

        self.setBeFixedCheckBox = []

        qt_form1 = qt.QFrame(self.parent)
        qt_form1_layout = qt.QHBoxLayout()
        qt_form1.setLayout(qt_form1_layout)

        for i_chbx in range(10):
            tmp_s = str(i_chbx)
            #print(tmp_s)
            CheckBox = qt.QCheckBox(tmp_s)
            CheckBox.checked = False
            CheckBox.setToolTip('Segment # ' + str(i_chbx))
            #CheckBox.setFixedWidth(25)
            CheckBox.connect('clicked(bool)', self.onCheckBoxBeFixedUpdated)
            self.setBeFixedCheckBox.append(CheckBox)
            qt_form1.layout().addWidget(CheckBox)

        beFixedFormLayout.addRow(qt_form1)

        qt_form2 = qt.QFrame()
        qt_form2_layout = qt.QHBoxLayout()
        qt_form2.setLayout(qt_form2_layout)

        for i_chbx in range(10, 20, 1):
            tmp_s = str(i_chbx)
            #print(tmp_s)
            CheckBox = qt.QCheckBox(tmp_s)
            CheckBox.checked = False
            CheckBox.setToolTip('Segment # ' + str(i_chbx))
            #CheckBox.setFixedWidth(25)
            CheckBox.connect('clicked(bool)', self.onCheckBoxBeFixedUpdated)
            self.setBeFixedCheckBox.append(CheckBox)
            qt_form2.layout().addWidget(CheckBox)

        beFixedFormLayout.addRow(qt_form2)

        # set them up to be disabled and hiden
        for i in range(20):
            self.setBeFixedCheckBox[i].enabled = False
            self.setBeFixedCheckBox[i].hide()
        #
        # Above still under development
        #print('&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&')
        #

        #
        # Segment editor widget
        #
        #
        #import qSlicerSegmentationsModuleWidgetsPythonQt
        #self.editor = qSlicerSegmentationsModuleWidgetsPythonQt.qMRMLSegmentEditorWidget()
        self.editor = slicer.qMRMLSegmentEditorWidget()
        #slicer.util.delayDisplay('edited: self.editor = qSlicerSegmentationsModuleWidgetsPythonQt.qMRMLSegmentEditorWidget() ')
        #self.editor.switchToSegmentationsButtonVisible =True

        #print(get_class_members(self.editor))
        #print(get_object_attrs(self.editor))

        self.editor.setMaximumNumberOfUndoStates(15)
        # Set parameter node first so that the automatic selections made when the scene is set are saved
        self.selectParameterNode()
        self.editor.setMRMLScene(slicer.mrmlScene)

        self.layout.addWidget(
            self.editor)  # adding the Widgets here to the layout

        # Observe editor effect registrations to make sure that any effects that are registered
        # later will show up in the segment editor widget. For example, if Segment Editor is set
        # as startup module, additional effects are registered after the segment editor widget is created.

        #Events of onSegmentAddedRemoved???
        #self.addObserver(self.editor, self.editor.InvokeCustomModifiedEvent, self.editorAddOrRemoveSegments)

        #Modified by Aiden
        #import qSlicerSegmentationsEditorEffectsPythonQt
        #TODO: For some reason the instance() function cannot be called as a class function although it's static
        #factory = qSlicerSegmentationsEditorEffectsPythonQt.qSlicerSegmentEditorEffectFactory()

        #qSlicerSegmentEditorEffectFactory--> Singleton class managing segment editor effect plugins.
        factory = slicer.qSlicerSegmentEditorEffectFactory()

        #slicer.util.delayDisplay('factory = qSlicerSegmentationsEditorEffectsPythonQt.qSlicerSegmentEditorEffectFactory()')
        self.effectFactorySingleton = factory.instance()
        self.effectFactorySingleton.connect('effectRegistered(QString)',
                                            self.editorEffectRegistered)

        # Connect observers to scene events
        self.addObserver(slicer.mrmlScene, slicer.mrmlScene.StartCloseEvent,
                         self.onSceneStartClose)
        self.addObserver(slicer.mrmlScene, slicer.mrmlScene.EndCloseEvent,
                         self.onSceneEndClose)
        self.addObserver(slicer.mrmlScene, slicer.mrmlScene.EndImportEvent,
                         self.onSceneEndImport)

        # It seems it will work until a 3D-view exists
        layoutManager = slicer.app.layoutManager()
        if layoutManager:
            threeDWidget = layoutManager.threeDWidget(0)
            threeDView = threeDWidget.threeDView()
            threeDView.resetFocalPoint()
    def run(self,
            inputVolume,
            imageThreshold_min,
            imageThreshold_max,
            minimumVoxelsize,
            tls_per_min,
            enableScreenshots=0):
        """
    Run the actual algorithm
    """

        if not self.isValidInputData(inputVolume):
            slicer.util.errorDisplay('Input volume error.')
            return False

        logging.info('Processing started')

        masterVolumeNode = inputVolume

        # Create segmentation
        SegmentationNodeCol = slicer.mrmlScene.GetNodesByClass(
            "vtkMRMLSegmentationNode")
        SegmentationNodeCol.UnRegister(slicer.mrmlScene)
        b = True
        for SegmentationNode in SegmentationNodeCol:
            if SegmentationNode.GetName() == "rc_seg":
                SegmentationNode.GetSegmentation().RemoveAllSegments()
                SegmentationNode.GetDisplayNode(
                ).ClearSegmentDisplayProperties()
                print("segmantation rc_seg cleared ")
                b = False
                break

        if b:
            SegmentationNode = slicer.mrmlScene.AddNewNodeByClass(
                "vtkMRMLSegmentationNode")
            SegmentationNode.UnRegister(slicer.mrmlScene)
            SegmentationNode.SetName("rc_seg")
            print("segmantation created : ", SegmentationNode.GetName())
            SegmentationNode.CreateDefaultDisplayNodes(
            )  # only needed for display
            SegmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
                masterVolumeNode)

        addedSegmentID = SegmentationNode.GetSegmentation().AddEmptySegment(
            SegmentationNode.GetName() + "_")

        # Create temporary segment editor to get access to effects
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorNode.SetSelectedSegmentID(addedSegmentID)

        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(SegmentationNode)
        segmentEditorWidget.setMasterVolumeNode(masterVolumeNode)

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

        # Fill by thresholding

        effect.setParameter("MinimumThreshold", str(imageThreshold_min))
        effect.setParameter("MaximumThreshold", str(imageThreshold_max))
        effect.self().onApply()

        # Fill by thresholding
        if minimumVoxelsize is not None:
            segmentEditorWidget.setActiveEffectByName("Islands")
            effect = segmentEditorWidget.activeEffect()
            effect.setParameter("Operation", "SPLIT_ISLANDS_TO_SEGMENTS")
            effect.setParameter("MinimumSize", minimumVoxelsize)
            effect.self().onApply()

        # Compute segment volumes
        resultsTableNode = slicer.mrmlScene.AddNewNodeByClass(
            'vtkMRMLTableNode')
        resultsTableNode.UnRegister(slicer.mrmlScene)

        import SegmentStatistics
        segStatLogic = SegmentStatistics.SegmentStatisticsLogic()
        segStatLogic.getParameterNode().SetParameter("Segmentation",
                                                     SegmentationNode.GetID())
        segStatLogic.getParameterNode().SetParameter("ScalarVolume",
                                                     masterVolumeNode.GetID())

        segStatLogic.getParameterNode().SetParameter(
            "ClosedSurfaceSegmentStatisticsPlugin.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ClosedSurfaceSegmentStatisticsPlugin.surface_mm2.enabled",
            "False")
        segStatLogic.getParameterNode().SetParameter(
            "ClosedSurfaceSegmentStatisticsPlugin.volume_cm3.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ClosedSurfaceSegmentStatisticsPlugin.volume_mm3.enabled", "False")

        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.volume_cm3.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.volume_mm3.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "LabelmapSegmentStatisticsPlugin.voxel_count.enabled", "False")

        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.enabled", "True")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.max.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.mean.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.median.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.min.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.stdev.enabled", "False")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.volume_mm3.enabled", "True")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.volume_cm3.enabled", "True")
        segStatLogic.getParameterNode().SetParameter(
            "ScalarVolumeSegmentStatisticsPlugin.voxel_count.enabled", "False")

        segStatLogic.computeStatistics()
        segStatLogic.exportToTable(resultsTableNode)
        col = resultsTableNode.AddColumn()
        col.SetName("Time of lithotripsy [min:sec:1/100s]")
        id_colone_vmm3 = resultsTableNode.GetColumnIndex("Volume [mm3]")
        id_colone_Tl = resultsTableNode.GetColumnIndex(
            "Time of lithotripsy [min:sec:1/100s]")

        import math
        for i in range(resultsTableNode.GetNumberOfRows()):
            vol_i = float(resultsTableNode.GetCellText(i, id_colone_vmm3))
            tl_i = math.modf(vol_i / tls_per_min)
            tl_i_min = int(tl_i[1])
            tli_1 = math.modf(60. * tl_i[0])
            tli_sec = int(tli_1[1])
            tli_cent = 100 * tli_1[0]
            resultsTableNode.SetCellText(
                i, id_colone_Tl,
                "{:d}:{:d}:{:.0f}".format(tl_i_min, tli_sec, tli_cent))

        segStatLogic.showTable(resultsTableNode)

        logging.info('Processing completed !')

        return True
Ejemplo n.º 16
0
  def test_SegmentEditorHollow1(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: SegmentEditorHollow)
    """

    self.delayDisplay("Starting test_SegmentEditorHollow1")

    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("Hollow")
    effect = segmentEditorWidget.activeEffect()
    effect.setParameter("ShellThicknessMm", 3.0)
    effect.setParameter("ShellMode", "MEDIAL_SURFACE")
    
    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('test_SegmentEditorHollow1 passed')
    def process_segmentation(threshold_range, image, update_status):
        print(threshold_range)

        # Fix Volume Orientation
        update_status(text="Rotating views to volume plane...", progress=2)
        manager = slicer.app.layoutManager()
        for name in manager.sliceViewNames():
            widget = manager.sliceWidget(name)
            node = widget.mrmlSliceNode()
            node.RotateToVolumePlane(image)

        # Create segmentation
        update_status(text="Creating segmentation...", progress=5)
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            image)
        segmentId = segmentationNode.GetSegmentation().AddEmptySegment("Bone")
        segmentationNode.GetSegmentation().GetSegment(segmentId).SetColor(
            [0.9, 0.8, 0.7])

        # Create segment editor to get access to effects
        update_status(text="Starting segmentation editor...", progress=6)
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(image)

        # Threshold
        update_status(text="Processing threshold segmentation...", progress=8)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold",
                            str(threshold_range[0]))  # 1460 #1160 # 223
        effect.setParameter("MaximumThreshold", str(threshold_range[1]))
        effect.self().onApply()

        # Smoothing
        update_status(text="Processing smoothing segmentation...", progress=10)
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_OPENING")
        effect.setParameter("KernelSizeMm", 0.5)
        effect.self().onApply()

        # Islands
        update_status(text="Processing island segmentation...", progress=11)
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", "KEEP_LARGEST_ISLAND")
        effect.setParameter("MinimumSize", 1000)
        effect.self().onApply()

        # Crop
        # update_status("Cropping segmentation...")
        # segmentEditorWidget.setActiveEffectByName("Scissors")
        # effect = segmentEditorWidget.activeEffect()
        # effect.setParameter("MinimumThreshold", "223")
        # effect.setParameter("MaximumThreshold", "3071")
        # effect.self().onApply()

        # Clean up
        update_status(text="Cleaning up...", progress=13)
        segmentEditorWidget.setActiveEffectByName(None)
        slicer.mrmlScene.RemoveNode(segmentEditorNode)

        # Make segmentation results visible in 3D and set focal
        update_status(text="Rendering...", progress=15)
        segmentationNode.CreateClosedSurfaceRepresentation()

        # Make sure surface mesh cells are consistently oriented
        update_status(text="Retrieving surface mesh...", progress=18)
        polyData = segmentationNode.GetClosedSurfaceRepresentation(segmentId)
        return polyData
Ejemplo n.º 18
0
    def ProceduralSegmentation(self, inputDir, outputDir):

        # Importing Dicom into temporary database
        dicomDataDir = inputDir
        from DICOMLib import DICOMUtils
        loadedNodeIDs = []

        with DICOMUtils.TemporaryDICOMDatabase() as db:
            DICOMUtils.importDicom(dicomDataDir, db)
            patientUIDs = db.patients()
            for patientUID in patientUIDs:
                loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))

# Loading Dicom into scene
        seriesVolumeNode = slicer.util.getNode(loadedNodeIDs[0])
        storageVolumeNode = seriesVolumeNode.CreateDefaultStorageNode()
        slicer.mrmlScene.AddNode(storageVolumeNode)
        storageVolumeNode.UnRegister(slicer.mrmlScene)
        seriesVolumeNode.SetAndObserveStorageNodeID(storageVolumeNode.GetID())

        # Access segmentation module
        slicer.util.selectModule('Segment Editor')
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            seriesVolumeNode)

        # TODO Automate creation of different segments in the future (using some form of -type argument)
        # Create spine segment
        segmentTypeID = "Spine"
        newSegment = slicer.vtkSegment()
        newSegment.SetName(segmentTypeID)
        newSegment.SetColor([0.89, 0.85, 0.78])
        segmentationNode.GetSegmentation().AddSegment(newSegment,
                                                      segmentTypeID)

        # Create segment editor widget to get access to effects
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

        # Access segment editor node
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(seriesVolumeNode)

        # Segment Editor Effect: Thresholding
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", "90")
        effect.setParameter("MaximumThreshold", "1600")
        effect.self().onApply()

        # Setting Closed Surface Representation Values
        segmentationNode.GetSegmentation().SetConversionParameter(
            "Oversampling factor", "1.0")
        segmentationNode.GetSegmentation().SetConversionParameter(
            "Joint smoothing", "0.50")
        segmentationNode.GetSegmentation().SetConversionParameter(
            "Smoothing factor", "0.50")

        # Segment Editor Effect: Smoothing
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        # 2mm MEDIAN Smoothing
        effect.setParameter("SmoothingMethod", "MEDIAN")
        effect.setParameter("KernelSizeMm", 2.5)
        effect.self().onApply()
        # 2mm OPEN Smoothing
        #effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_OPENING")
        #effect.setParameter("KernelSizeMm", 2)
        #effect.self().onApply
        # 1.5mm CLOSED Smoothing
        #effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING")
        #effect.setParameter("KernelSizeMm", 1.5)
        #effect.self().onApply

        # Create Closed Surface Representation
        segmentationNode.CreateClosedSurfaceRepresentation()

        # Export Segmentation to Model Node
        shNode = slicer.mrmlScene.GetSubjectHierarchyNode()
        exportFolderItemId = shNode.CreateFolderItem(shNode.GetSceneItemID(),
                                                     "Segments")
        slicer.modules.segmentations.logic().ExportAllSegmentsToModels(
            segmentationNode, exportFolderItemId)

        segmentID = segmentationNode.GetSegmentation().GetNthSegmentID(0)
        surfaceMesh = segmentationNode.GetClosedSurfaceInternalRepresentation(
            segmentID)

        # Decimate Model
        decimator = vtk.vtkDecimatePro()
        decimator.SplittingOff()
        decimator.PreserveTopologyOn()
        decimator.SetTargetReduction(0.95)
        decimator.SetInputData(surfaceMesh)
        decimator.Update()
        surfaceMesh = decimator.GetOutput()

        # Smooth the Model
        smoothingFactor = 0.5
        smoother = vtk.vtkWindowedSincPolyDataFilter()
        smoother.SetInputData(surfaceMesh)
        smoother.SetNumberOfIterations(50)
        smoother.SetPassBand(pow(10.0, -4.0 * smoothingFactor))
        smoother.BoundarySmoothingOff()
        smoother.FeatureEdgeSmoothingOff()
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()
        smoother.Update()
        surfaceMesh = smoother.GetOutput()

        # Clean up Model
        cleaner = vtk.vtkCleanPolyData()
        #cleaner.PointMergingOff()
        #cleaner.ConvertLinesToPointsOn()
        #cleaner.ConvertPolysToLinesOn()
        #cleaner.ConvertStripsToPolysOn()
        cleaner.SetInputData(surfaceMesh)
        cleaner.Update()
        surfaceMesh = cleaner.GetOutput()

        # Write to OBJ File
        outputFileName = outputDir + "segmentation.obj"
        writer = vtk.vtkOBJWriter()
        writer.SetFileName(outputFileName)
        writer.SetInputData(surfaceMesh)
        writer.Update()

        # Clean up
        segmentEditorWidget = None
        slicer.mrmlScene.RemoveNode(segmentEditorNode)
Ejemplo n.º 19
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        parametersCollapsibleButton.setFont(qt.QFont("Times", 12))
        self.layout.addWidget(parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

        #
        # input volume selector
        #
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = False
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = False
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Input Volume: ", self.inputSelector)

        #
        # ROI selector
        #
        self.ROISelector = slicer.qMRMLNodeComboBox()
        self.ROISelector.nodeTypes = ["vtkMRMLAnnotationROINode"]
        self.ROISelector.selectNodeUponCreation = True
        self.ROISelector.addEnabled = False
        self.ROISelector.removeEnabled = True
        self.ROISelector.noneEnabled = True
        self.ROISelector.showHidden = False
        self.ROISelector.showChildNodeTypes = False
        self.ROISelector.setMRMLScene(slicer.mrmlScene)
        self.ROISelector.setToolTip("Pick the ROI to the algorithm.")
        parametersFormLayout.addRow("Select ROI: ", self.ROISelector)

        #
        # Pectoral Smoothing Iterations Spin Box
        #
        self.pectoralSmoothingIterationSpinBox = qt.QSpinBox()
        self.pectoralSmoothingIterationSpinBox.setRange(0, 20000)
        self.pectoralSmoothingIterationSpinBox.setSingleStep(500)
        self.pectoralSmoothingIterationSpinBox.setValue(4000)
        parametersFormLayout.addRow("Pectoral Smoothing Iterations: ",
                                    self.pectoralSmoothingIterationSpinBox)

        #
        # Breast Implants Collapsible Button
        #
        breastImplantsCollapsibleButton = ctk.ctkCollapsibleButton()
        breastImplantsCollapsibleButton.text = "Breast Implants"
        breastImplantsCollapsibleButton.setFont(qt.QFont("Times", 12))
        breastImplantsCollapsibleButton.collapsed = True
        self.layout.addWidget(breastImplantsCollapsibleButton)

        # Layout within the dummy collapsible button
        breastImplantsFormLayout = qt.QFormLayout(
            breastImplantsCollapsibleButton)

        #
        # Breast implants algorithm hint label
        #
        self.breastImplantsHintLabel = qt.QLabel()
        self.breastImplantsHintLabel.setText(
            "Please pick one point for one side or two points for both sides.")
        # Align Center
        self.breastImplantsHintLabel.setAlignment(4)
        self.breastImplantsHintLabel.setFrameStyle(qt.QFrame.WinPanel)
        self.breastImplantsHintLabel.setFrameShadow(qt.QFrame.Sunken)
        self.breastImplantsHintLabel.setMargin(2)
        self.breastImplantsHintLabel.setFont(
            qt.QFont("Times", 14, qt.QFont.Black))
        breastImplantsFormLayout.addRow(self.breastImplantsHintLabel)

        #
        # GACM initial point selector
        #
        self.pointSelector = slicer.qMRMLNodeComboBox()
        self.pointSelector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"]
        self.pointSelector.selectNodeUponCreation = True
        self.pointSelector.addEnabled = True
        self.pointSelector.removeEnabled = True
        self.pointSelector.noneEnabled = True
        self.pointSelector.showHidden = False
        self.pointSelector.showChildNodeTypes = False
        self.pointSelector.baseName = "P"
        self.pointSelector.setMRMLScene(slicer.mrmlScene)
        self.pointSelector.setToolTip("Pick the initial points for GACM.")
        breastImplantsFormLayout.addRow("Initial Points: ", self.pointSelector)

        #
        # Place the fiducial point(s) on screen
        #
        self.markupPointWidget = slicer.qSlicerMarkupsPlaceWidget()
        self.markupPointWidget.setMRMLScene(slicer.mrmlScene)
        self.markupPointWidget.setPlaceModePersistency(False)
        breastImplantsFormLayout.addRow(self.markupPointWidget)

        #
        # Estimate Volume Button
        #
        self.estimateButton = qt.QPushButton("Estimate Volume")
        self.estimateButton.toolTip = "Run the algorithm."
        self.estimateButton.enabled = False
        self.estimateButton.setFont(qt.QFont("Times", 24, qt.QFont.Black))
        self.layout.addWidget(self.estimateButton)

        #
        # Spacer
        #
        self.spacer = qt.QLabel()
        self.layout.addWidget(self.spacer)

        #
        # Editting Segmentation
        #
        segmentationEditorCollapsibleButton = ctk.ctkCollapsibleButton()
        segmentationEditorCollapsibleButton.text = "Editting Segmentation"
        segmentationEditorCollapsibleButton.setFont(qt.QFont("Times", 12))
        segmentationEditorCollapsibleButton.collapsed = True
        self.layout.addWidget(segmentationEditorCollapsibleButton)

        # Layout within the dummy collapsible button
        segmentationEditorFormLayout = qt.QFormLayout(
            segmentationEditorCollapsibleButton)

        self.segmentationEditorWidget = slicer.qMRMLSegmentEditorWidget()
        self.segmentationEditorWidget.setMaximumNumberOfUndoStates(10)
        self.parameterSetNode = None
        self.selectParameterNode()
        self.segmentationEditorWidget.setSwitchToSegmentationsButtonVisible(
            False)
        self.segmentationEditorWidget.setUndoEnabled(True)
        self.segmentationEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentationEditorFormLayout.addWidget(self.segmentationEditorWidget)

        #
        # Calculate Statistics Button
        #
        self.statButton = qt.QPushButton("Calculate Statistics")
        self.statButton.toolTip = "Calculate statistics."
        self.statButton.enabled = True
        self.statButton.setFont(qt.QFont("Times", 24, qt.QFont.Black))
        segmentationEditorFormLayout.addWidget(self.statButton)

        # connections
        self.estimateButton.connect('clicked(bool)', self.onEstimateButton)
        self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onSelect)
        self.pointSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.setPoint)
        self.segmentationEditorWidget.connect(
            "masterVolumeNodeChanged(vtkMRMLVolumeNode*)", self.saveState)
        self.statButton.connect('clicked(bool)', self.calculateStatistics)

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

        # Refresh Apply button state
        self.onSelect()
  def test_ScriptedSegmentEditorEffectModuleTemplate1(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: SegmentEditorScriptedSegmentEditorEffectModuleTemplate)
    """

    self.delayDisplay("Starting test_ScriptedSegmentEditorEffectModuleTemplate1")

    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.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
    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("ScriptedSegmentEditorEffectModuleTemplate")
    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_ScriptedSegmentEditorEffectModuleTemplate1 passed')
    def run(self, inputVolume, Index):

        logging.info('Processing started')

        DosiFilmImage = inputVolume

        date = datetime.datetime.now()

        # 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'

        # To obtain fiducial position from user
        markups = slicer.util.getNode('F')
        FiducialCoordinatesF1 = [0, 0, 0, 0]
        FiducialCoordinatesF2 = [0, 0, 0, 0]
        FiducialCoordinatesF3 = [0, 0, 0, 0]
        markups.GetNthFiducialWorldCoordinates(0, FiducialCoordinatesF1)
        markups.GetNthFiducialWorldCoordinates(1, FiducialCoordinatesF2)
        markups.GetNthFiducialWorldCoordinates(2, FiducialCoordinatesF3)

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

        # 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(10000))
        effect.setParameter("MaximumThreshold", str(30000))
        effect.self().onApply()

        # Passage en mode closed surface pour calcul des centres
        n = slicer.util.getNode('Segmentation')
        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()

        # Boucle de calcul des centres pour les 7 blocs (segment)
        n = slicer.util.getNode('Segmentation')
        s = n.GetSegmentation()
        ss = s.GetSegment("IrradiatedBlocks")
        pd = ss.GetRepresentation('Closed surface')
        com = vtk.vtkCenterOfMass()
        com.SetInputData(pd)
        com.Update()
        CenterOfBlock = com.GetCenter(
        )  # CenterOfBlock est alors un tuple avec plusieurs variables (coordonées x,y,z)
        XaxisCenterOfBlock = (
            CenterOfBlock[0]
        )  # 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 = (CenterOfBlock[1])
        YaxisCenterOfBlock = abs(
            YaxisCenterOfBlock)  # On passe en valeur absolue
        XaxisCenterOfBlock = abs(
            XaxisCenterOfBlock)  # On passe en valeur absolue

        ######### Calcul des éléments d'intérêt ###########
        VerticalOffsetInMm = (abs((
            (abs(FiducialCoordinatesF1[1]) + abs(FiducialCoordinatesF2[1])) /
            2) - YaxisCenterOfBlock)) * 0.3528
        VerticalDistanceInMm = (
            abs(abs(FiducialCoordinatesF1[1]) -
                abs(FiducialCoordinatesF2[1]))) * 0.3528
        LateralOffsetInMm = (abs(FiducialCoordinatesF3[0]) -
                             XaxisCenterOfBlock) * 0.3528

        ######### Enonciation des résultats ###########
        print(u"\n\nRésultats du test -Real and Virtual Isocentre-\n")
        print("Machine : " + str(machineName) + "\n")
        print(u"Coordonnée X du centre du bloc d'irradiation: " +
              str(XaxisCenterOfBlock) + "\n")
        print(u"Coordonnée Y du centre du bloc d'irradiation: " +
              str(YaxisCenterOfBlock) + "\n")
        print(u"Coordonnée du fiducial F1: " + str(FiducialCoordinatesF1) +
              "\n")
        print(u"Coordonnée du fiducial F1: " + str(FiducialCoordinatesF2) +
              "\n")
        print(u"Coordonnée du fiducial F1: " + str(FiducialCoordinatesF3) +
              "\n\n")
        print(u"Vertical Offset (mm): " + str(VerticalOffsetInMm) + "\n")
        print(u"Vertical Distance (mm): " + str(VerticalDistanceInMm) + "\n")
        print(u"Lateral Offset (mm): " + str(LateralOffsetInMm) + "\n")

        ######### Calcul de la conformité et mention des résultats ###########
        if 0 <= VerticalOffsetInMm < 1:
            ResultVerticalOffset = "Conforme"
        elif VerticalOffsetInMm > 1:
            ResultVerticalOffset = "Hors tolerance"
        else:
            ResultVerticalOffset = "Limite"  #car si pas < ou > à 1 alors = à 1

        print(u"Résultat pour Vertical Offset: " + str(ResultVerticalOffset))

        if 0 <= VerticalDistanceInMm < 1:
            ResultVerticalDistance = "Conforme"
        elif VerticalDistanceInMm > 1:
            ResultVerticalDistance = "Hors tolerance"
        else:
            ResultVerticalDistance = "Limite"  #car si pas < ou > à 1 alors = à 1

        print(u"Résultat pour Vertical Distance: " +
              str(ResultVerticalDistance))

        if 0 <= LateralOffsetInMm < 1:
            ResultLateralOffset = "Conforme"
        elif LateralOffsetInMm > 1:
            ResultLateralOffset = "Hors tolerance"
        else:
            ResultLateralOffset = "Limite"  #car si pas < ou > à 1 alors = à 1

        print(u"Résultat pour Lateral Offset: " + str(ResultLateralOffset) +
              "\n")
        """### Au cas ou problème dans l'image ##
    if  VerticalOffsetInMm or VerticalDistanceInMm or LateralOffsetInMm < 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('Processing completed')

        return True
Ejemplo n.º 22
0
    def run(self,
            inputVolume,
            outputSegmentation,
            smoothingKernelSize=3.0,
            splitCavitiesDiameter=15.0):
        """
    Run the processing algorithm.
    Can be used without GUI widget.
    :param inputVolume: volume to be segmented
    :param outputSegmentation: segmentation to sore the result in
    :param smoothingKernelSize: this is used for closing small holes in the segmentation
    :param splitCavitiesDiameter: plugs in holes smaller than splitCavitiesDiamater.
    """

        if not inputVolume or not outputSegmentation:
            raise ValueError("Input volume or output segmentation is invalid")

        logging.info('Processing started')

        # Compute bone threshold value automatically
        import vtkITK
        thresholdCalculator = vtkITK.vtkITKImageThresholdCalculator()
        thresholdCalculator.SetInputData(inputVolume.GetImageData())
        # thresholdCalculator.SetMethodToOtsu()  - this does not always work (see for example CTHead example data set)
        thresholdCalculator.SetMethodToMaximumEntropy()
        thresholdCalculator.Update()
        boneThresholdValue = thresholdCalculator.GetThreshold()
        volumeScalarRange = inputVolume.GetImageData().GetScalarRange()
        logging.debug(
            f"Volume minimum = {volumeScalarRange[0]}, maximum = {volumeScalarRange[1]}, bone threshold = {boneThresholdValue}"
        )

        # Set up segmentation
        outputSegmentation.CreateDefaultDisplayNodes()
        outputSegmentation.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolume)

        # 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)
        if not segmentEditorWidget.effectByName("Wrap Solidify"):
            raise NotImplementedError(
                "SurfaceWrapSolidify extension is required")

        segmentEditorNode = slicer.vtkMRMLSegmentEditorNode()
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(outputSegmentation)
        segmentEditorWidget.setMasterVolumeNode(inputVolume)

        # Create bone segment by thresholding
        boneSegmentID = outputSegmentation.GetSegmentation().AddEmptySegment(
            "bone")
        segmentEditorNode.SetSelectedSegmentID(boneSegmentID)
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", str(boneThresholdValue))
        effect.setParameter("MaximumThreshold", str(volumeScalarRange[1]))
        effect.self().onApply()

        # Smooth bone segment (just to reduce solidification computation time)
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING")
        effect.setParameter("KernelSizeMm", str(smoothingKernelSize))
        effect.self().onApply()

        # Solidify bone
        segmentEditorWidget.setActiveEffectByName("Wrap Solidify")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("region", "largestCavity")
        effect.setParameter("splitCavities",
                            "True" if splitCavitiesDiameter > 0 else "False")
        effect.setParameter("splitCavitiesDiameter",
                            str(splitCavitiesDiameter))  # in mm
        effect.setParameter("outputType", "newSegment")  # in mm
        effect.self().onApply()

        # Clean up
        #slicer.mrmlScene.RemoveNode(segmentEditorNode)
        #outputSegmentation.RemoveSegment(boneSegmentID)
        #segmentEditorWidget = None

        logging.info('Processing completed')
Ejemplo n.º 23
0
    def run(self,
            inputVolume,
            directory,
            exportlabelmaps=True,
            exportOBJ=True,
            medianFilter=True,
            exportDICOM=True,
            showResult=True):
        """
    Run the processing algorithm.
    Can be used without GUI widget.
    :param inputVolume: volume to be segmented
    :param exportOBJ: export to OBJ files
    :param exportlabelmaps: export to labelmaps
    :param medianFilter: Whether the medial filter is used for improving the segmentation
    :param exportDICOM: Whether the isotropic volume is exported as a DICOM series
    :param showResult: show output volume in slice viewers
    """

        if not inputVolume:
            raise ValueError("Input volume is invalid")

        logging.info('Processing started')

        # Perform the temporal bone autosegmentation
        InputVolume: inputVolume.GetID()
        spacing = inputVolume.GetSpacing()[2]
        # resample
        if spacing <= 0.25:
            parameters = {
                "outputPixelSpacing": "0.25,0.25,0.25",
                "InputVolume": inputVolume,
                "interpolationType": 'linear',
                "OutputVolume": inputVolume
            }
            slicer.cli.runSync(slicer.modules.resamplescalarvolume, None,
                               parameters)
        else:
            parameters = {
                "outputPixelSpacing": "0.25,0.25,0.25",
                "InputVolume": inputVolume,
                "interpolationType": 'bspline',
                "OutputVolume": inputVolume
            }
            slicer.cli.runSync(slicer.modules.resamplescalarvolume, None,
                               parameters)
        print('\nResampling...\n')
        spacing = inputVolume.GetSpacing()[2]
        volumeName = inputVolume.GetName()
        # Create segmentation
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolume)
        otic_capsule_segment = segmentationNode.GetSegmentation(
        ).AddEmptySegment("otic_capsule")
        # Create segment editor to get access to effects
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(inputVolume)

        segmentationNode1 = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        segmentationNode1.CreateDefaultDisplayNodes(
        )  # only needed for display
        segmentationNode1.SetReferenceImageGeometryParameterFromVolumeNode(
            inputVolume)
        # Create segment editor to get access to effects
        segmentEditorWidget1 = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget1.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode1 = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget1.setMRMLSegmentEditorNode(segmentEditorNode1)
        segmentEditorWidget1.setSegmentationNode(segmentationNode1)
        segmentEditorWidget1.setMasterVolumeNode(inputVolume)

        ## Autosegmentation of the otic capsule
        # NVIDIA auto segmentation
        segmentEditorWidget.setActiveEffectByName("Nvidia AIAA")
        effect = segmentEditorWidget.activeEffect()
        serverUrl = "http://tbone.onthewifi.com:956/v1/models"
        effect.self().ui.serverComboBox.currentText = serverUrl
        effect.self().onClickFetchModels()
        effect.self().ui.segmentationModelSelector.currentText = "inner_ear"
        effect.self().onClickSegmentation()
        inner_ear = segmentationNode.GetSegmentation(
        ).GetSegmentIdBySegmentName("inner_ear")
        segmentEditorWidget.setCurrentSegmentID(inner_ear)
        segmentationNode.GetSegmentation().GetSegment(inner_ear).SetColor(
            1, 0, 0)
        segmentationNode.GetSegmentation().GetSegment(
            otic_capsule_segment).SetColor(0.89, 0.92, 0.65)
        segmentEditorNode.SetMasterVolumeIntensityMaskRange(-300, 550)
        #Turn mask range on
        segmentEditorNode.MasterVolumeIntensityMaskOn()
        #growing the membranous labyrinth
        # Margin effect
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", 0.3)
        effect.self().onApply()
        segmentEditorWidget.setCurrentSegmentID('otic_capsule')
        #Copying the inner ear segment to otic capsule
        # Logical effect
        segmentEditorWidget.setActiveEffectByName("Logical operators")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", 'COPY')
        effect.setParameter("ModifierSegmentID", inner_ear)
        effect.setParameter("BypassMasking", 1)
        effect.self().onApply()
        # Define the Mask range for bony labyrinth
        segmentEditorNode.SetMasterVolumeIntensityMaskRange(650, 2500)
        #Turn mask range on
        segmentEditorNode.MasterVolumeIntensityMaskOn()
        #segmenting the otic capsule from the inner ear
        # Margin effect
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", spacing * 5)
        effect.self().onApply()
        segmentEditorNode.MasterVolumeIntensityMaskOff()
        # Islands effect
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", 'KEEP_LARGEST_ISLAND')
        effect.self().onApply()
        #Make the inner ear not visible to export only the otic capsule
        #segmentationNode.GetDisplayNode().SetSegmentVisibility(inner_ear, False)
        #copy the inner ear segment to another segmentation Node
        #segmentationNode1.GetSegmentation().CopySegmentFromSegmentation(segmentationNode.GetSegmentation(),inner_ear)
        # Remove the inner ear to export only the otic capsule
        segmentationNode.GetSegmentation().RemoveSegment(inner_ear)

        if exportlabelmaps == True:
            #Create labelmap for otic capsule and export the segment
            oticcapsule_labelmap = slicer.mrmlScene.AddNewNodeByClass(
                'vtkMRMLLabelMapVolumeNode')
            oticcapsule_labelmap.SetName('oticcapsule_labelmap')
            slicer.modules.segmentations.logic(
            ).ExportVisibleSegmentsToLabelmapNode(segmentationNode,
                                                  oticcapsule_labelmap,
                                                  inputVolume)
            slicer.util.saveNode(oticcapsule_labelmap,
                                 directory + '/oticcapsule_labelmap.nrrd')

        if exportOBJ == True:
            shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(
                slicer.mrmlScene)
            segnumber = shNode.GetItemByDataNode(segmentationNode)
            shNode.SetItemName(segnumber, volumeName + '_otic capsule')
            segmentIDs = vtk.vtkStringArray()
            segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)
            slicer.modules.segmentations.logic(
            ).ExportSegmentsClosedSurfaceRepresentationToFiles(
                directory, segmentationNode, segmentIDs, "OBJ", True, 1.0,
                False)

#copy the otic capsule segment to another segmentation Node
        segmentationNode1.GetSegmentation().CopySegmentFromSegmentation(
            segmentationNode.GetSegmentation(), otic_capsule_segment)

        # Remove the otic capsule after exporting
        segmentationNode.GetSegmentation().RemoveSegment('otic_capsule')

        # Autosegmentation of the ossicles
        segmentEditorWidget.setActiveEffectByName("Nvidia AIAA")
        effect = segmentEditorWidget.activeEffect()
        effect.self().ui.segmentationModelSelector.currentText = 'ossicles'
        effect.self().onClickSegmentation()
        ossicles = segmentationNode.GetSegmentation(
        ).GetSegmentIdBySegmentName("ossicles")
        segmentationNode.GetSegmentation().GetSegment(ossicles).SetColor(
            1, 1, 0.88)
        segmentEditorWidget.setCurrentSegmentID(ossicles)
        # Islands effect
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", 'REMOVE_SMALL_ISLANDS')
        effect.setParameter("MinimumSize", 50)
        effect.self().onApply()

        if exportlabelmaps == True:
            #Create labelmap for ossicles and export the segment
            ossicles_labelmap = slicer.mrmlScene.AddNewNodeByClass(
                'vtkMRMLLabelMapVolumeNode')
            ossicles_labelmap.SetName('ossicles_labelmap')
            slicer.modules.segmentations.logic(
            ).ExportVisibleSegmentsToLabelmapNode(segmentationNode,
                                                  ossicles_labelmap,
                                                  inputVolume)
            slicer.util.saveNode(ossicles_labelmap,
                                 directory + '/ossicles_labelmap.nrrd')

        if exportOBJ == True:
            shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(
                slicer.mrmlScene)
            segnumber = shNode.GetItemByDataNode(segmentationNode)
            shNode.SetItemName(segnumber, volumeName + '_ossicles')
            segmentIDs = vtk.vtkStringArray()
            segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)
            slicer.modules.segmentations.logic(
            ).ExportSegmentsClosedSurfaceRepresentationToFiles(
                directory, segmentationNode, segmentIDs, "OBJ", True, 1.0,
                False)

#copy the ossicles segment to another segmentation Node
        segmentationNode1.GetSegmentation().CopySegmentFromSegmentation(
            segmentationNode.GetSegmentation(), ossicles)

        # Remove the ossicles after exporting
        segmentationNode.GetSegmentation().RemoveSegment(ossicles)

        # Autosegmentation of Cochlear duct
        segmentEditorWidget.setActiveEffectByName("Nvidia AIAA")
        effect = segmentEditorWidget.activeEffect()
        effect.self(
        ).ui.segmentationModelSelector.currentText = "cochlear_duct"
        effect.self().onClickSegmentation()
        cochlear_duct = segmentationNode.GetSegmentation(
        ).GetSegmentIdBySegmentName("cochlear_duct")
        segmentEditorWidget.setCurrentSegmentID(cochlear_duct)
        segmentationNode.GetSegmentation().GetSegment(cochlear_duct).SetColor(
            1, 0, 0)
        segmentEditorNode.SetMasterVolumeIntensityMaskRange(-410, 750)
        #Turn mask range on
        segmentEditorNode.MasterVolumeIntensityMaskOn()
        #growing the membranous labyrinth
        # Margin effect
        segmentEditorWidget.setActiveEffectByName("Margin")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MarginSizeMm", 0.3)
        effect.self().onApply()

        if exportlabelmaps == True:
            #Create labelmap for cochlear duct and export the segment
            cochlear_duct_labelmap = slicer.mrmlScene.AddNewNodeByClass(
                'vtkMRMLLabelMapVolumeNode')
            cochlear_duct_labelmap.SetName('cochlear_duct_labelmap')
            slicer.modules.segmentations.logic(
            ).ExportVisibleSegmentsToLabelmapNode(segmentationNode,
                                                  cochlear_duct_labelmap,
                                                  inputVolume)
            slicer.util.saveNode(cochlear_duct_labelmap,
                                 directory + '/cochlear_duct_labelmap.nrrd')

        if exportOBJ == True:
            shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(
                slicer.mrmlScene)
            segnumber = shNode.GetItemByDataNode(segmentationNode)
            shNode.SetItemName(segnumber, volumeName + '_cochlear_duct')
            segmentIDs = vtk.vtkStringArray()
            segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)
            slicer.modules.segmentations.logic(
            ).ExportSegmentsClosedSurfaceRepresentationToFiles(
                directory, segmentationNode, segmentIDs, "OBJ", True, 1.0,
                False)

#copy the cochlear_duct segment to another segmentation Node
        segmentationNode1.GetSegmentation().CopySegmentFromSegmentation(
            segmentationNode.GetSegmentation(), cochlear_duct)

        # Remove the cochlear_duct after exporting
        segmentationNode.GetSegmentation().RemoveSegment(cochlear_duct)

        if medianFilter == True:
            volumesLogic = slicer.modules.volumes.logic()
            median = volumesLogic.CloneVolume(slicer.mrmlScene, inputVolume,
                                              'Volume_median_filter')

            parameters = {
                "neighborhood": "1,1,1",
                "inputVolume": inputVolume,
                "outputVolume": median
            }
            slicer.cli.runSync(slicer.modules.medianimagefilter, None,
                               parameters)

            segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
                median)
            segmentEditorWidget.setMasterVolumeNode(median)

        # Autosegmentation of Facial Nerve
        segmentEditorWidget.setActiveEffectByName("Nvidia AIAA")
        effect = segmentEditorWidget.activeEffect()
        effect.self().ui.segmentationModelSelector.currentText = 'facial_nerve'
        effect.self().onClickSegmentation()
        facial_nerve = segmentationNode.GetSegmentation(
        ).GetSegmentIdBySegmentName("facial_nerve")
        segmentationNode.GetSegmentation().GetSegment(facial_nerve).SetColor(
            0.9, 1, 0)

        if exportlabelmaps == True:
            #Create labelmap for facial nerve and export the segment
            facial_labelmap = slicer.mrmlScene.AddNewNodeByClass(
                'vtkMRMLLabelMapVolumeNode')
            slicer.modules.segmentations.logic(
            ).ExportVisibleSegmentsToLabelmapNode(segmentationNode,
                                                  facial_labelmap, inputVolume)
            facial_labelmap.SetName('facial_labelmap')
            slicer.util.saveNode(facial_labelmap,
                                 directory + '/facial_labelmap.nrrd')

        if exportOBJ == True:
            shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(
                slicer.mrmlScene)
            segnumber = shNode.GetItemByDataNode(segmentationNode)
            shNode.SetItemName(segnumber, volumeName + '_facial_nerve')
            segmentIDs = vtk.vtkStringArray()
            segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)
            slicer.modules.segmentations.logic(
            ).ExportSegmentsClosedSurfaceRepresentationToFiles(
                directory, segmentationNode, segmentIDs, "OBJ", True, 1.0,
                False)

#copy the facial nerve segment to another segmentation Node
        segmentationNode1.GetSegmentation().CopySegmentFromSegmentation(
            segmentationNode.GetSegmentation(), facial_nerve)

        # Remove the facial_nerve after exporting
        segmentationNode.GetSegmentation().RemoveSegment(facial_nerve)

        # Autosegmentation of Sigmoid sinus
        segmentEditorWidget.setActiveEffectByName("Nvidia AIAA")
        effect = segmentEditorWidget.activeEffect()
        effect.self(
        ).ui.segmentationModelSelector.currentText = 'sigmoid_sinus'
        effect.self().onClickSegmentation()
        sigmoid = segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(
            "sigmoid_sinus")
        segmentEditorWidget.setCurrentSegmentID(sigmoid)
        # Islands effect
        segmentEditorWidget.setActiveEffectByName("Islands")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("Operation", 'REMOVE_SMALL_ISLANDS')
        effect.setParameter("MinimumSize", 500)
        effect.self().onApply()

        if exportlabelmaps == True:
            # Create labelmap for sigmoid sinus and export the segment
            sigmoid_labelmap = slicer.mrmlScene.AddNewNodeByClass(
                'vtkMRMLLabelMapVolumeNode')
            sigmoid_labelmap.SetName('sigmoid_labelmap')
            slicer.modules.segmentations.logic(
            ).ExportVisibleSegmentsToLabelmapNode(segmentationNode,
                                                  sigmoid_labelmap,
                                                  inputVolume)
            slicer.util.saveNode(sigmoid_labelmap,
                                 directory + '/sigmoid_labelmap.nrrd')

        if exportOBJ == True:
            shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(
                slicer.mrmlScene)
            segnumber = shNode.GetItemByDataNode(segmentationNode)
            shNode.SetItemName(segnumber, volumeName + '_sigmoid')
            segmentIDs = vtk.vtkStringArray()
            segmentationNode.GetSegmentation().GetSegmentIDs(segmentIDs)
            slicer.modules.segmentations.logic(
            ).ExportSegmentsClosedSurfaceRepresentationToFiles(
                directory, segmentationNode, segmentIDs, "OBJ", True, 1.0,
                False)

#copy the sigmoid segment to another segmentation Node
        segmentationNode1.GetSegmentation().CopySegmentFromSegmentation(
            segmentationNode.GetSegmentation(), sigmoid)

        # Remove the sigmoid after exporting
        segmentationNode.GetSegmentation().RemoveSegment(sigmoid)

        # Remove the empty segmentation node
        slicer.mrmlScene.RemoveNode(segmentationNode)

        # Export the isotropic volume as nrrd file
        slicer.util.saveNode(inputVolume, directory + '/Volume.nrrd')

        # Export the isotropic volume as a DICOM series
        if exportDICOM == True:
            from datetime import datetime
            now = datetime.now()
            patient = now.strftime("%b-%d-%Y_%H-%M-%S")

            # Create patient and study and put the volume under the study
            shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(
                slicer.mrmlScene)
            patientItemID = shNode.CreateSubjectItem(shNode.GetSceneItemID(),
                                                     patient)
            studyItemID = shNode.CreateStudyItem(patientItemID,
                                                 "Auto-segmentation Study")
            volumeShItemID = shNode.GetItemByDataNode(inputVolume)
            shNode.SetItemParent(volumeShItemID, studyItemID)

            import DICOMScalarVolumePlugin
            exporter = DICOMScalarVolumePlugin.DICOMScalarVolumePluginClass()
            exportables = exporter.examineForExport(volumeShItemID)
            for exp in exportables:
                exp.directory = directory

            exporter.export(exportables)

        # Make segmentation results visible in 3D
        segmentationNode1.CreateClosedSurfaceRepresentation()

        layoutManager = slicer.app.layoutManager()
        threeDWidget = layoutManager.threeDWidget(0)
        threeDView = threeDWidget.threeDView()
        threeDView.resetFocalPoint()

        # Remove volume
        #slicer.mrmlScene.RemoveNode(median)

        #saveNode(inputVolume, directory+'/inputVolume.nrrd')
        #slicer.mrmlScene.RemoveNode(segmentationNode)
        #print(path)
        logging.info('Processing completed')
    def test_SplitVolume1(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: SegmentEditorSplitVolume)
    """

        self.delayDisplay("Starting test_SplitVolume1")

        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("SplitVolume")
        effect = segmentEditorWidget.activeEffect()
        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("Check extent of cropped volumes")
        expectedBounds = [[
            100.31225000000003, 119.99975000000003, 101.24974999999999,
            119.99974999999999, -78.4, -58.8
        ],
                          [
                              19.68725000000002, 119.99975000000003,
                              16.874749999999977, 119.99974999999999, -78.4,
                              16.80000000000001
                          ],
                          [
                              -49.687749999999994, 119.99975000000003,
                              90.93724999999999, 119.99974999999999, -78.4,
                              -47.6
                          ]]

        for segmentIndex in range(
                segmentationNode.GetSegmentation().GetNumberOfSegments()):
            segmentID = segmentationNode.GetSegmentation().GetNthSegmentID(
                segmentIndex)
            outputVolumeName = masterVolumeNode.GetName() + '_' + segmentID
            outputVolume = slicer.util.getNode(outputVolumeName)
            bounds = [0, 0, 0, 0, 0, 0]
            outputVolume.GetBounds(bounds)
            self.assertEqual(bounds, expectedBounds)

        ##################################
        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_SplitVolume1 passed')
Ejemplo n.º 25
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_WrapSolidify1(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: SegmentEditorWrapSolidify)
    """

        self.delayDisplay("Starting test_WrapSolidify1")

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

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

        masterVolumeNode = SampleData.downloadSample('MRBrainTumor1')

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

        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            'vtkMRMLSegmentationNode')
        segmentationNode.CreateDefaultDisplayNodes()
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            masterVolumeNode)

        features = ["none", "carveCavities", "createShell", "both"]
        spheres = [[20, 5, 5, 5], [20, -5, -5, -5]]
        appender = vtk.vtkAppendPolyData()
        for sphere in spheres:
            sphereSource = vtk.vtkSphereSource()
            sphereSource.SetRadius(sphere[0])
            sphereSource.SetCenter(sphere[1], sphere[2], sphere[3])
            appender.AddInputConnection(sphereSource.GetOutputPort())

        for m in features:
            segmentName = str(m)
            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 WrapSolidify Effect")
        segmentEditorWidget.setActiveEffectByName("Wrap Solidify")
        effect = segmentEditorWidget.activeEffect()

        for t in ["SEGMENTATION", "MODEL"]:
            effect.setParameter("outputType", t)

            self.delayDisplay(
                "Creating Output Type %s, activated feature none" % (t))
            segmentEditorWidget.setCurrentSegmentID(
                segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(
                    'none'))
            effect.setParameter("carveCavities", False)
            effect.setParameter("createShell", False)
            effect.self().onApply()

            self.delayDisplay(
                "Creating Output Type %s, activated feature carveCavities" %
                (t))
            effect.setParameter("carveCavities", True)
            effect.setParameter("createShell", False)
            segmentEditorWidget.setCurrentSegmentID(
                segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(
                    'carveCavities'))
            effect.self().onApply()

            self.delayDisplay(
                "Creating Output Type %s, activated feature createShell" % (t))
            effect.setParameter("carveCavities", False)
            effect.setParameter("createShell", True)
            segmentEditorWidget.setCurrentSegmentID(
                segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(
                    'createShell'))
            effect.self().onApply()

            self.delayDisplay(
                "Creating Output Type %s, activated feature both" % (t))
            effect.setParameter("carveCavities", True)
            effect.setParameter("createShell", True)
            segmentEditorWidget.setCurrentSegmentID(
                segmentationNode.GetSegmentation().GetSegmentIdBySegmentName(
                    'both'))
            effect.self().onApply()

        ##################################
        self.delayDisplay("Creating Segments from Models")
        for m in features:
            model = slicer.util.getNode(m)
            segmentName = "MODEL_%s" % m
            segment = vtkSegmentationCore.vtkSegment()
            segment.SetName(
                segmentationNode.GetSegmentation().GenerateUniqueSegmentID(
                    segmentName))
            segment.SetColor(model.GetDisplayNode().GetColor())
            segment.AddRepresentation(
                vtkSegmentationCore.vtkSegmentationConverter.
                GetSegmentationClosedSurfaceRepresentationName(),
                model.GetPolyData())
            segmentationNode.GetSegmentation().AddSegment(segment)

        ##################################
        self.delayDisplay("Compute statistics")
        segStatLogic = SegmentStatisticsLogic()
        segStatLogic.getParameterNode().SetParameter("Segmentation",
                                                     segmentationNode.GetID())
        segStatLogic.getParameterNode().SetParameter("ScalarVolume",
                                                     masterVolumeNode.GetID())
        segStatLogic.computeStatistics()
        statistics = segStatLogic.getStatistics()

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

        # logging.info(round(statistics["none",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["MODEL_none",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["carveCavities",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["MODEL_carveCavities",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["createShell",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["MODEL_createShell",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["both",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))
        # logging.info(round(statistics["MODEL_both",'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']))

        self.assertEqual(
            round(
                statistics["none",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            46605)
        self.assertEqual(
            round(
                statistics["MODEL_none",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            46320)

        self.assertEqual(
            round(
                statistics["carveCavities",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            46605)
        self.assertEqual(
            round(
                statistics["MODEL_carveCavities",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            46321)

        self.assertEqual(
            round(
                statistics["createShell",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            9257)
        self.assertEqual(
            round(
                statistics["MODEL_createShell",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            9230)

        self.assertEqual(
            round(
                statistics["both",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            9254)
        self.assertEqual(
            round(
                statistics["MODEL_both",
                           'ScalarVolumeSegmentStatisticsPlugin.volume_mm3']),
            9245)

        self.delayDisplay('test_WrapSolidify1 passed')
Ejemplo n.º 27
0
    def TestSection_04_qMRMLSegmentEditorWidget(self):
        logging.info('Test section 4: qMRMLSegmentEditorWidget')

        self.segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            'vtkMRMLSegmentEditorNode')
        self.assertIsNotNone(self.segmentEditorNode)

        self.inputSegmentationNode.SetSegmentListFilterEnabled(False)
        self.inputSegmentationNode.SetSegmentListFilterOptions("")

        displayNode = self.inputSegmentationNode.GetDisplayNode()
        self.assertIsNotNone(displayNode)

        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLSegmentEditorNode(self.segmentEditorNode)
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorWidget.setSegmentationNode(self.inputSegmentationNode)
        segmentEditorWidget.installKeyboardShortcuts(segmentEditorWidget)
        segmentEditorWidget.setFocus(qt.Qt.OtherFocusReason)
        segmentEditorWidget.show()

        self.segmentEditorNode.SetSelectedSegmentID('first')
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'first')
        slicer.app.processEvents()
        slicer.util.delayDisplay("First selected")

        segmentEditorWidget.selectNextSegment()
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'second')
        slicer.app.processEvents()
        slicer.util.delayDisplay("Next segment")

        segmentEditorWidget.selectPreviousSegment()
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'first')
        slicer.app.processEvents()
        slicer.util.delayDisplay("Previous segment")

        displayNode.SetSegmentVisibility('second', False)
        segmentEditorWidget.selectNextSegment()
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'third')
        slicer.app.processEvents()
        slicer.util.delayDisplay("Next segment (with second segment hidden)")

        # Trying to go out of bounds past first segment
        segmentEditorWidget.selectPreviousSegment()  #First
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'first')
        segmentEditorWidget.selectPreviousSegment()  #First
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'first')
        segmentEditorWidget.selectPreviousSegment()  #First
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'first')
        slicer.app.processEvents()
        slicer.util.delayDisplay("Multiple previous segment")

        # Wrap around
        self.segmentEditorNode.SetSelectedSegmentID('third')
        segmentEditorWidget.selectNextSegment()
        self.assertEqual(self.segmentEditorNode.GetSelectedSegmentID(),
                         'first')
        slicer.util.delayDisplay("Wrap around segments")
Ejemplo n.º 28
0
    def convertSegmentsToSegment(self, probeNode, nodeIds):
        thisScene = probeNode.GetScene()

        #probeNode.GetSegmentation().CreateRepresentation("Binary labelmap") #added 2/22
        #probeNode.GetSegmentation().SetMasterRepresentationName("Binary labelmap") #added 2/22

        probeName = "ablation zone"
        if len(nodeIds) > 1:
            print(
                "Found multiple probe nodes, combining them into a single segment!: ",
                nodeIds)
            probeName = "combined ablation zone"

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

        slicer.app.processEvents()

        for probeNodeID in nodeIds:
            duplicateProbeNode = thisScene.GetNodeByID(probeNodeID)
            #duplicateProbeNode.GetSegmentation().SetMasterRepresentationName("Binary labelmap") #ADDED 2/22
            segmentType = duplicateProbeNode.GetSegmentation(
            ).GetMasterRepresentationName()
            slicer.app.processEvents()
            if (segmentType == "Closed surface"):
                mergedImage = vtk.vtkPolyData()
                duplicateProbeNode.GetClosedSurfaceRepresentation(
                    duplicateProbeNode.GetSegmentation().GetNthSegmentID(0),
                    mergedImage)
                newSegmentID = segmentationNode.AddSegmentFromClosedSurfaceRepresentation(
                    mergedImage, probeNodeID, [0, 1, 0])
                newSegment = segmentationNode.GetSegmentation().GetSegment(
                    newSegmentID)
                newSegment.SetName(probeName)
            else:
                labelmapImage = vtkSegmentationCore.vtkOrientedImageData()
                duplicateProbeNode.GetBinaryLabelmapRepresentation(
                    duplicateProbeNode.GetSegmentation().GetNthSegmentID(0),
                    labelmapImage)
                newSegmentID = segmentationNode.AddSegmentFromBinaryLabelmapRepresentation(
                    labelmapImage, probeNodeID, [1, 0, 0])
                newSegment = segmentationNode.GetSegmentation().GetSegment(
                    newSegmentID)
                newSegment.SetName(probeName)
                duplicateProbeNode.GetSegmentation().CreateRepresentation(
                    "Closed Surface")
                #segmentationNode.GetSegmentation().CreateRepresentation("Closed surface")
                #segmentationNode.GetSegmentation().SetMasterRepresentationName("Closed surface")
            #slicer.mrmlScene.RemoveNode(duplicateProbeNode)
            duplicateProbeNode.SetDisplayVisibility(0)

        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)

        for i in range(
                1,
                segmentationNode.GetSegmentation().GetNumberOfSegments() +
                1):  #TWO ADDITIONAL PROBES
            segmentEditorWidget.setActiveEffectByName("Logical operators")
            effect = segmentEditorWidget.activeEffect()
            effect.self().scriptedEffect.setParameter("Operation", "UNION")
            effect.self().scriptedEffect.setParameter(
                "ModifierSegmentID",
                segmentationNode.GetSegmentation().GetNthSegmentID(i))
            effect.self().onApply()
            #segmentationNode.GetSegmentation().RemoveSegment(segmentationNode.GetSegmentation().GetNthSegmentID(i))

        #for i in range(1, segmentationNode.GetSegmentation().GetNumberOfSegments()):  #TWO ADDITIONAL PROBES
        #    segmentationNode.GetSegmentation().RemoveSegment(segmentationNode.GetSegmentation().GetNthSegmentID(i))

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

        segmentationNode.GetSegmentation().CreateRepresentation(
            "Closed surface")
        segmentationNode.GetSegmentation().SetMasterRepresentationName(
            "Closed surface")

        segNum = segmentationNode.GetSegmentation().GetNumberOfSegments()
        for i in range(0, segNum):
            segmentationNode.GetSegmentation().RemoveSegment(
                segmentationNode.GetSegmentation().GetNthSegmentID(1))

        segmentationNode.SetName("translated probe")
        #segmentationNode.GetSegmentation().GetNthSegment(0).SetName(probeName)
        return segmentationNode
Ejemplo n.º 29
0
    def test_NvidiaAIAA1(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: SegmentEditorNvidiaAIAA)
        """

        self.delayDisplay("Starting test_NvidiaAIAA1")

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

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

        masterVolumeNode = SampleData.downloadSample('MRBrainTumor1')

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

        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            'vtkMRMLSegmentationNode')
        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("NvidiaAIAA")
        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_NvidiaAIAA1 passed')
Ejemplo n.º 30
0
loadedVolumeNode = slicer.util.loadVolume(TestFile, returnNode=True)
vol = slicer.util.getNode('*ORIG')
VoxelSize = vol.GetSpacing()
Origin = vol.GetOrigin()
VolDims = vol.GetImageData().GetDimensions()

# Create segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
    "vtkMRMLSegmentationNode")
segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
    loadedVolumeNode)
addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment("skin")

# Create segment editor to get access to effects
segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
segmentEditorWidget.setMRMLScene(slicer.mrmlScene)
segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
    "vtkMRMLSegmentEditorNode")
segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
segmentEditorWidget.setSegmentationNode(segmentationNode)
segmentEditorWidget.setMasterVolumeNode(loadedVolumeNode)

# Thresholding
segmentEditorWidget.setActiveEffectByName("Threshold")
effect = segmentEditorWidget.activeEffect()
effect.setParameter("MinimumThreshold", "35")
effect.setParameter("MaximumThreshold", "695")
effect.self().onApply()

# Smoothing