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!')
Example #2
0
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!')
Example #4
0
	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')
Example #8
0
  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)
Example #12
0
  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)
Example #13
0
  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)
Example #14
0
    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