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))
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()
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)
def buildSegment(self, inputVolme, masterSegment=None, segmentationNode=None, name='airway'): if (segmentationNode == None): segmentationNode = slicer.vtkMRMLSegmentationNode() slicer.mrmlScene.AddNode(segmentationNode) segmentationNode.CreateDefaultDisplayNodes() segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode( inputVolme) segmentID = segmentationNode.GetSegmentation().AddEmptySegment(name) segmentationEditor = slicer.qMRMLSegmentEditorWidget() segmentationEditor.setMRMLScene(slicer.mrmlScene) segmentationEditor.setMRMLSegmentEditorNode( slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSegmentEditorNode')) segmentationEditor.setSegmentationNode(segmentationNode) #//segmentationEditor.ad & test & # ? What was this line supposed to be? I can't remember but it doesn't seem to be causing problems for now segmentationEditor.setMasterVolumeNode(inputVolme) #import qSlicerSegmentationEditorEffectsPythonQt as effects segmentationEditor.setActiveEffectByName('Threshold') effect = segmentationEditor.activeEffect() effect.setParameter('MinimumThreshold', '-1024') effect.setParameter('MaximumThreshold', AIR_DENSITY_THRESHOLD) effect.self().onApply() # FIXME: part of the fix for handling out of bounds air - currently broken #if masterSegment is not None: #segmentationEditor.setActiveEffectByName('Logical operators') #effect = segmentationEditor.activeEffect() #effect.setParameter('ModifierSegmentID', masterSegment.GetName()) #effect.setParameter('Operation', 'INTERSECT') #effect.self().onApply() segmentationEditor.setActiveEffectByName('Islands') effect = segmentationEditor.activeEffect() effect.setParameter('KeepLargestIsland', True) effect.self().onApply() segmentationNode.CreateClosedSurfaceRepresentation() surfaceMesh = segmentationNode.GetClosedSurfaceRepresentation( segmentID) normals = vtk.vtkPolyDataNormals() normals.ConsistencyOn() normals.SetInputData(surfaceMesh) normals.Update() surfaceMesh = normals.GetOutput() return segmentationNode
def 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
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')
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')
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)
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')
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
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')
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
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
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)
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
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')
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')
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')
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")
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
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')
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