def test_GraphCutSegmentSelfTest1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ # # first, get some data # # import urllib # downloads = (('http://www.slicer.org/slicerWiki/images/5/59/RegLib_C01_1.nrrd', 'Tumor.nrrd', slicer.util.loadVolume),) #export http_proxy=http://proxyhost:proxyport # for url,name,loader in downloads: # filePath = slicer.app.temporaryPath + '/' + name # if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: # logging.info('Requesting download %s from %s...\n' % (name, url)) # urllib.urlretrieve(url, filePath) # if loader: # logging.info('Loading %s...' % (name,)) # loader(filePath) # self.delayDisplay('Finished with download and loading') self.delayDisplay("Starting the test") mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule( 'GraphCutInteravtiveSegmenter') volumeNode = self.downloadMRHead() # slicer.util.loadVolume(slicer.app.slicerHome+"/RegLib_C01_1.nrrd") # volumeNode = slicer.util.getNode('RegLib_C01_1') cropVolumeNode = slicer.vtkMRMLCropVolumeParametersNode() cropVolumeNode.SetScene(slicer.mrmlScene) slicer.mrmlScene.AddNode(cropVolumeNode) fiducial = slicer.vtkMRMLMarkupsFiducialNode() fiducial.SetScene(slicer.mrmlScene) fiducial.AddFiducial(-1.8, 31.6, 11.9) fiducial.AddFiducial(15.7, 45.0, 30.1) fiducial.AddFiducial(-18.5, 12.0, 30.1) fiducial.AddFiducial(-2.6, 28.7, 45.5) slicer.mrmlScene.AddNode(fiducial) graphCutLogic = slicer.modules.graphcutinteractivesegmenter.logic() graphCutLogic.checkMarkups(volumeNode, fiducial) graphCutLogic.crop(volumeNode, cropVolumeNode) graphCutLogic.apply( slicer.mrmlScene.GetNodeByID( cropVolumeNode.GetOutputVolumeNodeID()), True, True) self.delayDisplay('Test passed!')
def createCroppedVolume(inputVolume, roi): cropVolumeLogic = slicer.modules.cropvolume.logic() cropVolumeParameterNode = slicer.vtkMRMLCropVolumeParametersNode() cropVolumeParameterNode.SetROINodeID(roi.GetID()) cropVolumeParameterNode.SetInputVolumeNodeID(inputVolume.GetID()) cropVolumeParameterNode.SetVoxelBased(True) cropVolumeLogic.Apply(cropVolumeParameterNode) croppedVolume = slicer.mrmlScene.GetNodeByID(cropVolumeParameterNode.GetOutputVolumeNodeID()) return croppedVolume
def test_GraphCutSegmentSelfTest1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ # # first, get some data # # import urllib # downloads = (('http://www.slicer.org/slicerWiki/images/5/59/RegLib_C01_1.nrrd', 'Tumor.nrrd', slicer.util.loadVolume),) #export http_proxy=http://proxyhost:proxyport # for url,name,loader in downloads: # filePath = slicer.app.temporaryPath + '/' + name # if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: # logging.info('Requesting download %s from %s...\n' % (name, url)) # urllib.urlretrieve(url, filePath) # if loader: # logging.info('Loading %s...' % (name,)) # loader(filePath) # self.delayDisplay('Finished with download and loading') self.delayDisplay("Starting the test") mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('GraphCutInteravtiveSegmenter') volumeNode = self.downloadMRHead() # slicer.util.loadVolume(slicer.app.slicerHome+"/RegLib_C01_1.nrrd") # volumeNode = slicer.util.getNode('RegLib_C01_1') cropVolumeNode = slicer.vtkMRMLCropVolumeParametersNode() cropVolumeNode.SetScene(slicer.mrmlScene) slicer.mrmlScene.AddNode(cropVolumeNode) fiducial = slicer.vtkMRMLMarkupsFiducialNode() fiducial.SetScene(slicer.mrmlScene) fiducial.AddFiducial(-1.8,31.6,11.9) fiducial.AddFiducial(15.7,45.0,30.1) fiducial.AddFiducial(-18.5,12.0,30.1) fiducial.AddFiducial(-2.6,28.7,45.5) slicer.mrmlScene.AddNode(fiducial) graphCutLogic = slicer.modules.graphcutinteractivesegmenter.logic() graphCutLogic.checkMarkups(volumeNode,fiducial) graphCutLogic.crop(volumeNode,cropVolumeNode) graphCutLogic.apply(slicer.mrmlScene.GetNodeByID(cropVolumeNode.GetOutputVolumeNodeID()),True,True) self.delayDisplay('Test passed!')
def runCropVolume(self, roi, volume): #Create Crop Volume Parameter node cropParamNode = slicer.vtkMRMLCropVolumeParametersNode() cropParamNode.SetScene(slicer.mrmlScene) cropParamNode.SetName('Crop_volume_Node1') #Create Crop Volume Parameter node cropParamNode = slicer.vtkMRMLCropVolumeParametersNode() cropParamNode.SetScene(slicer.mrmlScene) cropParamNode.SetName('Crop_volume_Node1') cropParamNode.SetInputVolumeNodeID(volume.GetID()) cropParamNode.SetROINodeID(roi.GetID()) slicer.mrmlScene.AddNode(cropParamNode) #Apply Cropping slicer.modules.cropvolume.logic().Apply(cropParamNode) cropVol = slicer.mrmlScene.GetNodeByID(cropParamNode.GetOutputVolumeNodeID()) #TODO - Make cropped output visible!! return cropVol
def run(self, inputVolume, ROITemplateSelectorPath): """ Run the actual algorithm """ if inputVolume is None: return False """ Add Data no longer loads DICOM series rightly See : https://discourse.slicer.org/t/dicom-volume-orientation-may-be-bad/10068/1 https://discourse.slicer.org/t/python-how-to-centre-volume-on-load/10220/1 """ volumesLogic = slicer.modules.volumes.logic() volumesLogic.CenterVolume(inputVolume) # https://www.slicer.org/wiki/Documentation/Nightly/ScriptRepository displayNode = inputVolume.GetDisplayNode() displayNode.AutoWindowLevelOff() # CT-Bones displayNode.SetWindow(1000) displayNode.SetLevel(400) # https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/util.py [success, roi] = slicer.util.loadAnnotationROI(ROITemplateSelectorPath, True) """ TODO: Prevent the file path from being added to the recent history list. Or delete the entry. Perhaps Slicer should prevent duplicate entries in that list. """ # https://www.snip2code.com/Snippet/707153/Loads-the-volume-and-performs-the-Volume # volumeNode = slicer.util.getNode('CTA-cardio') cropLogic = slicer.modules.cropvolume.logic() cvpn = slicer.vtkMRMLCropVolumeParametersNode() cvpn.SetROINodeID(roi.GetID()) cvpn.SetInputVolumeNodeID(inputVolume.GetID()) cvpn.SetVoxelBased(True) cvpn.VoxelBasedOn() cropLogic.Apply(cvpn) roi.SetDisplayVisibility(False) outputVolumeNodeID = cvpn.GetOutputVolumeNodeID() #https://www.slicer.org/wiki/Documentation/4.3/Developers/Python_scripting views = ['Red', 'Yellow', 'Green'] for view in views: view_logic = slicer.app.layoutManager().sliceWidget( view).sliceLogic() view_cn = view_logic.GetSliceCompositeNode() view_cn.SetBackgroundVolumeID(outputVolumeNodeID) view_logic.FitSliceToAll() return [success, outputVolumeNodeID]
def runCropVolume(self, roi, volume): logging.info('Cropping processing started') #Create Crop Volume Parameter node cropParamNode = slicer.vtkMRMLCropVolumeParametersNode() cropParamNode.SetScene(slicer.mrmlScene) cropParamNode.SetName('Crop_volume_Node1') cropParamNode.SetInputVolumeNodeID(volume.GetID()) cropParamNode.SetROINodeID(roi.GetID()) slicer.mrmlScene.AddNode(cropParamNode) #Apply Cropping slicer.modules.cropvolume.logic().Apply(cropParamNode) logging.info('Cropping processing completed')
def test_CropVolumeSelfTest(self): """ Replicate the crashe in issue 3117 """ print("Running CropVolumeSelfTest Test case:") import SampleData vol = SampleData.downloadSample("MRHead") roi = slicer.vtkMRMLAnnotationROINode() roi.Initialize(slicer.mrmlScene) mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('CropVolume') cropVolumeNode = slicer.vtkMRMLCropVolumeParametersNode() cropVolumeNode.SetScene(slicer.mrmlScene) cropVolumeNode.SetName('ChangeTracker_CropVolume_node') cropVolumeNode.SetIsotropicResampling(True) cropVolumeNode.SetSpacingScalingConst(0.5) slicer.mrmlScene.AddNode(cropVolumeNode) cropVolumeNode.SetInputVolumeNodeID(vol.GetID()) cropVolumeNode.SetROINodeID(roi.GetID()) cropVolumeLogic = slicer.modules.cropvolume.logic() cropVolumeLogic.Apply(cropVolumeNode) self.delayDisplay( 'First test passed, closing the scene and running again') # test clearing the scene and running a second time slicer.mrmlScene.Clear(0) # the module will re-add the removed parameters node mainWindow.moduleSelector().selectModule('Transforms') mainWindow.moduleSelector().selectModule('CropVolume') cropVolumeNode = slicer.mrmlScene.GetNodeByID( 'vtkMRMLCropVolumeParametersNode1') vol = SampleData.downloadSample("MRHead") roi = slicer.vtkMRMLAnnotationROINode() roi.Initialize(slicer.mrmlScene) cropVolumeNode.SetInputVolumeNodeID(vol.GetID()) cropVolumeNode.SetROINodeID(roi.GetID()) cropVolumeLogic.Apply(cropVolumeNode) self.delayDisplay('Test passed')
def test_CropVolumeSelfTest(self): """ Replicate the crashe in issue 3117 """ print("Running CropVolumeSelfTest Test case:") import SampleData vol = SampleData.downloadSample("MRHead") roi = slicer.vtkMRMLAnnotationROINode() roi.Initialize(slicer.mrmlScene) mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('CropVolume') cropVolumeNode = slicer.vtkMRMLCropVolumeParametersNode() cropVolumeNode.SetScene(slicer.mrmlScene) cropVolumeNode.SetName('ChangeTracker_CropVolume_node') cropVolumeNode.SetIsotropicResampling(True) cropVolumeNode.SetSpacingScalingConst(0.5) slicer.mrmlScene.AddNode(cropVolumeNode) cropVolumeNode.SetInputVolumeNodeID(vol.GetID()) cropVolumeNode.SetROINodeID(roi.GetID()) cropVolumeLogic = slicer.modules.cropvolume.logic() cropVolumeLogic.Apply(cropVolumeNode) self.delayDisplay('First test passed, closing the scene and running again') # test clearing the scene and running a second time slicer.mrmlScene.Clear(0) # the module will re-add the removed parameters node mainWindow.moduleSelector().selectModule('Transforms') mainWindow.moduleSelector().selectModule('CropVolume') cropVolumeNode = slicer.mrmlScene.GetNodeByID('vtkMRMLCropVolumeParametersNode1') vol = SampleData.downloadSample("MRHead") roi = slicer.vtkMRMLAnnotationROINode() roi.Initialize(slicer.mrmlScene) cropVolumeNode.SetInputVolumeNodeID(vol.GetID()) cropVolumeNode.SetROINodeID(roi.GetID()) cropVolumeLogic.Apply(cropVolumeNode) self.delayDisplay('Test passed')
def runDefineCropROIVoxel(self, inputVol): #create crop volume parameter node cropParamNode = slicer.vtkMRMLCropVolumeParametersNode() cropParamNode.SetScene(slicer.mrmlScene) cropParamNode.SetName('Template_ROI') cropParamNode.SetInputVolumeNodeID(inputVol.GetID()) #create ROI template_roi = slicer.vtkMRMLAnnotationROINode() slicer.mrmlScene.AddNode(template_roi) cropParamNode.SetROINodeID(template_roi.GetID()) #Fit roi to input image slicer.mrmlScene.AddNode(cropParamNode) slicer.modules.cropvolume.logic().SnapROIToVoxelGrid(cropParamNode) slicer.modules.cropvolume.logic().FitROIToInputVolume(cropParamNode) return template_roi
def test_ThresholdThreading(self): """ Replicate the issue reported in bug 1822 where splitting a grow-cut produced volume causes a multi-threading related issue on mac release builds """ self.delayDisplay("Starting the test") # # first, get some sample data # self.delayDisplay("Get some data") import SampleData head = SampleData.downloadSample("MRHead") # # now, define an ROI in it # roi = slicer.vtkMRMLAnnotationROINode() slicer.mrmlScene.AddNode(roi) roi.SetXYZ(-2, 104, -80) roi.SetRadiusXYZ(30, 30, 30) # # apply the cropping to the head # cropLogic = slicer.modules.cropvolume.logic() cvpn = slicer.vtkMRMLCropVolumeParametersNode() cvpn.SetROINodeID( roi.GetID() ) cvpn.SetInputVolumeNodeID( head.GetID() ) cropLogic.Apply( cvpn ) croppedHead = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID() ) # # create a label map and set it for editing # volumesLogic = slicer.modules.volumes.logic() croppedHeadLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, croppedHead, croppedHead.GetName() + '-label' ) selectionNode = slicer.app.applicationLogic().GetSelectionNode() selectionNode.SetActiveVolumeID( croppedHead.GetID() ) selectionNode.SetActiveLabelVolumeID( croppedHeadLabel.GetID() ) slicer.app.applicationLogic().PropagateVolumeSelection(0) # # got to the editor and do some drawing # self.delayDisplay("Paint some things") parameterNode = EditUtil.getParameterNode() lm = slicer.app.layoutManager() paintEffect = EditorLib.PaintEffectOptions() paintEffect.setMRMLDefaults() paintEffect.__del__() sliceWidget = lm.sliceWidget('Red') paintTool = EditorLib.PaintEffectTool(sliceWidget) EditUtil.setLabel(1) paintTool.paintAddPoint(100,100) paintTool.paintApply() EditUtil.setLabel(2) paintTool.paintAddPoint(200,200) paintTool.paintApply() paintTool.cleanup() paintTool = None self.delayDisplay("Now grow cut") # # now do GrowCut # growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic()) growCutLogic.growCut() # # now split the volume, merge it back, and see if it looks right # preArray = slicer.util.array(croppedHeadLabel.GetName()) slicer.util.selectModule('Editor') slicer.util.findChildren(text='Split Merge Volume')[0].clicked() slicer.util.findChildren(text='Merge All')[0].clicked() postArray = slicer.util.array(croppedHeadLabel.GetName()) if (postArray - preArray).max() != 0: print("!$!$!#!@#!@!@$%! Test Failed!!") else: print("Ahh... test passed.") self.assertEqual((postArray - preArray).max(), 0) self.delayDisplay("Test passed!")
def refineLandmark(self, state): """Refine the specified landmark""" # Refine landmark, or if none, do nothing # Crop images around the fiducial # Affine registration of the cropped images # Transform the fiducial using the transformation # # No need to take into account the current transformation because landmarks are in World RAS timing = False if self.VerboseMode == "Verbose": timing = True if state.logic.cropLogic is None: print( "Cannot refine landmarks. CropVolume module is not available.") if state.fixed == None or state.moving == None or state.fixedFiducials == None or state.movingFiducials == None or state.currentLandmarkName == None: print "Cannot refine landmarks. Images or landmarks not selected." return print("Refining landmark " + state.currentLandmarkName) + " using " + self.name start = time.time() volumes = (state.fixed, state.moving) (fixedVolume, movingVolume) = volumes slicer.mrmlScene.StartState(slicer.mrmlScene.BatchProcessState) landmarks = state.logic.landmarksForVolumes(volumes) cvpn = slicer.vtkMRMLCropVolumeParametersNode() cvpn.SetInterpolationMode(1) cvpn.SetVoxelBased(1) fixedPoint = [ 0, ] * 3 movingPoint = [ 0, ] * 3 (fixedFiducial, movingFiducial) = landmarks[state.currentLandmarkName] (fixedList, fixedIndex) = fixedFiducial (movingList, movingIndex) = movingFiducial # define an roi for the fixed if timing: roiStart = time.time() roiFixed = slicer.vtkMRMLAnnotationROINode() slicer.mrmlScene.AddNode(roiFixed) fixedList.GetNthFiducialPosition(fixedIndex, fixedPoint) roiFixed.SetDisplayVisibility(0) roiFixed.SelectableOff() roiFixed.SetXYZ(fixedPoint) roiFixed.SetRadiusXYZ(30, 30, 30) # crop the fixed. note we hide the display node temporarily to avoid the automated # window level calculation on temporary nodes created by cloning cvpn.SetROINodeID(roiFixed.GetID()) cvpn.SetInputVolumeNodeID(fixedVolume.GetID()) fixedDisplayNode = fixedVolume.GetDisplayNode() fixedVolume.SetAndObserveDisplayNodeID( 'This is not a valid DisplayNode ID') if timing: roiEnd = time.time() if timing: cropStart = time.time() state.logic.cropLogic.Apply(cvpn) if timing: cropEnd = time.time() croppedFixedVolume = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID()) fixedVolume.SetAndObserveDisplayNodeID(fixedDisplayNode.GetID()) # define an roi for the moving if timing: roi2Start = time.time() roiMoving = slicer.vtkMRMLAnnotationROINode() slicer.mrmlScene.AddNode(roiMoving) movingList.GetNthFiducialPosition(movingIndex, movingPoint) roiMoving.SetDisplayVisibility(0) roiMoving.SelectableOff() roiMoving.SetXYZ(movingPoint) if self.LocalBRAINSFitMode == "Small": roiMoving.SetRadiusXYZ(45, 45, 45) else: roiMoving.SetRadiusXYZ(60, 60, 60) # crop the moving. note we hide the display node temporarily to avoid the automated # window level calculation on temporary nodes created by cloning cvpn.SetROINodeID(roiMoving.GetID()) cvpn.SetInputVolumeNodeID(movingVolume.GetID()) movingDisplayNode = movingVolume.GetDisplayNode() movingVolume.SetAndObserveDisplayNodeID( 'This is not a valid DisplayNode ID') if timing: roi2End = time.time() if timing: crop2Start = time.time() state.logic.cropLogic.Apply(cvpn) if timing: crop2End = time.time() croppedMovingVolume = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID()) movingVolume.SetAndObserveDisplayNodeID(movingDisplayNode.GetID()) if timing: print 'Time to set up fixed ROI was ' + str(roiEnd - roiStart) + ' seconds' if timing: print 'Time to set up moving ROI was ' + str( roi2End - roi2Start) + ' seconds' if timing: print 'Time to crop fixed volume ' + str(cropEnd - cropStart) + ' seconds' if timing: print 'Time to crop moving volume ' + str(crop2End - crop2Start) + ' seconds' # transform = slicer.vtkMRMLLinearTransformNode() slicer.mrmlScene.AddNode(transform) matrix = vtk.vtkMatrix4x4() # define the registration parameters minPixelSpacing = min(croppedFixedVolume.GetSpacing()) parameters = {} parameters['fixedVolume'] = croppedFixedVolume.GetID() parameters['movingVolume'] = croppedMovingVolume.GetID() parameters['linearTransform'] = transform.GetID() parameters['useRigid'] = True parameters['initializeTransformMode'] = 'useGeometryAlign' parameters['samplingPercentage'] = 0.2 parameters['minimumStepLength'] = 0.1 * minPixelSpacing parameters['maximumStepLength'] = minPixelSpacing # run the registration if timing: regStart = time.time() slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) if timing: regEnd = time.time() if timing: print 'Time for local registration ' + str(regEnd - regStart) + ' seconds' # apply the local transform to the landmark #print transform if timing: resultStart = time.time() transform.GetMatrixTransformToWorld(matrix) matrix.Invert() tp = [ 0, ] * 4 tp = matrix.MultiplyPoint(fixedPoint + [ 1, ]) #print fixedPoint, movingPoint, tp[:3] movingList.SetNthFiducialPosition(movingIndex, tp[0], tp[1], tp[2]) if timing: resultEnd = time.time() if timing: print 'Time for transforming landmark was ' + str( resultEnd - resultStart) + ' seconds' # clean up cropped volmes, need to reset the foreground/background display before we delete it if timing: cleanUpStart = time.time() slicer.mrmlScene.RemoveNode(croppedFixedVolume) slicer.mrmlScene.RemoveNode(croppedMovingVolume) slicer.mrmlScene.RemoveNode(roiFixed) slicer.mrmlScene.RemoveNode(roiMoving) slicer.mrmlScene.RemoveNode(transform) roiFixed = None roiMoving = None transform = None matrix = None if timing: cleanUpEnd = time.time() if timing: print 'Cleanup took ' + str(cleanUpEnd - cleanUpStart) + ' seconds' end = time.time() print 'Refined landmark ' + state.currentLandmarkName + ' in ' + str( end - start) + ' seconds' slicer.mrmlScene.EndState(slicer.mrmlScene.BatchProcessState)
def setup(self): self.developerMode = True ScriptedLoadableModuleWidget.setup(self) self.logic = RegistrationLogic() self.cropVolumeParameterNode = slicer.vtkMRMLCropVolumeParametersNode() # why initializing them here? self.VIEW_MODE_Preop_Only = 0 self.VIEW_MODE_Intraop_Only = 1 self.VIEW_MODE_ThreeCompare = 2 self.VIEW_MODE_Axial = 3 self.VIEW_MODE_Sagittal = 4 self.VIEW_MODE_Coronal = 5 self.PREOP_VOLUME = None self.INTRAOP_VOLUME = None volumes = slicer.util.getNodesByClass("vtkMRMLScalarVolumeNode") for i in range(0,len(volumes)): if 'Preop' in volumes[i].GetName(): self.PREOP_VOLUME = volumes[i] elif 'Intraop' in volumes[i].GetName(): self.INTRAOP_VOLUME = volumes[i] scansCollapsibleButton = ctk.ctkCollapsibleButton() scansCollapsibleButton.text = "Volumes" self.layout.addWidget(scansCollapsibleButton) scansFormLayout = qt.QFormLayout(scansCollapsibleButton) # Layout within the dummy collapsible button # input inputBackVol self.inputBackVol = slicer.qMRMLNodeComboBox() self.inputBackVol.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputBackVol.selectNodeUponCreation = True self.inputBackVol.setAutoFillBackground(self.INTRAOP_VOLUME) self.inputBackVol.addEnabled = False self.inputBackVol.removeEnabled = False self.inputBackVol.noneEnabled = True self.inputBackVol.showHidden = False self.inputBackVol.showChildNodeTypes = False self.inputBackVol.setMRMLScene( slicer.mrmlScene ) self.inputBackVol.setToolTip( "Pick the input scan to the algorithm." ) # self.layout.addWidget("Input Background Volume: ", self.inputBackVol) # input vol node connection self.inputBackVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputBackVol) # input inputBackVol self.inputForVol = slicer.qMRMLNodeComboBox() self.inputForVol.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputForVol.selectNodeUponCreation = True self.inputForVol.setAutoFillBackground(self.PREOP_VOLUME) self.inputForVol.addEnabled = False self.inputForVol.removeEnabled = False self.inputForVol.noneEnabled = True self.inputForVol.showHidden = False self.inputForVol.showChildNodeTypes = False self.inputForVol.setMRMLScene( slicer.mrmlScene ) self.inputForVol.setToolTip( "Pick the input scan to the algorithm." ) # self.layout.addWidget("Input Foreground Volume: ", self.inputForVol) # input vol node connection self.inputForVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputForVol) scansFormLayout.addRow("Input Intraop Volume: ", self.inputBackVol) scansFormLayout.addRow("Input Preop Volume: ", self.inputForVol) # # ROI Area # self.roiCollapsibleGroupBox = ctk.ctkCollapsibleGroupBox() self.roiCollapsibleGroupBox.title = "Define ROI" self.roiCollapsibleGroupBox.collapsed = True self.layout.addWidget(self.roiCollapsibleGroupBox) # Layout within the dummy collapsible button roiFormLayout = qt.QFormLayout(self.roiCollapsibleGroupBox) # input intraop/fixed volume selector self.inputVol = slicer.qMRMLNodeComboBox() self.inputVol.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputVol.selectNodeUponCreation = True self.inputVol.setAutoFillBackground(False) self.inputVol.addEnabled = False self.inputVol.removeEnabled = False self.inputVol.noneEnabled = True self.inputVol.showHidden = False self.inputVol.showChildNodeTypes = False self.inputVol.setMRMLScene( slicer.mrmlScene ) self.inputVol.setToolTip( "Pick the input scan to the algorithm." ) roiFormLayout.addRow("Input Volume: ", self.inputVol) # input vol node connection self.inputVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputVol) # ROI Buttons self.defineROIButton = qt.QPushButton("Define ROI") self.defineROIButton.enabled = False self.defineROIButton.toolTip = "Define the region/vertebrae of the interest" self.applyROIButton = qt.QPushButton("Crop the ROI") self.applyROIButton.enabled = False self.defineROIButton.toolTip = "Crop the region/vertebrae of the interest" # place them on GUI side by side roiFormLayout.addWidget(self.createHLayout([self.defineROIButton, self.applyROIButton])) self.defineROIButton.connect("clicked(bool)", self.onDefineROIButton) self.applyROIButton.connect("clicked(bool)", self.onApplyROIButton) self.thresholdGroupBox = ctk.ctkCollapsibleGroupBox() self.thresholdGroupBox.title = "Generate Mesh" self.thresholdGroupBox.collapsed = True roiFormLayout.addRow(self.thresholdGroupBox) self.thresholdGroupBox.connect('clicked(bool)' , self.onGenerateMeshGroupBox) thresholdGroupBoxLayout = qt.QFormLayout(self.thresholdGroupBox) # threshold value self.threshold = ctk.ctkRangeWidget() self.threshold.spinBoxAlignment = 0xff # put enties on top self.threshold.singleStep = 0.1 self.threshold.minimum = -1000 self.threshold.maximum = 3000 self.threshold.setToolTip( "Set the range of the background values that should be labeled.") thresholdGroupBoxLayout.addRow("Image threshold", self.threshold) # Generate Mesh based on the cursour movment self.generateMeshButton = qt.QPushButton("Generate Mesh") self.generateMeshButton.enabled = False self.generateMeshButton.toolTip = "Crop the region/vertebrae of the interest" # place them on GUI side by side thresholdGroupBoxLayout.addRow(self.generateMeshButton) self.generateMeshButton.connect('clicked()', self.onMeshButton) # connection # Instantiate and connect widgets ... self.displayLayoutBox = qt.QGroupBox('Display Layout') self.displayLayout = qt.QGridLayout() self.displayLayoutBox.setLayout(self.displayLayout) self.layout.addWidget(self.displayLayoutBox) # button to only show preop volume self.PreopOnlyButton = qt.QPushButton("Preop Only") self.PreopOnlyButton.name = "Preop Only" self.PreopOnlyButton.setCheckable(True) self.PreopOnlyButton.setFlat(True) self.displayLayout.addWidget(self.PreopOnlyButton, 0, 0) self.PreopOnlyButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Preop_Only)) # button to only show intraop volume self.IntraopOnlyButton = qt.QPushButton("Intraop Only") self.IntraopOnlyButton.name = "Intraop Only" self.IntraopOnlyButton.setCheckable(True) self.IntraopOnlyButton.setFlat(True) self.displayLayout.addWidget(self.IntraopOnlyButton, 0, 1) self.IntraopOnlyButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Intraop_Only)) # button to show the overalp of the intraop and preop volumes self.OverlapButton = qt.QPushButton("Ax/Sa/Co") self.OverlapButton.name = "Ax/Sa/Co" self.OverlapButton.setCheckable(True) self.OverlapButton.setFlat(True) self.displayLayout.addWidget(self.OverlapButton, 0, 2) self.OverlapButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_ThreeCompare)) # button to only show Axial view of preop, intraop, and overlap self.AxialButton = qt.QPushButton("Axial View") self.AxialButton.name = "Axial View" self.AxialButton.setCheckable(True) self.AxialButton.setFlat(True) self.displayLayout.addWidget(self.AxialButton, 1, 0) self.AxialButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Axial)) # button to only show Sagittal view of preop, intraop, and overlap self.SagittalButton = qt.QPushButton("Sagittal View") self.SagittalButton.name = "Sagittal View" self.SagittalButton.setCheckable(True) self.SagittalButton.setFlat(True) self.displayLayout.addWidget(self.SagittalButton, 1, 1) self.SagittalButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Sagittal)) # button to only show Coronal view of preop, intraop, and overlap self.CoronalButton = qt.QPushButton("Coronal View") self.CoronalButton.name = "Coronal View" self.CoronalButton.setCheckable(True) self.CoronalButton.setFlat(True) self.displayLayout.addWidget(self.CoronalButton, 1, 2) self.CoronalButton.connect('clicked()', lambda: self.onViewMode(self.VIEW_MODE_Coronal)) # extra visualization self.VisualizationGroupBox = ctk.ctkCollapsibleGroupBox() self.VisualizationGroupBox.title = "Visualization" self.VisualizationGroupBox.collapsed = True self.layout.addWidget(self.VisualizationGroupBox) VisualizationFormLayout = qt.QFormLayout(self.VisualizationGroupBox) self.visualizationWidget = RegistrationLib.VisualizationWidget(self.logic) b = self.visualizationWidget.widget allChildren = b.children()[1].children()[1].children() groupbox = b.children()[1].children()[1] groupbox.setTitle('') allChildren[1].hide() allChildren[2].hide() allChildren[3].hide() allChildren[4].hide() VisualizationFormLayout.addWidget(b) # Landmark Registration Area fiducialregistrationwizardModuleWidget = slicer.modules.fiducialregistrationwizard.createNewWidgetRepresentation() fiducialregistrationwizardModuleWidgetGroupBoxes = fiducialregistrationwizardModuleWidget.findChildren("ctkCollapsibleGroupBox") fiducialregistrationwizardModuleWidgetQGroupBoxes = fiducialregistrationwizardModuleWidget.findChildren("QGroupBox") self.FidRegWizRegResultComboBox = fiducialregistrationwizardModuleWidgetQGroupBoxes[3].children()[1] fiducialregistrationwizardModuleWidgetGroupBoxes[2].hide() #hide the landmark from transform # hide extra crap extra = fiducialregistrationwizardModuleWidget.children()[1].children() self.FiducialRegWizNode = slicer.vtkMRMLFiducialRegistrationWizardNode() slicer.mrmlScene.AddNode(self.FiducialRegWizNode) tag = self.FiducialRegWizNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.onFiducialRegWizNode) extra[1].setCurrentNode(self.FiducialRegWizNode) extra[1].hide() extra[3].hide() extra[4].hide() #registrationResult = extra[8] #initialregTransformBox = registrationResult.children()[1] #self.initialLandmarkTransform #initialregTransformBox.setCurrentNode(slicer.util.getNode('FromPreopToIntraopInitialTransform')) fiducialregistrationwizardModuleWidgetCollapsibleButton = fiducialregistrationwizardModuleWidget.findChildren("ctkCollapsibleButton") fiducialregistrationwizardModuleWidgetCollapsibleButton[0].setText('Landmark Registration') fiducialregistrationwizardModuleWidgetCollapsibleButton[0].collapsed = True #fiducialregistrationwizardModuleWidgetGroupBoxes[3].setText('') self.layout.addWidget(fiducialregistrationwizardModuleWidget) AutoCollapsibleButton = ctk.ctkCollapsibleButton() AutoCollapsibleButton.text = "Auto Registrationn" self.layout.addWidget(AutoCollapsibleButton) AutoCollapsibleButton.collapsed = True # Layout within the dummy collapsible button autoFormLayout = qt.QFormLayout(AutoCollapsibleButton) self.rigidCheckmarkBox = qt.QCheckBox() self.rigidCheckmarkBox.checked = 1 self.rigidCheckmarkBox.setToolTip("If checked, the rigid registration is performed (6 DOF)") self.rigidscaleCheckmarkBox = qt.QCheckBox() self.rigidscaleCheckmarkBox.checked = 0 self.rigidscaleCheckmarkBox.setToolTip("If checked, the rigid and scaling is performed (7 DOF)") # Auto Rigid Registration Button self.autoRegButton = qt.QPushButton("Run Registration") self.autoRegButton.toolTip = "Run the automatic brains rigid registration algorithm." self.autoRegButton.enabled = True self.autoRegButton.connect('clicked(bool)', self.onautoRegButton) # connection # input moving mesh self.inputMovingMesh = slicer.qMRMLNodeComboBox() self.inputMovingMesh.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.inputMovingMesh.selectNodeUponCreation = True self.inputMovingMesh.addEnabled = False self.inputMovingMesh.removeEnabled = False self.inputMovingMesh.noneEnabled = True self.inputMovingMesh.showHidden = False self.inputMovingMesh.showChildNodeTypes = False self.inputMovingMesh.setMRMLScene( slicer.mrmlScene ) self.inputMovingMesh.setToolTip( "Pick the input mesh for intraop scan" ) #self.inputVol.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputPreopMesh) # input fixed mesh self.inputFixedMesh = slicer.qMRMLNodeComboBox() self.inputFixedMesh.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.inputFixedMesh.selectNodeUponCreation = True self.inputFixedMesh.addEnabled = False self.inputFixedMesh.removeEnabled = False self.inputFixedMesh.noneEnabled = True self.inputFixedMesh.showHidden = False self.inputFixedMesh.showChildNodeTypes = False self.inputFixedMesh.setMRMLScene( slicer.mrmlScene ) self.inputFixedMesh.setToolTip( "Pick the input mesh for intraop scan" ) # self.inputMovingMesh.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputPreopMesh) # self.inputFixedMesh.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputIntraopMesh) autoFormLayout.addRow('Rigid (6 DOF)', self.rigidCheckmarkBox) autoFormLayout.addRow('Rigid+Scaling (7 DOF)', self.rigidscaleCheckmarkBox) autoFormLayout.addRow("Input Intraop Mesh: ", self.inputFixedMesh) autoFormLayout.addRow("Input Preop Mesh: ", self.inputMovingMesh) autoFormLayout.addRow(self.autoRegButton) # Add vertical spacer self.layout.addStretch(1)
def refineLandmark(self, state): """Refine the specified landmark""" # Refine landmark, or if none, do nothing # Crop images around the fiducial # Affine registration of the cropped images # Transform the fiducial using the transformation # # No need to take into account the current transformation because landmarks are in World RAS timing = False if self.VerboseMode == "Verbose": timing = True if state.logic.cropLogic is None: print("Cannot refine landmarks. CropVolume module is not available.") if state.fixed == None or state.moving == None or state.fixedFiducials == None or state.movingFiducials == None or state.currentLandmarkName == None: print "Cannot refine landmarks. Images or landmarks not selected." return print ("Refining landmark " + state.currentLandmarkName) + " using " + self.name start = time.time() volumes = (state.fixed, state.moving) (fixedVolume, movingVolume) = volumes slicer.mrmlScene.StartState(slicer.mrmlScene.BatchProcessState) landmarks = state.logic.landmarksForVolumes(volumes) cvpn = slicer.vtkMRMLCropVolumeParametersNode() cvpn.SetInterpolationMode(1) cvpn.SetVoxelBased(1) fixedPoint = [0,]*3 movingPoint = [0,]*3 (fixedFiducial, movingFiducial) = landmarks[state.currentLandmarkName] (fixedList,fixedIndex) = fixedFiducial (movingList, movingIndex) = movingFiducial # define an roi for the fixed if timing: roiStart = time.time() roiFixed = slicer.vtkMRMLAnnotationROINode() slicer.mrmlScene.AddNode(roiFixed) fixedList.GetNthFiducialPosition(fixedIndex,fixedPoint) roiFixed.SetDisplayVisibility(0) roiFixed.SelectableOff() roiFixed.SetXYZ(fixedPoint) roiFixed.SetRadiusXYZ(30, 30, 30) # crop the fixed. note we hide the display node temporarily to avoid the automated # window level calculation on temporary nodes created by cloning cvpn.SetROINodeID( roiFixed.GetID() ) cvpn.SetInputVolumeNodeID( fixedVolume.GetID() ) fixedDisplayNode = fixedVolume.GetDisplayNode() fixedVolume.SetAndObserveDisplayNodeID('This is not a valid DisplayNode ID') if timing: roiEnd = time.time() if timing: cropStart = time.time() state.logic.cropLogic.Apply( cvpn ) if timing: cropEnd = time.time() croppedFixedVolume = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID() ) fixedVolume.SetAndObserveDisplayNodeID(fixedDisplayNode.GetID()) # define an roi for the moving if timing: roi2Start = time.time() roiMoving = slicer.vtkMRMLAnnotationROINode() slicer.mrmlScene.AddNode(roiMoving) movingList.GetNthFiducialPosition(movingIndex,movingPoint) roiMoving.SetDisplayVisibility(0) roiMoving.SelectableOff() roiMoving.SetXYZ(movingPoint) if self.LocalBRAINSFitMode == "Small": roiMoving.SetRadiusXYZ(45, 45, 45) else: roiMoving.SetRadiusXYZ(60, 60, 60) # crop the moving. note we hide the display node temporarily to avoid the automated # window level calculation on temporary nodes created by cloning cvpn.SetROINodeID( roiMoving.GetID() ) cvpn.SetInputVolumeNodeID( movingVolume.GetID() ) movingDisplayNode = movingVolume.GetDisplayNode() movingVolume.SetAndObserveDisplayNodeID('This is not a valid DisplayNode ID') if timing: roi2End = time.time() if timing: crop2Start = time.time() state.logic.cropLogic.Apply( cvpn ) if timing: crop2End = time.time() croppedMovingVolume = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID() ) movingVolume.SetAndObserveDisplayNodeID(movingDisplayNode.GetID()) if timing: print 'Time to set up fixed ROI was ' + str(roiEnd - roiStart) + ' seconds' if timing: print 'Time to set up moving ROI was ' + str(roi2End - roi2Start) + ' seconds' if timing: print 'Time to crop fixed volume ' + str(cropEnd - cropStart) + ' seconds' if timing: print 'Time to crop moving volume ' + str(crop2End - crop2Start) + ' seconds' # transform = slicer.vtkMRMLLinearTransformNode() slicer.mrmlScene.AddNode(transform) matrix = vtk.vtkMatrix4x4() # define the registration parameters minPixelSpacing = min(croppedFixedVolume.GetSpacing()) parameters = {} parameters['fixedVolume'] = croppedFixedVolume.GetID() parameters['movingVolume'] = croppedMovingVolume.GetID() parameters['linearTransform'] = transform.GetID() parameters['useRigid'] = True parameters['initializeTransformMode'] = 'useGeometryAlign'; parameters['samplingPercentage'] = 0.2 parameters['minimumStepLength'] = 0.1 * minPixelSpacing parameters['maximumStepLength'] = minPixelSpacing # run the registration if timing: regStart = time.time() slicer.cli.run(slicer.modules.brainsfit, None, parameters, wait_for_completion=True) if timing: regEnd = time.time() if timing: print 'Time for local registration ' + str(regEnd - regStart) + ' seconds' # apply the local transform to the landmark #print transform if timing: resultStart = time.time() transform.GetMatrixTransformToWorld(matrix) matrix.Invert() tp = [0,]*4 tp = matrix.MultiplyPoint(fixedPoint + [1,]) #print fixedPoint, movingPoint, tp[:3] movingList.SetNthFiducialPosition(movingIndex, tp[0], tp[1], tp[2]) if timing: resultEnd = time.time() if timing: print 'Time for transforming landmark was ' + str(resultEnd - resultStart) + ' seconds' # clean up cropped volmes, need to reset the foreground/background display before we delete it if timing: cleanUpStart = time.time() slicer.mrmlScene.RemoveNode(croppedFixedVolume) slicer.mrmlScene.RemoveNode(croppedMovingVolume) slicer.mrmlScene.RemoveNode(roiFixed) slicer.mrmlScene.RemoveNode(roiMoving) slicer.mrmlScene.RemoveNode(transform) roiFixed = None roiMoving = None transform = None matrix = None if timing: cleanUpEnd = time.time() if timing: print 'Cleanup took ' + str(cleanUpEnd - cleanUpStart) + ' seconds' end = time.time() print 'Refined landmark ' + state.currentLandmarkName + ' in ' + str(end - start) + ' seconds' slicer.mrmlScene.EndState(slicer.mrmlScene.BatchProcessState)
def run(self, inputVolume, labelMap, ROIValue, cortValue): logging.info('Processing started') if not self.isValidInputOutputData(inputVolume, labelMap): slicer.util.errorDisplay('Volumes de entrada e saida sao so mesmos. Escolha outros volumes') return False volumeLogic = slicer.modules.volumes.logic() slicer.app.processEvents() # Executar correcao N4ITK self.progressBar.value = 10 slicer.app.processEvents() n4itkVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", inputVolume.GetName() + ' N4ITK') parameters = {} parameters["inputImageName"] = inputVolume.GetID() parameters["outputImageName"] = n4itkVolume.GetID() n4itkModule = slicer.modules.n4itkbiasfieldcorrection slicer.cli.run(n4itkModule, None, parameters, wait_for_completion=True) logging.info('N4ITK finished') # Executar CastScalarVolume self.progressBar.value = 20 slicer.app.processEvents() castVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", inputVolume.GetName() + ' Cast Volume') parameters.clear() parameters["InputVolume"] = n4itkVolume.GetID() parameters["OutputVolume"] = castVolume.GetID() parameters["Type"] = "Int" csv = slicer.modules.castscalarvolume slicer.cli.run(csv, None, parameters, wait_for_completion=True) logging.info('Cast Scalar Volume finished') # Inverter voxels do Volume self.progressBar.value = 30 slicer.app.processEvents() invertVolume = volumeLogic.CloneVolume(slicer.mrmlScene, castVolume, inputVolume.GetName() + ' Inverted Volume') invertVolume.SetName(inputVolume.GetName() + ' Inverted Volume') a = slicer.util.array(invertVolume.GetName()) Max=0 if (a.max() < 256): # 8 bits Max=255 if (a.max() >= 256) and (a.max() < 4096): # 12 bits Max=4095 if (a.max() >= 4096) and (a.max() < 16384): # 14 bits Max=16383 if (a.max() >= 16384) and (a.max() < 65536): # 16 bits Max=65535 a[:] = Max -a #inverte os valores dos voxels logging.info('Inverted Volume finished') #invertVolume.GetImageData().Modified() # Calcular osso cortical self.progressBar.value = 40 slicer.app.processEvents() volumeArray = slicer.util.array(invertVolume.GetName()) labelArray = slicer.util.array(labelMap.GetName()) points = numpy.where(labelArray == cortValue) values = volumeArray[points] ICort = values.mean() logging.info('Calculo do Osso Cortical (ICort) finished') # Calculo da media da ROI (ITrab) self.progressBar.value = 50 slicer.app.processEvents() ROIArray = slicer.util.array(invertVolume.GetName()) labelArray = slicer.util.array(labelMap.GetName()) points = numpy.where(labelArray == ROIValue) values = volumeArray[points] ocorrencias = numpy.bincount(values) #contar ocorrencias. Posicao e o valor! ocorrenciasList = list(ocorrencias) #converter array numpy em lista ocurrenciasListSorted = numpy.sort(ocorrenciasList) #ordenar array ITrab = values.mean() #media dos pontos logging.info('Calculo da ROI (ITrab) finished') # capturar o valor do pixel (posicao) no vetor do pico do histograma picoPixelValue=ocorrenciasList.index(ocorrencias.max()) # Encontrar ILow if (ocorrencias.max()/2) in ocorrencias: ILow=ocorrenciasList.index(ocorrencias.max()/2) else: for x in ocurrenciasListSorted: if x > (ocorrencias.max()/2): posterior=ocorrenciasList.index(x) break else: anterior=ocorrenciasList.index(x) try: ILow #print 'ilow existe' except NameError: #print 'ilow nao existe' if (posterior-(ocorrencias.max()/2)) <= ((ocorrencias.max()/2)-anterior): ILow = posterior else: ILow = anterior logging.info('Procura ILow finished') FVTO = (ITrab - ILow) / (ICort - ILow) logging.info('Calculo do FVTO finished') # Executa Mask Scalar Volume no ROI self.progressBar.value = 60 slicer.app.processEvents() ROIVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", inputVolume.GetName() + ' ROI Volume') parameters.clear() parameters["InputVolume"] = invertVolume.GetID() parameters["MaskVolume"] = labelMap.GetID() parameters["OutputVolume"] = ROIVolume.GetID() parameters["Label"] = ROIValue maskScalarVolume = slicer.modules.maskscalarvolume slicer.cli.run(maskScalarVolume, None, parameters, wait_for_completion=True) logging.info('Mask Scalar Volume finished') # Posicionando a ROI para cortar a imagem self.progressBar.value = 70 slicer.app.processEvents() # Achar o centro da imagem segmentada array = slicer.util.array(ROIVolume.GetName()) points = numpy.where(array > 0) # Calculo da posicao pos = [0.0, 0.0, 0.0] IJKtoRASMatrix = vtk.vtkMatrix4x4() ROIVolume.GetIJKToRASMatrix(IJKtoRASMatrix) i = points[2].max() - (points[2].max() - points[2].min())/2 j = points[1].max() - (points[1].max() - points[1].min())/2 k = points[0].max() - (points[0].max() - points[0].min())/2 IJK = [i, j, k, 1] RAS = IJKtoRASMatrix.MultiplyPoint(IJK) pos[0] = RAS[0] pos[1] = RAS[1] pos[2] = RAS[2] # Calculo das dimensoes spacing = [0.0, 0.0, 0.0] spacing = ROIVolume.GetSpacing() L = ((points[0].max() - points[0].min())/2*spacing[0])+spacing[0] P = ((points[2].max() - points[2].min())/2*spacing[2])+spacing[1] A = ((points[1].max() - points[1].min())/2*spacing[1])+spacing[1] print L, P, A # Criar a ROI ROI = slicer.vtkMRMLAnnotationROINode() ROI.SetName(inputVolume.GetName() + ' ROI') slicer.mrmlScene.AddNode(ROI) ROI.SetXYZ(pos) ROI.SetRadiusXYZ(L, P, A) ROI.SetDisplayVisibility(True) # Realiza o Crop da imagem #Crop Voxel Based self.progressBar.value = 80 slicer.app.processEvents() cropLogic = slicer.modules.cropvolume.logic() cropVolume = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLScalarVolumeNode", inputVolume.GetName() + ' Cropped Volume') parametersNode = slicer.vtkMRMLCropVolumeParametersNode() parametersNode.SetInputVolumeNodeID(ROIVolume.GetID()) parametersNode.SetOutputVolumeNodeID(cropVolume.GetID()) parametersNode.SetROINodeID(ROI.GetID()) parametersNode.SetVoxelBased(True) slicer.mrmlScene.AddNode(parametersNode) cropLogic.SnapROIToVoxelGrid(parametersNode) cropLogic.Apply(parametersNode) # Binarizar volume self.progressBar.value = 90 slicer.app.processEvents() resultVolume = volumeLogic.CloneVolume(slicer.mrmlScene, cropVolume, inputVolume.GetName() + ' Result Volume') resultVolume.SetName(inputVolume.GetName() + ' Result Volume') arrayResult = slicer.util.array(resultVolume.GetName()) arrayResult[arrayResult < ITrab] = 0 arrayResult[arrayResult >= ITrab] = Max logging.info('Volume ROI Binario finished') # Popular tabela logging.info('Popular tabela') rowIndex = self.table.AddEmptyRow() self.table.SetCellText(rowIndex, 0, inputVolume.GetName()) self.table.SetCellText(rowIndex, 1, str(ICort)) self.table.SetCellText(rowIndex, 2, str(ITrab)) self.table.SetCellText(rowIndex, 3, str(ILow)) self.table.SetCellText(rowIndex, 4, str(FVTO)) # Exibir o resultado logging.info('Exibir resultado') for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic().GetSliceCompositeNode().SetBackgroundVolumeID(resultVolume.GetID()) self.resultButton.enabled = True self.progressBar.value = 100 slicer.app.processEvents() logging.info('Processing finished') return True