def updateAblationVolume(self): if self.AutomaticUpdate == False: return if self.SourceNode and self.DestinationNode: pTip = [0.0, 0.0, 0.0] pTail = [0.0, 0.0, 0.0] #self.SourceNode.GetNthFiducialPosition(0,pTip) self.SourceNode.GetPosition1(pTip) #self.SourceNode.GetNthFiducialPosition(1,pTail) self.SourceNode.GetPosition2(pTail) if self.DestinationNode.GetDisplayNodeID() == None: modelDisplayNode = slicer.vtkMRMLModelDisplayNode() modelDisplayNode.SetColor(self.ModelColor) slicer.mrmlScene.AddNode(modelDisplayNode) self.DestinationNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID()) displayNodeID = self.DestinationNode.GetDisplayNodeID() modelDisplayNode = slicer.mrmlScene.GetNodeByID(displayNodeID) if modelDisplayNode != None and self.SliceIntersection == True: modelDisplayNode.SliceIntersectionVisibilityOn() else: modelDisplayNode.SliceIntersectionVisibilityOff() if self.SphereSource == None: self.SphereSource = vtk.vtkSphereSource() self.SphereSource.SetThetaResolution(20) self.SphereSource.SetPhiResolution(20) self.SphereSource.Update() # Scale sphere to make ellipsoid scale = vtk.vtkTransform() scale.Scale(self.MinorAxis, self.MinorAxis, self.MajorAxis) scaleFilter = vtk.vtkTransformPolyDataFilter() scaleFilter.SetInputConnection(self.SphereSource.GetOutputPort()) scaleFilter.SetTransform(scale) scaleFilter.Update(); # Transform transform = vtk.vtkTransform() self.computeTransform(pTip, pTail, self.TipOffset, transform) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputConnection(scaleFilter.GetOutputPort()) transformFilter.SetTransform(transform) transformFilter.Update(); self.DestinationNode.SetAndObservePolyData(transformFilter.GetOutput()) self.DestinationNode.Modified() if self.DestinationNode.GetScene() == None: slicer.mrmlScene.AddNode(self.DestinationNode)
def sliderValueChanged(self, value): print value print self.oldPosition transform = vtk.vtkTransform() if self.selector.currentNodeID == 'vtkMRMLSliceNodeRed': print "red" redSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed') transform.SetMatrix(redSlice.GetSliceToRAS()) transform.RotateX(value - self.oldPosition) redSlice.GetSliceToRAS().DeepCopy(transform.GetMatrix()) redSlice.UpdateMatrices() elif self.selector.currentNodeID == 'vtkMRMLSliceNodeYellow': print "yellow" redSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow') transform.SetMatrix(redSlice.GetSliceToRAS()) transform.RotateY(value - self.oldPosition) redSlice.GetSliceToRAS().DeepCopy(transform.GetMatrix()) redSlice.UpdateMatrices() elif self.selector.currentNodeID == 'vtkMRMLSliceNodeGreen': print "green" redSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeGreen') transform.SetMatrix(redSlice.GetSliceToRAS()) transform.RotateZ(value - self.oldPosition) redSlice.GetSliceToRAS().DeepCopy(transform.GetMatrix()) redSlice.UpdateMatrices() #self.slider.TypeOfTransform = self.slider.ROTATION_LR #self.slider.applyTransformation(self.slider.value - self.oldPosition) self.oldPosition = value
def createNeedleModelNode(self, name): locatorModel = self.scene.CreateNodeByClass('vtkMRMLModelNode') # Cylinder represents the locator stick cylinder = vtk.vtkCylinderSource() cylinder.SetRadius(1.5) cylinder.SetHeight(100) cylinder.SetCenter(0, 0, 0) cylinder.Update() # Rotate cylinder tfilter = vtk.vtkTransformPolyDataFilter() trans = vtk.vtkTransform() trans.RotateX(90.0) trans.Translate(0.0, -50.0, 0.0) trans.Update() if vtk.VTK_MAJOR_VERSION <= 5: tfilter.SetInput(cylinder.GetOutput()) else: tfilter.SetInputConnection(cylinder.GetOutputPort()) tfilter.SetTransform(trans) tfilter.Update() # Sphere represents the locator tip sphere = vtk.vtkSphereSource() sphere.SetRadius(3.0) sphere.SetCenter(0, 0, 0) sphere.Update() apd = vtk.vtkAppendPolyData() if vtk.VTK_MAJOR_VERSION <= 5: apd.AddInput(sphere.GetOutput()) apd.AddInput(tfilter.GetOutput()) else: apd.AddInputConnection(sphere.GetOutputPort()) apd.AddInputConnection(tfilter.GetOutputPort()) apd.Update() locatorModel.SetAndObservePolyData(apd.GetOutput()); self.scene.AddNode(locatorModel) locatorModel.SetScene(self.scene); locatorModel.SetName(name) locatorDisp = locatorModel.GetDisplayNodeID() if locatorDisp == None: locatorDisp = self.scene.CreateNodeByClass('vtkMRMLModelDisplayNode') self.scene.AddNode(locatorDisp) locatorDisp.SetScene(self.scene) locatorModel.SetAndObserveDisplayNodeID(locatorDisp.GetID()); color = [0, 0, 0] color[0] = 0.5 color[1] = 0.5 color[2] = 1.0 locatorDisp.SetColor(color) return locatorModel.GetID()
def rotateOrthogonalSlicesDeg(self, axialNode, ortho1Node, ortho2Node, rotationChangeDeg): """ Rotate the orthogonal nodes around the common intersection point, around the normal of the axial node """ # All points and vectors are in RAS coordinate system intersectionPoint = self.getPlaneIntersectionPoint(axialNode, ortho1Node, ortho2Node) axialSliceToRas = axialNode.GetSliceToRAS() rotationTransform = vtk.vtkTransform() rotationTransform.RotateZ(rotationChangeDeg) #rotatedAxialSliceToRas = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(axialSliceToRas, rotationTransform.GetMatrix(), axialSliceToRas) # Invert the direction of the two vectors so that by default they produce the same slice orientation as Slicer's # "sagittal" and "coronal" slice orientation if the axial node is in "axial" orientation axialSliceNormal = [-axialSliceToRas.GetElement(0,2),-axialSliceToRas.GetElement(1,2),-axialSliceToRas.GetElement(2,2)] axialSliceAxisX = [-axialSliceToRas.GetElement(0,0),-axialSliceToRas.GetElement(1,0),-axialSliceToRas.GetElement(2,0)] paraSagittalOrientationCode = 1 paraCoronalOrientationCode = 2 ortho1Node.SetSliceToRASByNTP(axialSliceNormal[0],axialSliceNormal[1],axialSliceNormal[2], axialSliceAxisX[0],axialSliceAxisX[1],axialSliceAxisX[2], intersectionPoint[0], intersectionPoint[1], intersectionPoint[2], paraSagittalOrientationCode) ortho2Node.SetSliceToRASByNTP(axialSliceNormal[0],axialSliceNormal[1],axialSliceNormal[2], axialSliceAxisX[0],axialSliceAxisX[1],axialSliceAxisX[2], intersectionPoint[0], intersectionPoint[1], intersectionPoint[2], paraCoronalOrientationCode) return True
def onCentrar(self): volumenCentrar = self.imagenSelector.currentNode() lm = slicer.app.layoutManager() origenVolumen = volumenCentrar.GetOrigin() volumeLogic = slicer.vtkSlicerVolumesLogic() origenCentro = [0, 0, 0] volumeLogic.GetVolumeCenteredOrigin(volumenCentrar, origenCentro) traslacion = [0, 0, 0] volumenCentrar.SetOrigin(origenCentro) lm.resetSliceViews() for i in range(3): traslacion[i] = origenCentro[i] - origenVolumen[i] T = slicer.vtkMRMLTransformNode() I = slicer.vtkMRMLTransformNode() transmatrix = vtk.vtkMatrix4x4() transform = vtk.vtkTransform() T.SetAndObserveTransformToParent(transform) T.SetName('centrarTransformacionSeeg') I.SetName('CentrarTInversaSeeg') transmatrix.DeepCopy((1, 0, 0, traslacion[0], 0, 1, 0, traslacion[1], 0, 0, 1, traslacion[2], 0, 0, 0, 1)) transform.SetMatrix(transmatrix) inv = transform.GetInverse() I.SetAndObserveTransformToParent(inv) slicer.mrmlScene.AddNode(T) slicer.mrmlScene.AddNode(I)
def __init__(self,fixed=None,moving=None,transform=None): self.interval = 20 self.timer = None # parameter defaults self.sampleSpacing = 3 self.gradientWindow = 1 self.stepSize = 1 # the parametricTransform #self.parametricTransform = RegimaticTranslationTransform() self.parametricTransform = RegimaticTranslateSRotatePATransform() #self.parametricTransform = RegimaticRigidTransform() #TODO: fix quaternion # slicer nodes set by the GUI self.fixed = fixed self.moving = moving self.transform = transform # optimizer state variables self.iteration = 0 self.metric = 0 # helper objects self.scratchMatrix = vtk.vtkMatrix4x4() self.ijkToRAS = vtk.vtkMatrix4x4() self.rasToIJK = vtk.vtkMatrix4x4() self.matrixToParent = vtk.vtkMatrix4x4() self.reslice = vtk.vtkImageReslice() self.resliceTransform = vtk.vtkTransform() self.viewer = None
def recolorLabelMap(self, modelNode, labelMap, initialValue, outputValue): import vtkSlicerRtCommonPython if (modelNode != None and labelMap != None): self.labelMapImgData = labelMap.GetImageData() self.resectionPolyData = modelNode.GetPolyData() # IJK -> RAS ijkToRasMatrix = vtk.vtkMatrix4x4() labelMap.GetIJKToRASMatrix(ijkToRasMatrix) # RAS -> IJK rasToIjkMatrix = vtk.vtkMatrix4x4() labelMap.GetRASToIJKMatrix(rasToIjkMatrix) rasToIjkTransform = vtk.vtkTransform() rasToIjkTransform.SetMatrix(rasToIjkMatrix) rasToIjkTransform.Update() # Transform Resection model from RAS -> IJK polyDataTransformFilter = vtk.vtkTransformPolyDataFilter() if (vtk.VTK_MAJOR_VERSION <= 5): polyDataTransformFilter.SetInput(self.resectionPolyData) else: polyDataTransformFilter.SetInputData(self.resectionPolyData) polyDataTransformFilter.SetTransform(rasToIjkTransform) polyDataTransformFilter.Update() # Convert Resection model to label map polyDataToLabelmapFilter = vtkSlicerRtCommonPython.vtkPolyDataToLabelmapFilter() polyDataToLabelmapFilter.SetInputPolyData(polyDataTransformFilter.GetOutput()) polyDataToLabelmapFilter.SetReferenceImage(self.labelMapImgData) polyDataToLabelmapFilter.UseReferenceValuesOn() polyDataToLabelmapFilter.SetBackgroundValue(0) polyDataToLabelmapFilter.SetLabelValue(outputValue) polyDataToLabelmapFilter.Update() # Cast resection label map to unsigned char for use with mask filter castFilter = vtk.vtkImageCast() if (vtk.VTK_MAJOR_VERSION <= 5): castFilter.SetInput(polyDataToLabelmapFilter.GetOutput()) else: castFilter.SetInputData(polyDataToLabelmapFilter.GetOutput()) castFilter.SetOutputScalarTypeToUnsignedChar() castFilter.Update() # Create mask for recoloring the original label map maskFilter = vtk.vtkImageMask() if (vtk.VTK_MAJOR_VERSION <= 5): maskFilter.SetImageInput(self.labelMapImgData) maskFilter.SetMaskInput(castFilter.GetOutput()) else: maskFilter.SetImageInputData(self.labelMapImgData) maskFilter.SetMaskInputData(castFilter.GetOutput()) maskFilter.SetMaskedOutputValue(outputValue) maskFilter.NotMaskOn() maskFilter.Update() self.labelMapImgData = maskFilter.GetOutput() self.labelMapImgData.Modified() labelMap.SetAndObserveImageData(self.labelMapImgData)
def generate3DVisualisationNode(self, polydata, name, color=(1, 1, 1), initial_pos_x=0): #create Model Node shape_node = slicer.vtkMRMLModelNode() shape_node.SetAndObservePolyData(polydata) shape_node.SetName(name) #create display node model_display = slicer.vtkMRMLModelDisplayNode() model_display.SetColor(color[0], color[1], color[2]) model_display.AutoScalarRangeOff() model_display.SetScene(slicer.mrmlScene) model_display.SetName("Display " + name) #create transform node transform = vtk.vtkTransform() transform.Translate(initial_pos_x, 0, 0) transform_node = slicer.vtkMRMLTransformNode() transform_node.SetName("Translation " + name) transform_node.SetAndObserveTransformToParent(transform) #Add Nodes to Slicer slicer.mrmlScene.AddNode(transform_node) slicer.mrmlScene.AddNode(model_display) slicer.mrmlScene.AddNode(shape_node) #Link nodes shape_node.SetAndObserveTransformNodeID(transform_node.GetID()) shape_node.SetAndObserveDisplayNodeID(model_display.GetID())
def sliderValueChanged(self, value): logging.debug(value) logging.debug(self.oldPosition) transform = vtk.vtkTransform() if self.selector.currentNodeID == 'vtkMRMLSliceNodeRed': logging.debug("red") redSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed') transform.SetMatrix(redSlice.GetSliceToRAS()) transform.RotateX(value - self.oldPosition) redSlice.GetSliceToRAS().DeepCopy(transform.GetMatrix()) redSlice.UpdateMatrices() elif self.selector.currentNodeID == 'vtkMRMLSliceNodeYellow': logging.debug("yellow") redSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow') transform.SetMatrix(redSlice.GetSliceToRAS()) transform.RotateY(value - self.oldPosition) redSlice.GetSliceToRAS().DeepCopy(transform.GetMatrix()) redSlice.UpdateMatrices() elif self.selector.currentNodeID == 'vtkMRMLSliceNodeGreen': logging.debug("green") redSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeGreen') transform.SetMatrix(redSlice.GetSliceToRAS()) transform.RotateZ(value - self.oldPosition) redSlice.GetSliceToRAS().DeepCopy(transform.GetMatrix()) redSlice.UpdateMatrices() #self.slider.TypeOfTransform = self.slider.ROTATION_LR #self.slider.applyTransformation(self.slider.value - self.oldPosition) self.oldPosition = value
def run(self,referenceNode, inputNode, transformNode, outputNode): """ Run the actual algorithm """ dimensions = [1,1,1] referenceNode.GetImageData().GetDimensions(dimensions) inputIJK2RASMatrix = vtk.vtkMatrix4x4() inputNode.GetIJKToRASMatrix(inputIJK2RASMatrix) referenceRAS2IJKMatrix = vtk.vtkMatrix4x4() referenceNode.GetRASToIJKMatrix(referenceRAS2IJKMatrix) inputRAS2RASMatrix = transformNode.GetMatrixTransformToParent() resampleTransform = vtk.vtkTransform() resampleTransform.Identity() resampleTransform.PostMultiply() resampleTransform.SetMatrix(inputIJK2RASMatrix) resampleTransform.Concatenate(inputRAS2RASMatrix) resampleTransform.Concatenate(referenceRAS2IJKMatrix) resampleTransform.Inverse() resampler = vtk.vtkImageReslice() resampler.SetInput(inputNode.GetImageData()) resampler.SetOutputOrigin(0,0,0) resampler.SetOutputSpacing(1,1,1) resampler.SetOutputExtent(0,dimensions[0],0,dimensions[1],0,dimensions[2]) resampler.SetResliceTransform(resampleTransform) resampler.Update() outputNode.CopyOrientation(referenceNode) outputNode.SetAndObserveImageData(resampler.GetOutput()) return True
def __init__(self, sliceWidget): super(LevelTracingEffectTool,self).__init__(sliceWidget) # create a logic instance to do the non-gui work self.logic = LevelTracingEffectLogic(self.sliceWidget.sliceLogic()) # instance variables self.actionState = '' # initialization self.xyPoints = vtk.vtkPoints() self.rasPoints = vtk.vtkPoints() self.polyData = vtk.vtkPolyData() self.tracingFilter = vtkITK.vtkITKLevelTracingImageFilter() self.ijkToXY = vtk.vtkTransform() self.mapper = vtk.vtkPolyDataMapper2D() self.actor = vtk.vtkActor2D() property_ = self.actor.GetProperty() property_.SetColor( 107/255., 190/255., 99/255. ) property_.SetLineWidth( 1 ) self.mapper.SetInput(self.polyData) self.actor.SetMapper(self.mapper) property_ = self.actor.GetProperty() property_.SetColor(1,1,0) property_.SetLineWidth(1) self.renderer.AddActor2D( self.actor ) self.actors.append( self.actor )
def updateCurrentPosition(self): matrixSourceToTarget = vtk.vtkMatrix4x4() self.transformSourceNode.GetMatrixTransformToNode(self.transformTargetNode,matrixSourceToTarget) transformSourceToTarget = vtk.vtkTransform() transformSourceToTarget.SetMatrix(matrixSourceToTarget) transformSourceToTarget.GetPosition(self.currentPositionMm) # determine self.currentDistanceFromPointNMinus2Mm if (self.markupsFiducialNode.GetNumberOfFiducials() >= 2): pointNMinus2Mm = [0,0,0] self.markupsFiducialNode.GetNthFiducialPosition(self.markupsFiducialNode.GetNumberOfFiducials() - 2, pointNMinus2Mm) positionRelativeToPointNMinus2Mm = [0,0,0] vtk.vtkMath.Subtract(self.currentPositionMm,pointNMinus2Mm,positionRelativeToPointNMinus2Mm) self.currentDistanceFromPointNMinus2Mm = vtk.vtkMath.Norm(positionRelativeToPointNMinus2Mm) else: self.currentDistanceFromPointNMinus2Mm = 0 # determine self.currentDistanceFromPointNMinus3Mm if (self.markupsFiducialNode.GetNumberOfFiducials() >= 3): pointNMinus3Mm = [0,0,0] # second last point self.markupsFiducialNode.GetNthFiducialPosition(self.markupsFiducialNode.GetNumberOfFiducials() - 3, pointNMinus3Mm) positionRelativeToPointNMinus3Mm = [0,0,0] vtk.vtkMath.Subtract(self.currentPositionMm,pointNMinus3Mm,positionRelativeToPointNMinus3Mm) self.currentDistanceFromPointNMinus3Mm = vtk.vtkMath.Norm(positionRelativeToPointNMinus3Mm) else: self.currentDistanceFromPointNMinus3Mm = 0
def updateCurrentPosition(self): matrixSourceToTarget = vtk.vtkMatrix4x4() self.transformSourceNode.GetMatrixTransformToNode( self.transformTargetNode, matrixSourceToTarget) transformSourceToTarget = vtk.vtkTransform() transformSourceToTarget.SetMatrix(matrixSourceToTarget) transformSourceToTarget.GetPosition(self.currentPositionMm) # determine self.currentDistanceFromPointNMinus2Mm if (self.markupsFiducialNode.GetNumberOfFiducials() >= 2): pointNMinus2Mm = [0, 0, 0] self.markupsFiducialNode.GetNthFiducialPosition( self.markupsFiducialNode.GetNumberOfFiducials() - 2, pointNMinus2Mm) positionRelativeToPointNMinus2Mm = [0, 0, 0] vtk.vtkMath.Subtract(self.currentPositionMm, pointNMinus2Mm, positionRelativeToPointNMinus2Mm) self.currentDistanceFromPointNMinus2Mm = vtk.vtkMath.Norm( positionRelativeToPointNMinus2Mm) else: self.currentDistanceFromPointNMinus2Mm = 0 # determine self.currentDistanceFromPointNMinus3Mm if (self.markupsFiducialNode.GetNumberOfFiducials() >= 3): pointNMinus3Mm = [0, 0, 0] # second last point self.markupsFiducialNode.GetNthFiducialPosition( self.markupsFiducialNode.GetNumberOfFiducials() - 3, pointNMinus3Mm) positionRelativeToPointNMinus3Mm = [0, 0, 0] vtk.vtkMath.Subtract(self.currentPositionMm, pointNMinus3Mm, positionRelativeToPointNMinus3Mm) self.currentDistanceFromPointNMinus3Mm = vtk.vtkMath.Norm( positionRelativeToPointNMinus3Mm) else: self.currentDistanceFromPointNMinus3Mm = 0
def setTransform(self, handIndex, fingerIndex, fingerTipPosition): transformName = "Hand%iFinger%i" % (handIndex + 1, fingerIndex + 1 ) #设定手ID和指头ID print('transform:', transformName) transform = slicer.util.getNode(transformName) # Create the transform if does not exist yet if not transform: if self.enableAutoCreateTransforms: #如果复选判断框打开则在次场景中新建一个tranform # Create the missing transform transform = slicer.vtkMRMLLinearTransformNode() transform.SetName(transformName) slicer.mrmlScene.AddNode(transform) else: # No transform exist, so just ignore the finger return #通过VTK创建一个transform newTransform = vtk.vtkTransform() # 赋值transform,这里只是赋值给了tranform平移的信息,如果加入旋转的信息也可以在这里,或者缩放的信息 newTransform.Translate(-fingerTipPosition[0], fingerTipPosition[2], fingerTipPosition[1]) print('fingerTipPositiion:', fingerTipPosition ) #fingerTipPosition应该是一个坐标,但是也许是一个LPS坐标,所以这里需要转换为RAS坐标 transform.SetMatrixTransformToParent(newTransform.GetMatrix())
def onApplyButton(self): """ Aply the Surface ICP Registration """ print("Run the algorithm") fixed = self.modelSelectors['Fixed Surface Volume'].currentNode() moving = self.modelSelectors['Moving Surface Volume'].currentNode() outputSurf = self.modelOutputSurfaceSelectors['Output Surface Volume'].currentNode() initialTrans = self.volumeInitialTransformSelectors["Initial Transform"].currentNode() outputTrans = self.volumeOutputTransformSelectors["Output Transform"].currentNode() inputPolyData = moving.GetPolyData() if initialTrans: print "Applying initial transform" initialMatrix = initialTrans.GetMatrixTransformToParent() transform = vtk.vtkTransform() transform.SetMatrix(initialMatrix) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInput(inputPolyData) transformFilter.SetTransform(transform) transformFilter.Update() inputPolyData = transformFilter.GetOutput() self.icp.SetSource(inputPolyData) self.icp.SetTarget(fixed.GetPolyData()) print self.icpLandmarkTransformType if self.icpLandmarkTransformType == "RigidBody": print self.icpLandmarkTransformType self.icp.GetLandmarkTransform().SetModeToRigidBody() elif self.icpLandmarkTransformType == "Similarity": print self.icpLandmarkTransformType self.icp.GetLandmarkTransform().SetModeToSimilarity() print self.icpLandmarkTransformType elif self.icpLandmarkTransformType == "Affine": self.icp.GetLandmarkTransform().SetModeToAffine() self.icp.SetMaximumNumberOfIterations(self.numberOfIterationsValueChanged) self.icp.SetMaximumMeanDistance(self.maxDistanceValueChanged) self.icp.SetMaximumNumberOfLandmarks(self.numberOfLandmarksValueChanged) self.icp.SetCheckMeanDistance(int(self.checkMeanDistanceActive)) self.icp.SetStartByMatchingCentroids(int(self.matchCentroidsLinearActive)) #self.icp.Update print self.icp.GetLandmarkTransform() outputMatrix = vtk.vtkMatrix4x4() self.icp.GetMatrix(outputMatrix) outputTrans.SetAndObserveMatrixTransformToParent(outputMatrix) outputPolyData = vtk.vtkPolyData() outputPolyData.DeepCopy(inputPolyData) outputSurf.SetAndObservePolyData(outputPolyData) print self.icp.GetLandmarkTransform() print self.icp.GetLandmarkTransform().GetSourceLandmarks() print self.icp.GetLandmarkTransform().GetTargetLandmarks() print self.icp.GetMaximumMeanDistance() print self.icp.GetMeanDistanceModeAsString() print self.icp.GetMaximumNumberOfIterations() print self.icp.GetMaximumNumberOfLandmarks()
def __init__(self,fixed=None,moving=None,transform=None,fiducial=None,checked = None): self.interval = 2 self.timer = None # parameter defaults self.sampleSpacing = 10 self.gradientWindow = 1 self.stepSize = 1 # slicer nodes set by the GUI self.fixed = fixed self.moving = moving self.transform = transform self.fiducial = fiducial self.checked = checked # optimizer state variables self.iteration = 0 self.position = [0, 0, 0] self.paintCoordinates = [] self.x0, self.y0, self.z0 = 0,0,0 self.tx0, self.ty0,self.tz0 = 0,0,0 self.m = vtk.vtkMatrix4x4() self.r = vtk.vtkTransform() self.transformNode,self.neutral = None, None self.before = 0 self.plan = 'plan' self.actionState = "idle" self.interactorObserverTags = [] self.styleObserverTags = [] self.sliceWidgetsPerStyle = {} self.tac=0 self.WMAX = 0 self.L=[] self.divider = 1 self.step = 1 # helper objects self.scratchMatrix = vtk.vtkMatrix4x4() self.ijkToRAS = vtk.vtkMatrix4x4() self.rasToIJK = vtk.vtkMatrix4x4() self.reslice = vtk.vtkImageReslice() self.resliceTransform = vtk.vtkTransform() self.viewer = None self.render = None
def test_Regimatic1(self): """Set up two copies of the same data and try to recover identity""" self.delayDisplay("Starting the test",50) # # first, get some data # import urllib downloads = ( ('http://www.slicer.org/slicerWiki/images/4/43/MR-head.nrrd', 'Head_moving.nrrd', slicer.util.loadVolume), ('http://www.slicer.org/slicerWiki/images/4/43/MR-head.nrrd', 'Head_fixed.nrrd', slicer.util.loadVolume), ) for url,name,loader in downloads: filePath = slicer.app.temporaryPath + '/' + name if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: print('Requesting download %s from %s...\n' % (name, url)) urllib.urlretrieve(url, filePath) if loader: print('Loading %s...\n' % (name,)) loader(filePath) self.delayDisplay('Finished with download and loading\n',50) volumeNode = slicer.util.getNode(pattern="Head") # Create transform node movingToFixed = slicer.vtkMRMLLinearTransformNode() movingToFixed.SetName('movingToFixed') slicer.mrmlScene.AddNode(movingToFixed) # set up the nodes for viewing fixed = slicer.util.getNode('Head_fixed') moving = slicer.util.getNode('Head_moving') moving.SetAndObserveTransformNodeID(movingToFixed.GetID()) compositeNodes = slicer.util.getNodes('vtkMRMLSliceCompositeNode*') for compositeNode in compositeNodes.values(): compositeNode.SetBackgroundVolumeID(fixed.GetID()) compositeNode.SetForegroundVolumeID(moving.GetID()) compositeNode.SetForegroundOpacity(0.5) applicationLogic = slicer.app.applicationLogic() applicationLogic.FitSliceToAll() # apply an initial transform transform = vtk.vtkTransform() # transform.RotateWXYZ(.1, 1,1,1) # TODO: fix quaternion transform.Translate(50, 33, -32) movingToFixed.SetMatrixTransformToParent(transform.GetMatrix()) mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('Regimatic') regimaticWidget = slicer.modules.RegimaticWidget regimaticWidget.fixedSelector.setCurrentNode(fixed) regimaticWidget.movingSelector.setCurrentNode(moving) self.delayDisplay('Test passed!',50)
def updateTransform(self, shape, value): #translation shape A if shape == 'A': transform_node = slicer.mrmlScene.GetFirstNodeByName( "Translation " + self.shapeA_name) if transform_node is not None: transform = vtk.vtkTransform() transform.Translate(value, 0, 0) transform_node.SetAndObserveTransformToParent(transform) #translation shape B if shape == 'B': transform_node = slicer.mrmlScene.GetFirstNodeByName( "Translation " + self.shapeB_name) if transform_node is not None: transform = vtk.vtkTransform() transform.Translate(-value, 0, 0) transform_node.SetAndObserveTransformToParent(transform)
def retargetTools(self, targetFid): if self.markupsNode is None or \ targetFid.GetNumberOfFiducials() < 1 or \ targetFid == self.markupsNode: return import numpy import numpy.linalg import math # Get target coordinates targetLoc = [0, 0, 0] targetFid.GetNthFiducialPosition(0, targetLoc) targetLoc = numpy.array(targetLoc) # Iterate through port tool map and retarget their associated tools for i in range(self.markupsNode.GetNumberOfFiducials()): portLocList = [0, 0, 0] self.markupsNode.GetNthFiducialPosition(i, portLocList) portLoc = numpy.array(portLocList) # Assume tools get drawn aligned with the global y-axis. We # want to transform the tool to be oriented along the port # toward the target point. We begin by finding the axis to # rotate the tool by, which is the cross product of the # global y and the target vector targetVec = targetLoc - portLoc if numpy.linalg.norm(targetVec) <= 0.0000001: continue targetVec = targetVec / numpy.linalg.norm(targetVec) mat = vtk.vtkMatrix4x4() self.toolList[i].transformNode.GetMatrixTransformToWorld(mat) currentVec = numpy.array([mat.GetElement(j, 1) for j in [0, 1, 2]]) rotAxis = numpy.cross(currentVec, targetVec) normRotAxis = numpy.linalg.norm(rotAxis) if normRotAxis <= 0.000001: continue # get rotation angle and normalize rotation axis rotAxis = rotAxis / numpy.linalg.norm(rotAxis) angle = math.acos(numpy.dot(currentVec, targetVec)) * 180. / math.pi # generate our transform t = vtk.vtkTransform() trans = [mat.GetElement(j, 3) for j in [0, 1, 2]] negTrans = [-x for x in trans] t.Translate(trans) t.RotateWXYZ(angle, rotAxis.tolist()) t.Translate(negTrans) self.toolList[i].transformNode.ApplyTransformMatrix(t.GetMatrix())
def updatePosition(self, p): mat = vtk.vtkMatrix4x4() self.transformNode.GetMatrixTransformToWorld(mat) currPos = [mat.GetElement(j, 3) for j in [0,1,2]] trans = [x - y for (x,y) in zip(p, currPos)] t = vtk.vtkTransform() t.Translate(trans) self.transformNode.ApplyTransformMatrix(t.GetMatrix())
def ConvertTextureToPointAttribute(modelNode, textureImageNode): polyData=modelNode.GetPolyData() textureImageFlipVert=vtk.vtkImageFlip() textureImageFlipVert.SetFilteredAxis(1) textureImageFlipVert.SetInputConnection(textureImageNode.GetImageDataConnection()) textureImageFlipVert.Update() textureImageData=textureImageFlipVert.GetOutput() pointData=polyData.GetPointData() tcoords=pointData.GetTCoords() numOfPoints=pointData.GetNumberOfTuples() assert numOfPoints==tcoords.GetNumberOfTuples(), "Number of texture coordinates does not equal number of points" textureSamplingPointsUv=vtk.vtkPoints() textureSamplingPointsUv.SetNumberOfPoints(numOfPoints) for pointIndex in xrange(numOfPoints): uv=tcoords.GetTuple2(pointIndex) textureSamplingPointsUv.SetPoint(pointIndex, uv[0], uv[1], 0) textureSamplingPointDataUv=vtk.vtkPolyData() uvToXyz=vtk.vtkTransform() textureImageDataSpacingSpacing=textureImageData.GetSpacing() textureImageDataSpacingOrigin=textureImageData.GetOrigin() textureImageDataSpacingDimensions=textureImageData.GetDimensions() uvToXyz.Scale(textureImageDataSpacingDimensions[0]/textureImageDataSpacingSpacing[0], textureImageDataSpacingDimensions[1]/textureImageDataSpacingSpacing[1], 1) uvToXyz.Translate(textureImageDataSpacingOrigin) textureSamplingPointDataUv.SetPoints(textureSamplingPointsUv) transformPolyDataToXyz=vtk.vtkTransformPolyDataFilter() transformPolyDataToXyz.SetInputData(textureSamplingPointDataUv) transformPolyDataToXyz.SetTransform(uvToXyz) probeFilter=vtk.vtkProbeFilter() probeFilter.SetInputConnection(transformPolyDataToXyz.GetOutputPort()) probeFilter.SetSourceData(textureImageData) probeFilter.Update() rgbPoints=probeFilter.GetOutput().GetPointData().GetArray('ImageScalars') colorArrayRed=vtk.vtkDoubleArray() colorArrayRed.SetName('ColorRed') colorArrayRed.SetNumberOfTuples(numOfPoints) colorArrayGreen=vtk.vtkDoubleArray() colorArrayGreen.SetName('ColorGreen') colorArrayGreen.SetNumberOfTuples(numOfPoints) colorArrayBlue=vtk.vtkDoubleArray() colorArrayBlue.SetName('ColorBlue') colorArrayBlue.SetNumberOfTuples(numOfPoints) for pointIndex in xrange(numOfPoints): rgb=rgbPoints.GetTuple3(pointIndex) colorArrayRed.SetValue(pointIndex,rgb[0]) colorArrayGreen.SetValue(pointIndex,rgb[1]) colorArrayBlue.SetValue(pointIndex,rgb[2]) colorArrayRed.Modified() colorArrayGreen.Modified() colorArrayBlue.Modified() pointData.AddArray(colorArrayRed) pointData.AddArray(colorArrayGreen) pointData.AddArray(colorArrayBlue) pointData.Modified() polyData.Modified()
def retargetTools(self, targetFid): if self.markupsNode is None or \ targetFid.GetNumberOfFiducials() < 1 or \ targetFid == self.markupsNode: return import numpy import numpy.linalg import math # Get target coordinates targetLoc = [0,0,0] targetFid.GetNthFiducialPosition(0, targetLoc) targetLoc = numpy.array(targetLoc) # Iterate through port tool map and retarget their associated tools for i in range(self.markupsNode.GetNumberOfFiducials()): portLocList = [0,0,0] self.markupsNode.GetNthFiducialPosition(i, portLocList) portLoc = numpy.array(portLocList) # Assume tools get drawn aligned with the global y-axis. We # want to transform the tool to be oriented along the port # toward the target point. We begin by finding the axis to # rotate the tool by, which is the cross product of the # global y and the target vector targetVec = targetLoc - portLoc if numpy.linalg.norm(targetVec) <= 0.0000001: continue targetVec = targetVec / numpy.linalg.norm(targetVec) mat = vtk.vtkMatrix4x4() self.toolList[i].transformNode.GetMatrixTransformToWorld(mat) currentVec = numpy.array([mat.GetElement(j, 1) for j in [0,1,2]]) rotAxis = numpy.cross(currentVec, targetVec) normRotAxis = numpy.linalg.norm(rotAxis) if normRotAxis <= 0.000001: continue # get rotation angle and normalize rotation axis rotAxis = rotAxis / numpy.linalg.norm(rotAxis) angle = math.acos(numpy.dot(currentVec, targetVec)) * 180. / math.pi # generate our transform t = vtk.vtkTransform() trans = [mat.GetElement(j, 3) for j in [0,1,2]] negTrans = [-x for x in trans] t.Translate(trans) t.RotateWXYZ(angle, rotAxis.tolist()) t.Translate(negTrans) self.toolList[i].transformNode.ApplyTransformMatrix(t.GetMatrix())
def maskVolume(self, volumeIn, roiNode, inPlace=False): # Clone input volume, unless inPlace inPlace = False # TODO: make this work nameout = volumeIn.GetName() if not "masked" in nameout: nameout += " masked" if inPlace: outData = vtk.vtkImageData() volumeIn.SetName(volumeIn.GetName() + " masked") else: volumeOut = slicer.modules.volumes.logic().CloneVolume(volumeIn, nameout) outData = volumeOut.GetImageData() # Get transform into image space IJKtoRAS = vtk.vtkMatrix4x4() volumeIn.GetIJKToRASMatrix(IJKtoRAS) # Get ROI to image transform ROItoImage = vtk.vtkMatrix4x4() ROItoImage.Identity() parentNode = roiNode.GetParentTransformNode() if parentNode is None and volumeIn.GetParentTransformNode(): volumeIn.GetParentTransformNode().GetMatrixTransformToWorld(ROItoImage) # don't invert here, this is already the proper direction. if parentNode is not None: parentNode.GetMatrixTransformToNode(volumeIn.GetParentTransformNode(), ROItoImage) ROItoImage.Invert() # Transformations tfm = vtk.vtkTransform() tfm.SetMatrix(IJKtoRAS) tfm.PostMultiply() tfm.Concatenate(ROItoImage) # Get planes and apply transform planes = vtk.vtkPlanes() roiNode.GetTransformedPlanes(planes) planes.SetTransform(tfm) # Blot out selected region tostencil = vtk.vtkImplicitFunctionToImageStencil() tostencil.SetInput(planes) imgstencil = vtk.vtkImageStencil() imgstencil.SetInput(volumeIn.GetImageData()) imgstencil.SetStencil(tostencil.GetOutput()) imgstencil.SetBackgroundValue(0) imgstencil.ReverseStencilOn() # Write the changes imgstencil.SetOutput(outData) imgstencil.Update()
def rotate(self,fi,theta,psi): self.tx0 = self.m.GetElement(0,3) self.ty0 = self.m.GetElement(1,3) self.tz0 = self.m.GetElement(2,3) self.r = vtk.vtkTransform() self.r.Translate([self.tx0,self.ty0,self.tz0]) #self.r.Translate(new_rot_point) self.r.RotateWXYZ(theta,0,1,0) self.r.RotateWXYZ(psi,0,0,1) self.r.RotateWXYZ(fi,1,0,0) self.r.Translate([-self.tx0,-self.ty0,-self.tz0]) self.transform.ApplyTransformMatrix(self.r.GetMatrix())
def positionActors(self): """ update draw feedback to follow slice node """ sliceLogic = self.sliceWidget.sliceLogic() sliceNode = sliceLogic.GetSliceNode() rasToXY = vtk.vtkTransform() rasToXY.SetMatrix( sliceNode.GetXYToRAS() ) rasToXY.Inverse() self.xyPoints.Reset() rasToXY.TransformPoints( self.rasPoints, self.xyPoints ) self.polyData.Modified() self.sliceView.scheduleRender()
def positionActors(self): """ update draw feedback to follow slice node """ sliceLogic = self.sliceWidget.sliceLogic() sliceNode = sliceLogic.GetSliceNode() rasToXY = vtk.vtkTransform() rasToXY.SetMatrix(sliceNode.GetXYToRAS()) rasToXY.Inverse() self.xyPoints.Reset() rasToXY.TransformPoints(self.rasPoints, self.xyPoints) self.polyData.Modified() self.sliceView.scheduleRender()
def marchingCubes( self, image, ijkToRasMatrix, threshold ): transformIJKtoRAS = vtk.vtkTransform() transformIJKtoRAS.SetMatrix( ijkToRasMatrix ) marchingCubes = vtk.vtkMarchingCubes() marchingCubes.SetInput( image ) marchingCubes.SetValue( 0, threshold ) marchingCubes.ComputeScalarsOn() marchingCubes.ComputeGradientsOn() marchingCubes.ComputeNormalsOn() marchingCubes.GetOutput().ReleaseDataFlagOn() marchingCubes.Update() if transformIJKtoRAS.GetMatrix().Determinant() < 0: reverser = vtk.vtkReverseSense() reverser.SetInput( marchingCubes.GetOutput() ) reverser.ReverseNormalsOn() reverser.GetOutput().ReleaseDataFlagOn() reverser.Update() correctedOutput = reverser.GetOutput() else: correctedOutput = marchingCubes.GetOutput() transformer = vtk.vtkTransformPolyDataFilter() transformer.SetInput( correctedOutput ) transformer.SetTransform( transformIJKtoRAS ) transformer.GetOutput().ReleaseDataFlagOn() transformer.Update() normals = vtk.vtkPolyDataNormals() normals.ComputePointNormalsOn() normals.SetInput( transformer.GetOutput() ) normals.SetFeatureAngle( 60 ) normals.SetSplitting( 1 ) normals.GetOutput().ReleaseDataFlagOn() normals.Update() stripper = vtk.vtkStripper() stripper.SetInput( normals.GetOutput() ) stripper.GetOutput().ReleaseDataFlagOff() stripper.Update() stripper.GetOutput().Update() result = vtk.vtkPolyData() result.DeepCopy( stripper.GetOutput() ) result.Update() return result
def marchingCubes(self,image,ijkToRasMatrix,threshold): transformIJKtoRAS = vtk.vtkTransform() transformIJKtoRAS.SetMatrix(ijkToRasMatrix) marchingCubes = vtk.vtkMarchingCubes() marchingCubes.SetInput(image) marchingCubes.SetValue(0,threshold) marchingCubes.ComputeScalarsOn() marchingCubes.ComputeGradientsOn() marchingCubes.ComputeNormalsOn() marchingCubes.GetOutput().ReleaseDataFlagOn() marchingCubes.Update() if transformIJKtoRAS.GetMatrix().Determinant() < 0: reverser = vtk.vtkReverseSense() reverser.SetInput(marchingCubes.GetOutput()) reverser.ReverseNormalsOn() reverser.GetOutput().ReleaseDataFlagOn() reverser.Update() correctedOutput = reverser.GetOutput() else: correctedOutput = marchingCubes.GetOutput() transformer = vtk.vtkTransformPolyDataFilter() transformer.SetInput(correctedOutput) transformer.SetTransform(transformIJKtoRAS) transformer.GetOutput().ReleaseDataFlagOn() transformer.Update() normals = vtk.vtkPolyDataNormals() normals.ComputePointNormalsOn() normals.SetInput(transformer.GetOutput()) normals.SetFeatureAngle(60) normals.SetSplitting(1) normals.GetOutput().ReleaseDataFlagOn() normals.Update() stripper = vtk.vtkStripper() stripper.SetInput(normals.GetOutput()) stripper.GetOutput().ReleaseDataFlagOff() stripper.Update() stripper.GetOutput().Update() result = vtk.vtkPolyData() result.DeepCopy(stripper.GetOutput()) result.Update() return result
def eulers(self,cmd): p = urlparse.urlparse(cmd) q = urlparse.parse_qs(p.query) self.logMessage (q) alpha,beta,gamma = map(float,q['angles'][0].split(',')) self.setupMRMLTracking() transform = vtk.vtkTransform() transform.RotateZ(alpha) transform.RotateX(beta) transform.RotateY(gamma) self.tracker.SetMatrixTransformToParent(transform.GetMatrix()) return ( "got it" )
def rotateOrthogonalSlicesDeg(self, axialNode, ortho1Node, ortho2Node, rotationChangeDeg): """ Rotate the orthogonal nodes around the common intersection point, around the normal of the axial node """ # All points and vectors are in RAS coordinate system intersectionPoint = self.getPlaneIntersectionPoint( axialNode, ortho1Node, ortho2Node) axialSliceToRas = axialNode.GetSliceToRAS() rotationTransform = vtk.vtkTransform() rotationTransform.RotateZ(rotationChangeDeg) #rotatedAxialSliceToRas = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(axialSliceToRas, rotationTransform.GetMatrix(), axialSliceToRas) # Invert the direction of the two vectors so that by default they produce the same slice orientation as Slicer's # "sagittal" and "coronal" slice orientation if the axial node is in "axial" orientation axialSliceNormal = [ -axialSliceToRas.GetElement(0, 2), -axialSliceToRas.GetElement(1, 2), -axialSliceToRas.GetElement(2, 2) ] axialSliceAxisX = [ -axialSliceToRas.GetElement(0, 0), -axialSliceToRas.GetElement(1, 0), -axialSliceToRas.GetElement(2, 0) ] paraSagittalOrientationCode = 1 paraCoronalOrientationCode = 2 ortho1Node.SetSliceToRASByNTP( axialSliceNormal[0], axialSliceNormal[1], axialSliceNormal[2], axialSliceAxisX[0], axialSliceAxisX[1], axialSliceAxisX[2], intersectionPoint[0], intersectionPoint[1], intersectionPoint[2], paraSagittalOrientationCode) ortho2Node.SetSliceToRASByNTP( axialSliceNormal[0], axialSliceNormal[1], axialSliceNormal[2], axialSliceAxisX[0], axialSliceAxisX[1], axialSliceAxisX[2], intersectionPoint[0], intersectionPoint[1], intersectionPoint[2], paraCoronalOrientationCode) return True
def generateCylinderPolyData(self,x,y): cylinderHeightMm = 80 cylinderRadiusMm = 1 cylinderSource = vtk.vtkCylinderSource() cylinderSource.SetHeight(cylinderHeightMm) cylinderSource.SetRadius(cylinderRadiusMm) renderDepthMm = -cylinderHeightMm # negative because in graphics, negative is depth, positive goes toward the user transform = vtk.vtkTransform() transform.Translate(x,y,renderDepthMm) transform.RotateX(90) # rotate so that the cylinder follows the z axis transformFilter = vtk.vtkTransformFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(cylinderSource.GetOutputPort(0)) transformFilter.Update() polyData = transformFilter.GetOutput() return polyData
def calculateGoldStandard(scan,x,y,z,block,block_rot,fid_rot): transform = vtk.vtkTransform() transform.RotateY(int(fid_rot)) transform.RotateZ(-int(block)) transform.RotateY(int(block_rot)) transform.Translate(-int(x)*50,int(z)*10,-int(y)*50) ### Debug ### n = slicer.mrmlScene.CreateNodeByClass("vtkMRMLLinearTransformNode") n.SetName("Transform_GoldStandard_Serie"+str(scan)) slicer.mrmlScene.AddNode(n) n.SetAndObserveMatrixTransformToParent(transform.GetMatrix()) ############# return 0
def generateCylinderPolyData(self, x, y): cylinderHeightMm = 80 cylinderRadiusMm = 1 cylinderSource = vtk.vtkCylinderSource() cylinderSource.SetHeight(cylinderHeightMm) cylinderSource.SetRadius(cylinderRadiusMm) renderDepthMm = -cylinderHeightMm # negative because in graphics, negative is depth, positive goes toward the user transform = vtk.vtkTransform() transform.Translate(x, y, renderDepthMm) transform.RotateX(90) # rotate so that the cylinder follows the z axis transformFilter = vtk.vtkTransformFilter() transformFilter.SetTransform(transform) transformFilter.SetInputConnection(cylinderSource.GetOutputPort(0)) transformFilter.Update() polyData = transformFilter.GetOutput() return polyData
def PointsToSurfacePolyData( self, inPoints, reverse ): # Create a polydata object from the points pointsPolyData = vtk.vtkPolyData() pointsPolyData.SetPoints( inPoints ) # Create the surface filter from the polydata surfaceFilter = vtk.vtkSurfaceReconstructionFilter() surfaceFilter.SetInputData( pointsPolyData ) surfaceFilter.Update() # Do the contouring filter, and reverse to ensure it works properly contourFilter = vtk.vtkContourFilter() contourFilter.SetValue( 0, 0.0 ) contourFilter.SetInputData( surfaceFilter.GetOutput() ) contourFilter.Update() # Reverse the normals if necessary reverseFilter = vtk.vtkReverseSense() reverseFilter.SetInputData( contourFilter.GetOutput() ) reverseFilter.SetReverseCells( reverse ) reverseFilter.SetReverseNormals( reverse ) reverseFilter.Update() # Reset the scaling to let the surface match the points fiducialBounds = [ 0, 0, 0, 0, 0, 0 ] pointsPolyData.GetBounds( fiducialBounds ) tissueBounds = [ 0, 0, 0, 0, 0, 0 ] reverseFilter.GetOutput().GetBounds( tissueBounds ) scaleX = ( fiducialBounds[1] - fiducialBounds[0] ) / ( tissueBounds[1] - tissueBounds[0] ) scaleY = ( fiducialBounds[3] - fiducialBounds[2] ) / ( tissueBounds[3] - tissueBounds[2] ) scaleZ = ( fiducialBounds[5] - fiducialBounds[4] ) / ( tissueBounds[5] - tissueBounds[4] ) transform = vtk.vtkTransform() transform.Translate( fiducialBounds[0], fiducialBounds[2], fiducialBounds[4] ) transform.Scale( scaleX, scaleY, scaleZ ) transform.Translate( - tissueBounds[0], - tissueBounds[2], - tissueBounds[4] ) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputData( reverseFilter.GetOutput() ) transformFilter.SetTransform( transform ) transformFilter.Update() return transformFilter.GetOutput()
def __init__(self): self.scene = slicer.mrmlScene self.scene.SetUndoOn() self.scene.SaveStateForUndo(self.scene.GetNodes()) self.currentSlice = Slice('/luscinia/ProstateStudy/invivo/Patient59/loupas/RadialImagesCC_imwrite/arfi_ts3_26.57.png') # yay, adding images to slicer planeSource = vtk.vtkPlaneSource() planeSource.SetCenter(self.currentSlice.x, self.currentSlice.y, self.currentSlice.z) reader = vtk.vtkPNGReader() reader.SetFileName(self.currentSlice.name) # model node self.model = slicer.vtkMRMLModelNode() self.model.SetScene(self.scene) self.model.SetName(self.currentSlice.name) self.model.SetAndObservePolyData(planeSource.GetOutput()) # model display node self.modelDisplay = slicer.vtkMRMLModelDisplayNode() self.modelDisplay.BackfaceCullingOff() # so plane can be seen from both front and back face self.modelDisplay.SetScene(self.scene) self.scene.AddNode(self.modelDisplay) # connecting model node w/ its model display node self.model.SetAndObserveDisplayNodeID(self.modelDisplay.GetID()) # adding tiff file as texture to modelDisplay self.modelDisplay.SetAndObserveTextureImageData(reader.GetOutput()) self.scene.AddNode(self.model) # now doing a linear transform to set coordinates and orientation of plane self.transform = slicer.vtkMRMLLinearTransformNode() self.scene.AddNode(self.transform) self.model.SetAndObserveTransformNodeID(self.transform.GetID()) vTransform = vtk.vtkTransform() vTransform.Scale(150, 150, 150) vTransform.RotateX(0) vTransform.RotateY(0) vTransform.RotateZ(0) self.transform.SetAndObserveMatrixTransformToParent(vTransform.GetMatrix())
def selectSlice(self, index): self.scene.Undo() self.scene.SaveStateForUndo(self.scene.GetNodes()) imgFilePrefix = './data/test' imgFileSuffix = '.tiff' # yay, adding images to slicer planeSource = vtk.vtkPlaneSource() reader = vtk.vtkTIFFReader() reader.SetFileName(imgFilePrefix + str(self.imageList[index]) + imgFileSuffix) #reader.CanReadFile('imgFilePrefix + str(self.imageList[0]) + imgFileSuffix') # model node model = slicer.vtkMRMLModelNode() model.SetScene(self.scene) model.SetName("test " + str(self.imageList[index]) + "cow") model.SetAndObservePolyData(planeSource.GetOutput()) # model display node modelDisplay = slicer.vtkMRMLModelDisplayNode() modelDisplay.BackfaceCullingOff() # so plane can be seen from both front and back face modelDisplay.SetScene(self.scene) self.scene.AddNode(modelDisplay) # connecting model node w/ its model display node model.SetAndObserveDisplayNodeID(modelDisplay.GetID()) # adding tiff file as texture to modelDisplay modelDisplay.SetAndObserveTextureImageData(reader.GetOutput()) self.scene.AddNode(model) # now doing a linear transform to set coordinates and orientation of plane transform = slicer.vtkMRMLLinearTransformNode() self.scene.AddNode(transform) model.SetAndObserveTransformNodeID(transform.GetID()) vTransform = vtk.vtkTransform() vTransform.Scale(150, 150, 150) vTransform.RotateX(self.rotateXList[index]) vTransform.RotateY(self.rotateYList[index]) vTransform.RotateZ(self.rotateZList[index]) transform.SetAndObserveMatrixTransformToParent(vTransform.GetMatrix())
def updateScene(self): #self.scene.Undo() #self.scene.SaveStateForUndo(self.scene.GetNodes()) self.scene.RemoveNode(self.transform) self.scene.RemoveNode(self.modelDisplay) self.scene.RemoveNode(self.model) planeSource = vtk.vtkPlaneSource() planeSource.SetCenter(self.currentSlice.x, self.currentSlice.y, self.currentSlice.z) reader = vtk.vtkPNGReader() reader.SetFileName(self.currentSlice.name) # model node self.model = slicer.vtkMRMLModelNode() self.model.SetScene(self.scene) self.model.SetName(self.currentSlice.name) self.model.SetAndObservePolyData(planeSource.GetOutput()) # model display node self.modelDisplay = slicer.vtkMRMLModelDisplayNode() self.modelDisplay.BackfaceCullingOff() # so plane can be seen from both front and back face self.modelDisplay.SetScene(self.scene) self.scene.AddNode(self.modelDisplay) # connecting model node w/ its model display node self.model.SetAndObserveDisplayNodeID(self.modelDisplay.GetID()) # adding tiff file as texture to modelDisplay self.modelDisplay.SetAndObserveTextureImageData(reader.GetOutput()) self.scene.AddNode(self.model) # now doing a linear transform to set coordinates and orientation of plane self.transform = slicer.vtkMRMLLinearTransformNode() self.scene.AddNode(self.transform) self.model.SetAndObserveTransformNodeID(self.transform.GetID()) vTransform = vtk.vtkTransform() vTransform.Scale(self.currentSlice.scaling, self.currentSlice.scaling, self.currentSlice.scaling) vTransform.RotateX(self.currentSlice.xAngle) vTransform.RotateY(self.currentSlice.yAngle) vTransform.RotateZ(self.currentSlice.zAngle) self.transform.SetAndObserveMatrixTransformToParent(vTransform.GetMatrix())
def AddDamageTemplateModel(self,scene,LineLandmarkTransform ): # check if already implemented if ( self.DamageTemplateModel != None ): print "removing", self.DamageTemplateModel.GetName() scene.RemoveNode(self.DamageTemplateModel) # create sphere and scale vtkSphere = vtk.vtkSphereSource() vtkSphere.SetRadius(1.) vtkSphere.SetThetaResolution(16) vtkSphere.SetPhiResolution(16) ScaleAffineTransform = vtk.vtkTransform() ScaleAffineTransform.Scale([self.AblationMinorAxis,self.AblationMajorAxis,self.AblationMinorAxis]) vtkEllipsoid= vtk.vtkTransformFilter() vtkEllipsoid.SetInput(vtkSphere.GetOutput() ) vtkEllipsoid.SetTransform( ScaleAffineTransform ) vtkEllipsoid.Update() slicertransformFilter = vtk.vtkTransformFilter() slicertransformFilter.SetInput(vtkEllipsoid.GetOutput() ) slicertransformFilter.SetTransform( LineLandmarkTransform ) slicertransformFilter.Update() dampolyData=slicertransformFilter.GetOutput(); # Create model node self.DamageTemplateModel = slicer.vtkMRMLModelNode() self.DamageTemplateModel.SetScene(scene) #self.DamageTemplateModel.SetName(scene.GenerateUniqueName("Treatment-%s" % fiducialsNode.GetName())) self.DamageTemplateModel.SetName( scene.GenerateUniqueName("Treatment") ) self.DamageTemplateModel.SetAndObservePolyData(dampolyData) # Create display node modelDisplay = slicer.vtkMRMLModelDisplayNode() modelDisplay.SetColor(1,1,0) # yellow modelDisplay.SetOpacity(0.3) modelDisplay.SetScene(scene) scene.AddNode(modelDisplay) self.DamageTemplateModel.SetAndObserveDisplayNodeID(modelDisplay.GetID()) # Add to scene modelDisplay.SetInputPolyData(self.DamageTemplateModel.GetPolyData()) scene.AddNode(self.DamageTemplateModel)
def setTransform(self, handIndex, fingerIndex, fingerTipPosition): transformName = "Hand%iFinger%i" % (handIndex+1,fingerIndex+1) # +1 because to have 1-based indexes for the hands and fingers print transformName transform = slicer.util.getNode(transformName) # Create the transform if does not exist yet if not transform : if self.enableAutoCreateTransforms : # Create the missing transform transform = slicer.vtkMRMLLinearTransformNode() transform.SetName(transformName) slicer.mrmlScene.AddNode(transform) else : # No transform exist, so just ignore the finger return newTransform = vtk.vtkTransform() # Reorder and reorient to match the LeapMotion's coordinate system with RAS coordinate system newTransform.Translate(-fingerTipPosition[0], fingerTipPosition[2], fingerTipPosition[1]) transform.SetMatrixTransformToParent(newTransform.GetMatrix())
def GenerateCylinderLabelMap(self,needleTransform, image, outputMask, radius, length, offset, refineRate = 3): # Get needle matrix needleMatrix = needleTransform.GetMatrixTransformToParent() # Create cylinder cylinderSource = vtk.vtkCylinderSource() cylinderSource.SetCenter(0.0, 0.0, 0.0) cylinderSource.SetRadius(radius) cylinderSource.SetHeight(length) cylinderSource.SetResolution(240) cylinderSource.Update() # Move cylinder to needleTransform transformCylinder = vtk.vtkTransform() transformCylinder.RotateX(90) transformCylinder.Translate(0.0, -length/2, 0.0) transformCylinder.PostMultiply() transformCylinder.Concatenate(needleMatrix) transformCylinder.Update() transformPolyData = vtk.vtkTransformPolyDataFilter() transformPolyData.SetInputConnection(cylinderSource.GetOutputPort()) transformPolyData.SetTransform(transformCylinder) transformPolyData.Update() # Add nodes to the scene modelDisplayNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLModelDisplayNode") modelDisplayNode.SetColor(1.0,0.0,0.0) slicer.mrmlScene.AddNode(modelDisplayNode) modelNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLModelNode") modelNode.SetName("CylinderModel") modelNode.SetAndObservePolyData(transformPolyData.GetOutput()) modelNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID()) modelNode.Modified() slicer.mrmlScene.AddNode(modelNode) # Call ModelToLabelMap module cliNode = self.runModelToLabelMap(image, modelNode, outputMask, refineRate)
def setTransform(self, handIndex, fingerIndex, fingerTipPosition): transformName = "Hand%iFinger%i" % ( handIndex + 1, fingerIndex + 1 ) # +1 because to have 1-based indexes for the hands and fingers print transformName transform = slicer.util.getNode(transformName) # Create the transform if does not exist yet if not transform: if self.enableAutoCreateTransforms: # Create the missing transform transform = slicer.vtkMRMLLinearTransformNode() transform.SetName(transformName) slicer.mrmlScene.AddNode(transform) else: # No transform exist, so just ignore the finger return newTransform = vtk.vtkTransform() # Reorder and reorient to match the LeapMotion's coordinate system with RAS coordinate system newTransform.Translate(-fingerTipPosition[0], fingerTipPosition[2], fingerTipPosition[1]) transform.SetMatrixTransformToParent(newTransform.GetMatrix())
def resampleInputVolumeNodetoReferenceVolumeNode(self, inputVolumeNode, referenceVolumeNode, outputVolumeNode): if not inputVolumeNode or not referenceVolumeNode or not outputVolumeNode: print "Volumes not initialized." return inputVolumeIJK2RASMatrix = vtk.vtkMatrix4x4() inputVolumeNode.GetIJKToRASMatrix(inputVolumeIJK2RASMatrix) referenceVolumeRAS2IJKMatrix = vtk.vtkMatrix4x4() referenceVolumeNode.GetRASToIJKMatrix(referenceVolumeRAS2IJKMatrix) dimensions = referenceVolumeNode.GetImageData().GetDimensions() outputVolumeResliceTransform = vtk.vtkTransform() outputVolumeResliceTransform.Identity() outputVolumeResliceTransform.PostMultiply() outputVolumeResliceTransform.SetMatrix(inputVolumeIJK2RASMatrix) if inputVolumeNode.GetTransformNodeID() is not None: inputVolumeNodeTransformNode = slicer.util.getNode(inputVolumeNode.GetTransformNodeID()) inputVolumeRAS2RASMatrix = vtk.vtkMatrix4x4() if inputVolumeNodeTransformNode is not None: inputVolumeNodeTransformNode.GetMatrixTransformToWorld(inputVolumeRAS2RASMatrix) outputVolumeResliceTransform.Concatenate(inputVolumeRAS2RASMatrix) outputVolumeResliceTransform.Concatenate(referenceVolumeRAS2IJKMatrix) outputVolumeResliceTransform.Inverse() resliceFilter = vtk.vtkImageReslice() resliceFilter.SetInput(inputVolumeNode.GetImageData()) resliceFilter.SetOutputOrigin(0, 0, 0) resliceFilter.SetOutputSpacing(1, 1, 1) resliceFilter.SetOutputExtent(0, dimensions[0]-1, 0, dimensions[1]-1, 0, dimensions[2]-1) resliceFilter.SetResliceTransform(outputVolumeResliceTransform) resliceFilter.Update() outputVolumeNode.CopyOrientation(referenceVolumeNode) outputVolumeNode.SetAndObserveImageData(resliceFilter.GetOutput()) return
def makeMaskImage(self, polyData): """ Create a screen space (2D) mask image for the given polydata. Need to know the mapping from RAS into polygon space so the painter can use this as a mask - need the bounds in RAS space - need to get an IJKToRAS for just the mask area - directions are the XYToRAS for this slice - origin is the lower left of the polygon bounds - TODO: need to account for the boundary pixels Note: uses the slicer2-based vtkImageFillROI filter """ labelLogic = self.sliceLogic.GetLabelLayer() sliceNode = self.sliceLogic.GetSliceNode() maskIJKToRAS = vtk.vtkMatrix4x4() maskIJKToRAS.DeepCopy(sliceNode.GetXYToRAS()) polyData.GetPoints().Modified() bounds = polyData.GetBounds() xlo = bounds[0] - 1 xhi = bounds[1] ylo = bounds[2] - 1 yhi = bounds[3] originRAS = self.xyToRAS((xlo, ylo)) maskIJKToRAS.SetElement(0, 3, originRAS[0]) maskIJKToRAS.SetElement(1, 3, originRAS[1]) maskIJKToRAS.SetElement(2, 3, originRAS[2]) # # get a good size for the draw buffer # - needs to include the full region of the polygon # - plus a little extra # # round to int and add extra pixel for both sides # -- TODO: figure out why we need to add buffer pixels on each # side for the width in order to end up with a single extra # pixel in the rasterized image map. Probably has to # do with how boundary conditions are handled in the filler w = int(xhi - xlo) + 32 h = int(yhi - ylo) + 32 imageData = vtk.vtkImageData() imageData.SetDimensions(w, h, 1) labelNode = labelLogic.GetVolumeNode() if not labelNode: return labelImage = labelNode.GetImageData() if not labelImage: return if vtk.VTK_MAJOR_VERSION <= 5: imageData.SetScalarType(labelImage.GetScalarType()) imageData.AllocateScalars() else: imageData.AllocateScalars(labelImage.GetScalarType(), 1) # # move the points so the lower left corner of the # bounding box is at 1, 1 (to avoid clipping) # translate = vtk.vtkTransform() translate.Translate(-1. * xlo, -1. * ylo, 0) drawPoints = vtk.vtkPoints() drawPoints.Reset() translate.TransformPoints(polyData.GetPoints(), drawPoints) drawPoints.Modified() fill = slicer.vtkImageFillROI() if vtk.VTK_MAJOR_VERSION <= 5: fill.SetInput(imageData) else: fill.SetInputData(imageData) fill.SetValue(1) fill.SetPoints(drawPoints) fill.Update() mask = vtk.vtkImageData() mask.DeepCopy(fill.GetOutput()) return [maskIJKToRAS, mask]
def p2pCyl(startPoint, endPoint, radius=10, modName="Cyl", plus=0, Seg=3, color="red", Opacity=1, RotY=0, Tx=0): """12 prisms of point-to-point""" cylinderSource = vtk.vtkCylinderSource() cylinderSource.SetRadius(radius) cylinderSource.SetResolution(Seg) rng = vtk.vtkMinimalStandardRandomSequence() rng.SetSeed(8775070) # For testing 8775070 # Compute a basis normalizedX = [0] * 3 normalizedY = [0] * 3 normalizedZ = [0] * 3 # The X axis is a vector from start to end vtk.vtkMath.Subtract(endPoint, startPoint, normalizedX) length = vtk.vtkMath.Norm(normalizedX) + plus # length = 20 vtk.vtkMath.Normalize(normalizedX) # The Xn axis is an arbitrary vector cross X arbitrary = [0] * 3 for i in range(0, 3): rng.Next() arbitrary[i] = rng.GetRangeValue(-10, 10) vtk.vtkMath.Cross(normalizedX, arbitrary, normalizedZ) vtk.vtkMath.Normalize(normalizedZ) # The Zn axis is Xn cross X vtk.vtkMath.Cross(normalizedZ, normalizedX, normalizedY) matrix = vtk.vtkMatrix4x4() # Create the direction cosine matrix matrix.Identity() for i in range(0, 3): matrix.SetElement(i, 0, normalizedX[i]) matrix.SetElement(i, 1, normalizedY[i]) matrix.SetElement(i, 2, normalizedZ[i]) # Apply the transforms transform = vtk.vtkTransform() transform.Translate(startPoint) # translate to starting point transform.Concatenate(matrix) # apply direction cosines transform.RotateZ(-90.0) # align cylinder to x axis transform.Scale(1.0, length, 1.0) # scale along the height vector transform.Translate(0, .5, 0) # translate to start of cylinder transform.RotateY(RotY) transform.Translate(Tx, 0, 0) # Transform the polydata transformPD = vtk.vtkTransformPolyDataFilter() transformPD.SetTransform(transform) transformPD.SetInputConnection(cylinderSource.GetOutputPort()) stlMapper = vtk.vtkPolyDataMapper() stlMapper.SetInputConnection(transformPD.GetOutputPort()) vtkNode = slicer.modules.models.logic().AddModel(transformPD.GetOutputPort()) vtkNode.SetName(modName) modelDisplay = vtkNode.GetDisplayNode() modelDisplay.SetColor(Helper.myColor(color)) modelDisplay.SetOpacity(Opacity) modelDisplay.SetBackfaceCulling(0) # modelDisplay.SetVisibility(1) modelDisplay.SetVisibility2D(True) # modelDisplay.SetSliceDisplayModeToProjection() # dn.SetVisibility2D(True) return
def PolyDataToImageData(self, inputPolydata_Ras, referenceVolumeNode_Ras, inVal=100, outVal=0): """ We take in an polydata and convert it to an new image data , withing the Reference Voulume node the reference volume node is cleared with a threshold because originally the volume may contain alot of noisy pixels PARAM: inputPolydata_Ras: Polydata we are looking to conver vtkPolydata() PARAM: refernceVolumeNode_Ras vtkMRMLScalarVolumeNode() RETURN : vtkImageData """ """ Transform the polydata from ras to ijk using the referenceVolumeNode """ #inputPolydataTriangulated_Ijk=polyToImage.GetOutput() transformPolydataFilter = vtk.vtkTransformPolyDataFilter() rasToIjkMatrix = vtk.vtkMatrix4x4() referenceVolumeNode_Ras.GetRASToIJKMatrix(rasToIjkMatrix) rasToIjkTransform = vtk.vtkTransform() rasToIjkTransform.SetMatrix(rasToIjkMatrix) transformPolydataFilter.SetTransform(rasToIjkTransform) transformPolydataFilter.SetInputData(inputPolydata_Ras) transformPolydataFilter.Update() inputPolydata_Ijk = transformPolydataFilter.GetOutput() normalsFunction = vtk.vtkPolyDataNormals() normalsFunction.SetInputData(inputPolydata_Ijk) normalsFunction.ConsistencyOn() trigFilter = vtk.vtkTriangleFilter() trigFilter.SetInputConnection(normalsFunction.GetOutputPort()) stripper = vtk.vtkStripper() stripper.SetInputConnection(trigFilter.GetOutputPort()) stripper.Update() inputPolydataTriangulated_Ijk = stripper.GetOutput() # Clone reference image and clear it referenceImage_Ijk = referenceVolumeNode_Ras.GetImageData() # Fill image with outVal (there is no volume Fill filter in VTK, therefore we need to use threshold filter) thresh = vtk.vtkImageThreshold() thresh.ReplaceInOn() thresh.ReplaceOutOn() thresh.SetInValue(outVal) thresh.SetOutValue(outVal) #thresh.SetOutputScalarType (vtk.VTK_UNSIGNED_CHAR) thresh.SetInputData(referenceImage_Ijk) thresh.Update() whiteImage_Ijk = thresh.GetOutput() # Convert polydata to stencil polyToImage = vtk.vtkPolyDataToImageStencil() polyToImage.SetInputData(inputPolydataTriangulated_Ijk) polyToImage.SetOutputSpacing(whiteImage_Ijk.GetSpacing()) polyToImage.SetOutputOrigin(whiteImage_Ijk.GetOrigin()) polyToImage.SetOutputWholeExtent(whiteImage_Ijk.GetExtent()) polyToImage.Update() imageStencil_Ijk = polyToImage.GetOutput() # Convert stencil to image imgstenc = vtk.vtkImageStencil() imgstenc.SetInputData(whiteImage_Ijk) imgstenc.SetStencilData(imageStencil_Ijk) imgstenc.ReverseStencilOn() imgstenc.SetBackgroundValue(inVal) imgstenc.Update() return imgstenc.GetOutput()
def convertTextureToPointAttribute(self, modelNode, textureImageNode, colorAsVector): polyData = modelNode.GetPolyData() textureImageFlipVert = vtk.vtkImageFlip() textureImageFlipVert.SetFilteredAxis(1) textureImageFlipVert.SetInputConnection( textureImageNode.GetImageDataConnection()) textureImageFlipVert.Update() textureImageData = textureImageFlipVert.GetOutput() pointData = polyData.GetPointData() tcoords = pointData.GetTCoords() numOfPoints = pointData.GetNumberOfTuples() assert numOfPoints == tcoords.GetNumberOfTuples( ), "Number of texture coordinates does not equal number of points" textureSamplingPointsUv = vtk.vtkPoints() textureSamplingPointsUv.SetNumberOfPoints(numOfPoints) for pointIndex in range(numOfPoints): uv = tcoords.GetTuple2(pointIndex) textureSamplingPointsUv.SetPoint(pointIndex, uv[0], uv[1], 0) textureSamplingPointDataUv = vtk.vtkPolyData() uvToXyz = vtk.vtkTransform() textureImageDataSpacingSpacing = textureImageData.GetSpacing() textureImageDataSpacingOrigin = textureImageData.GetOrigin() textureImageDataSpacingDimensions = textureImageData.GetDimensions() uvToXyz.Scale( textureImageDataSpacingDimensions[0] / textureImageDataSpacingSpacing[0], textureImageDataSpacingDimensions[1] / textureImageDataSpacingSpacing[1], 1) uvToXyz.Translate(textureImageDataSpacingOrigin) textureSamplingPointDataUv.SetPoints(textureSamplingPointsUv) transformPolyDataToXyz = vtk.vtkTransformPolyDataFilter() transformPolyDataToXyz.SetInputData(textureSamplingPointDataUv) transformPolyDataToXyz.SetTransform(uvToXyz) probeFilter = vtk.vtkProbeFilter() probeFilter.SetInputConnection(transformPolyDataToXyz.GetOutputPort()) probeFilter.SetSourceData(textureImageData) probeFilter.Update() rgbPoints = probeFilter.GetOutput().GetPointData().GetArray( 'ImageScalars') if colorAsVector: colorArray = vtk.vtkDoubleArray() colorArray.SetName('Color') colorArray.SetNumberOfComponents(3) colorArray.SetNumberOfTuples(numOfPoints) for pointIndex in range(numOfPoints): rgb = rgbPoints.GetTuple3(pointIndex) colorArray.SetTuple3(pointIndex, rgb[0] / 255., rgb[1] / 255., rgb[2] / 255.) colorArray.Modified() pointData.AddArray(colorArray) else: colorArrayRed = vtk.vtkDoubleArray() colorArrayRed.SetName('ColorRed') colorArrayRed.SetNumberOfTuples(numOfPoints) colorArrayGreen = vtk.vtkDoubleArray() colorArrayGreen.SetName('ColorGreen') colorArrayGreen.SetNumberOfTuples(numOfPoints) colorArrayBlue = vtk.vtkDoubleArray() colorArrayBlue.SetName('ColorBlue') colorArrayBlue.SetNumberOfTuples(numOfPoints) for pointIndex in range(numOfPoints): rgb = rgbPoints.GetTuple3(pointIndex) colorArrayRed.SetValue(pointIndex, rgb[0]) colorArrayGreen.SetValue(pointIndex, rgb[1]) colorArrayBlue.SetValue(pointIndex, rgb[2]) colorArrayRed.Modified() colorArrayGreen.Modified() colorArrayBlue.Modified() pointData.AddArray(colorArrayRed) pointData.AddArray(colorArrayGreen) pointData.AddArray(colorArrayBlue) pointData.Modified() polyData.Modified()
def clipVolumeWithModel(self, inputVolume, clippingModel, clipOutsideSurface, fillOutsideValue, clipInsideSurface, fillInsideValue, outputVolume): """ Fill voxels of the input volume inside/outside the clipping model with the provided fill value """ # Determine the transform between the box and the image IJK coordinate systems rasToModel = vtk.vtkMatrix4x4() if clippingModel.GetTransformNodeID() != None: modelTransformNode = slicer.mrmlScene.GetNodeByID( clippingModel.GetTransformNodeID()) boxToRas = vtk.vtkMatrix4x4() modelTransformNode.GetMatrixTransformToWorld(boxToRas) rasToModel.DeepCopy(boxToRas) rasToModel.Invert() ijkToRas = vtk.vtkMatrix4x4() inputVolume.GetIJKToRASMatrix(ijkToRas) ijkToModel = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(rasToModel, ijkToRas, ijkToModel) modelToIjkTransform = vtk.vtkTransform() modelToIjkTransform.SetMatrix(ijkToModel) modelToIjkTransform.Inverse() transformModelToIjk = vtk.vtkTransformPolyDataFilter() transformModelToIjk.SetTransform(modelToIjkTransform) transformModelToIjk.SetInputConnection( clippingModel.GetPolyDataConnection()) # Use the stencil to fill the volume # Convert model to stencil polyToStencil = vtk.vtkPolyDataToImageStencil() polyToStencil.SetInputConnection(transformModelToIjk.GetOutputPort()) polyToStencil.SetOutputSpacing(inputVolume.GetImageData().GetSpacing()) polyToStencil.SetOutputOrigin(inputVolume.GetImageData().GetOrigin()) polyToStencil.SetOutputWholeExtent( inputVolume.GetImageData().GetExtent()) # Apply the stencil to the volume stencilToImage = vtk.vtkImageStencil() stencilToImage.SetInputConnection(inputVolume.GetImageDataConnection()) stencilToImage.SetStencilConnection(polyToStencil.GetOutputPort()) # Create a copy of the input volume to work on outputImageData = vtk.vtkImageData() outputImageData.DeepCopy(inputVolume.GetImageData()) outputVolume.SetAndObserveImageData(outputImageData) outputVolume.SetIJKToRASMatrix(ijkToRas) # Update volume with the stencil operation result depending on user choices if clipOutsideSurface: stencilToImage.ReverseStencilOff() stencilToImage.SetBackgroundValue(fillOutsideValue) stencilToImage.Update() outputImageData.DeepCopy(stencilToImage.GetOutput()) outputVolume.SetAndObserveImageData(outputImageData) outputVolume.SetIJKToRASMatrix(ijkToRas) if clipInsideSurface: stencilToImage.SetInputConnection( outputVolume.GetImageDataConnection()) stencilToImage.ReverseStencilOn() stencilToImage.SetBackgroundValue(fillInsideValue) stencilToImage.Update() outputImageData.DeepCopy(stencilToImage.GetOutput()) outputVolume.SetAndObserveImageData(outputImageData) outputVolume.SetIJKToRASMatrix(ijkToRas) # Add a default display node to output volume node if it does not exist yet if not outputVolume.GetDisplayNode: displayNode = slicer.vtkMRMLScalarVolumeDisplayNode() displayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeGrey") slicer.mrmlScene.AddNode(displayNode) outputVolume.SetAndObserveDisplayNodeID(displayNode.GetID()) return True
def recolorLabelMap(self, modelNode, labelMap, initialValue, outputValue): import vtkSlicerRtCommonPython if (modelNode != None and labelMap != None): self.labelMapImgData = labelMap.GetImageData() self.resectionPolyData = modelNode.GetPolyData() # IJK -> RAS ijkToRasMatrix = vtk.vtkMatrix4x4() labelMap.GetIJKToRASMatrix(ijkToRasMatrix) # RAS -> IJK rasToIjkMatrix = vtk.vtkMatrix4x4() labelMap.GetRASToIJKMatrix(rasToIjkMatrix) rasToIjkTransform = vtk.vtkTransform() rasToIjkTransform.SetMatrix(rasToIjkMatrix) rasToIjkTransform.Update() # Transform Resection model from RAS -> IJK polyDataTransformFilter = vtk.vtkTransformPolyDataFilter() if (vtk.VTK_MAJOR_VERSION <= 5): polyDataTransformFilter.SetInput(self.resectionPolyData) else: polyDataTransformFilter.SetInputData(self.resectionPolyData) polyDataTransformFilter.SetTransform(rasToIjkTransform) polyDataTransformFilter.Update() # Convert Resection model to label map polyDataToLabelmapFilter = vtkSlicerRtCommonPython.vtkPolyDataToLabelmapFilter( ) polyDataToLabelmapFilter.SetInputPolyData( polyDataTransformFilter.GetOutput()) polyDataToLabelmapFilter.SetReferenceImage(self.labelMapImgData) polyDataToLabelmapFilter.UseReferenceValuesOn() polyDataToLabelmapFilter.SetBackgroundValue(0) polyDataToLabelmapFilter.SetLabelValue(outputValue) polyDataToLabelmapFilter.Update() # Cast resection label map to unsigned char for use with mask filter castFilter = vtk.vtkImageCast() if (vtk.VTK_MAJOR_VERSION <= 5): castFilter.SetInput(polyDataToLabelmapFilter.GetOutput()) else: castFilter.SetInputData(polyDataToLabelmapFilter.GetOutput()) castFilter.SetOutputScalarTypeToUnsignedChar() castFilter.Update() # Create mask for recoloring the original label map maskFilter = vtk.vtkImageMask() if (vtk.VTK_MAJOR_VERSION <= 5): maskFilter.SetImageInput(self.labelMapImgData) maskFilter.SetMaskInput(castFilter.GetOutput()) else: maskFilter.SetImageInputData(self.labelMapImgData) maskFilter.SetMaskInputData(castFilter.GetOutput()) maskFilter.SetMaskedOutputValue(outputValue) maskFilter.NotMaskOn() maskFilter.Update() self.labelMapImgData = maskFilter.GetOutput() self.labelMapImgData.Modified() labelMap.SetAndObserveImageData(self.labelMapImgData)
def makeMaskVolumeFromROI(self, refVolumeNode, maskVolumeNode, roiNode): # Create a box implicit function that will be used as a stencil to fill the volume roiBox = vtk.vtkBox() roiCenter = [0, 0, 0] roiNode.GetXYZ( roiCenter ) roiRadius = [0, 0, 0] roiNode.GetRadiusXYZ( roiRadius ) roiBox.SetBounds(roiCenter[0] - roiRadius[0], roiCenter[0] + roiRadius[0], roiCenter[1] - roiRadius[1], roiCenter[1] + roiRadius[1], roiCenter[2] - roiRadius[2], roiCenter[2] + roiRadius[2]) # Determine the transform between the box and the image IJK coordinate systems rasToBox = vtk.vtkMatrix4x4() if roiNode.GetTransformNodeID() != None: roiBoxTransformNode = slicer.mrmlScene.GetNodeByID(roiNode.GetTransformNodeID()) boxToRas = vtk.vtkMatrix4x4() roiBoxTransformNode.GetMatrixTransformToWorld(boxToRas) rasToBox.DeepCopy(boxToRas) rasToBox.Invert() ijkToRas = vtk.vtkMatrix4x4() refVolumeNode.GetIJKToRASMatrix( ijkToRas ) ijkToBox = vtk.vtkMatrix4x4() vtk.vtkMatrix4x4.Multiply4x4(rasToBox,ijkToRas,ijkToBox) ijkToBoxTransform = vtk.vtkTransform() ijkToBoxTransform.SetMatrix(ijkToBox) roiBox.SetTransform(ijkToBoxTransform) # Use the stencil to fill the volume imageData = vtk.vtkImageData() refImageData = refVolumeNode.GetImageData() imageData.SetOrigin(refImageData.GetOrigin()) imageData.SetSpacing(refImageData.GetSpacing()) if vtk.VTK_MAJOR_VERSION <= 5: imageData.SetExtent(refImageData.GetWholeExtent()) imageData.SetScalarTypeToUnsignedChar() imageData.AllocateScalars() else: imageData.SetExtent(refImageData.GetExtent()) imageData.AllocateScalars(vtk.VTK_UNSIGNED_CHAR,1) # Convert the implicit function to a stencil functionToStencil = vtk.vtkImplicitFunctionToImageStencil() functionToStencil.SetInput(roiBox) functionToStencil.SetOutputOrigin(refImageData.GetOrigin()) functionToStencil.SetOutputSpacing(refImageData.GetSpacing()) if vtk.VTK_MAJOR_VERSION <= 5: functionToStencil.SetOutputWholeExtent(refImageData.GetWholeExtent()) else: functionToStencil.SetOutputWholeExtent(refImageData.GetExtent()) functionToStencil.Update() # Apply the stencil to the volume stencilToImage=vtk.vtkImageStencil() if vtk.VTK_MAJOR_VERSION <= 5: stencilToImage.SetInput(imageData) stencilToImage.SetStencil(functionToStencil.GetOutput()) else: stencilToImage.SetInputData(imageData) stencilToImage.SetStencilData(functionToStencil.GetOutput()) stencilToImage.ReverseStencilOn() stencilToImage.SetBackgroundValue(1) stencilToImage.Update() # Update the volume with the stencil operation result maskVolumeNode.SetAndObserveImageData(stencilToImage.GetOutput()) maskVolumeNode.CopyOrientation(refVolumeNode)
def CreateSlit(self, normal, pathPolydata, ruler, ROI, slitSize): """ Here we are going to create a boxSource , the size of the 2*ROI in the X,Y and the size of the slit Size in the Z. We are then going to translate the box source to its correct location in slicer As always to visualize , a DEBUG option can be set at the top. x is L->R, y is P->A, z is I->S """ #Cube Creation roiPoints = self.utility.GetROIPoints(ROI) frontExtentIndex = self.utility.GetClosestExtent(ruler, ROI) backExtentIndex = self.utility.GetOppositeExtent(frontExtentIndex) pointA = numpy.array(roiPoints[frontExtentIndex]) pointB = numpy.array(roiPoints[backExtentIndex]) yDist = numpy.linalg.norm(pointA - pointB) numPoints = pathPolydata.GetNumberOfPoints() pointA = numpy.array(pathPolydata.GetPoint(0)) pointB = numpy.array(pathPolydata.GetPoint(numPoints - 1)) xDist = numpy.linalg.norm(pointA - pointB) zDist = slitSize #Rewording the parameter to make it easier to understand slitCube = vtk.vtkCubeSource() slitCube.SetBounds(0, xDist, -yDist, yDist, -zDist / 2, zDist / 2) # (Xmin, Xmax, Ymin, Ymax,Zmin, Zmax) #Transforming Cube transformFilter = vtk.vtkTransformFilter() transform = vtk.vtkTransform() matrix = vtk.vtkMatrix4x4() pointA = numpy.array(pathPolydata.GetPoint(0)) pointB = numpy.array(pathPolydata.GetPoint(numPoints - 1)) xVector = pointA - pointB xDist = numpy.linalg.norm(pointA - pointB) xUnitVector = (xVector[0] / xDist, xVector[1] / xDist, xVector[2] / xDist) yVector = self.utility.GetRulerVector(ruler) yDist = numpy.linalg.norm(yVector) yUnitVector = (yVector[0] / yDist, yVector[1] / yDist, yVector[2] / yDist) zVector = numpy.cross(xVector, yVector) zDist = numpy.linalg.norm(zVector) zUnitVector = (zVector[0] / zDist, zVector[1] / zDist, zVector[2] / zDist) origin = pointA = numpy.array(pathPolydata.GetPoint(numPoints - 1)) matrix.DeepCopy( (xUnitVector[0], yUnitVector[0], zUnitVector[0], origin[0], xUnitVector[1], yUnitVector[1], zUnitVector[1], origin[1], xUnitVector[2], yUnitVector[2], zUnitVector[2], origin[2], 0, 0, 0, 1)) transform.SetMatrix(matrix) transformFilter.SetTransform(transform) transformFilter.SetInputConnection(slitCube.GetOutputPort()) transformFilter.Update() self.slitPlanes.append(transformFilter.GetOutput()) if len(self.slitPlanes ) == self.numberOfPaths and self.DEBUG_SLITPLANES == True: for i in range(self.numberOfPaths): self.utility.DisplayPolyData("Slit" + str(i), self.slitPlanes[i]) return transformFilter.GetOutput()
def extractROI(originalVolumeID, newVolumeID, rasCoordinates, diameter): ''' ''' originalVolume = slicer.mrmlScene.GetNodeByID(originalVolumeID) newVolume = slicer.mrmlScene.GetNodeByID(newVolumeID) # code below converted from cropVolume module by A. Fedorov # optimized after that :) inputRASToIJK = vtk.vtkMatrix4x4() inputIJKToRAS = vtk.vtkMatrix4x4() outputIJKToRAS = vtk.vtkMatrix4x4() outputRASToIJK = vtk.vtkMatrix4x4() volumeXform = vtk.vtkMatrix4x4() T = vtk.vtkMatrix4x4() originalVolume.GetRASToIJKMatrix(inputRASToIJK) originalVolume.GetIJKToRASMatrix(inputIJKToRAS) outputIJKToRAS.Identity() outputRASToIJK.Identity() volumeXform.Identity() T.Identity() # if the originalVolume is under a transform volumeTransformNode = originalVolume.GetParentTransformNode() if volumeTransformNode: volumeTransformNode.GetMatrixTransformToWorld(volumeXform) volumeXform.Invert() maxSpacing = max(originalVolume.GetSpacing()) # build our box rX = diameter * 4 * maxSpacing rY = diameter * 4 * maxSpacing rZ = diameter * 4 * maxSpacing cX = rasCoordinates[0] cY = rasCoordinates[1] cZ = rasCoordinates[2] inputSpacingX = originalVolume.GetSpacing()[0] inputSpacingY = originalVolume.GetSpacing()[1] inputSpacingZ = originalVolume.GetSpacing()[2] outputExtentX = int(2.0 * rX / inputSpacingX) outputExtentY = int(2.0 * rY / inputSpacingY) outputExtentZ = int(2.0 * rZ / inputSpacingZ) # configure spacing outputIJKToRAS.SetElement(0, 0, inputSpacingX) outputIJKToRAS.SetElement(1, 1, inputSpacingY) outputIJKToRAS.SetElement(2, 2, inputSpacingZ) # configure origin outputIJKToRAS.SetElement(0, 3, (cX - rX + inputSpacingX * 0.5)) outputIJKToRAS.SetElement(1, 3, (cY - rY + inputSpacingY * 0.5)) outputIJKToRAS.SetElement(2, 3, (cZ - rZ + inputSpacingZ * 0.5)) outputRASToIJK.DeepCopy(outputIJKToRAS) outputRASToIJK.Invert() T.DeepCopy(outputIJKToRAS) T.Multiply4x4(volumeXform, T, T) T.Multiply4x4(inputRASToIJK, T, T) resliceT = vtk.vtkTransform() resliceT.SetMatrix(T) reslicer = vtk.vtkImageReslice() reslicer.SetInterpolationModeToLinear() reslicer.SetInput(originalVolume.GetImageData()) reslicer.SetOutputExtent(0, int(outputExtentX), 0, int(outputExtentY), 0, int(outputExtentZ)) reslicer.SetOutputOrigin(0, 0, 0) reslicer.SetOutputSpacing(1, 1, 1) #reslicer.SetOutputOrigin(image.GetOrigin()) #reslicer.SetOutputSpacing(image.GetSpacing()) reslicer.SetResliceTransform(resliceT) reslicer.UpdateWholeExtent() changer = vtk.vtkImageChangeInformation() changer.SetInput(reslicer.GetOutput()) changer.SetOutputOrigin(0, 0, 0) changer.SetOutputSpacing(1, 1, 1) #changer.SetOutputOrigin(image.GetOrigin()) # changer.SetOutputSpacing(image.GetSpacing()) changer.Update() outImageData = vtk.vtkImageData() outImageData.DeepCopy(changer.GetOutput()) outImageData.Update() newVolume.SetAndObserveImageData(outImageData) newVolume.SetIJKToRASMatrix(outputIJKToRAS) newVolume.SetRASToIJKMatrix(outputRASToIJK) newVolume.Modified() newVolume.SetModifiedSinceRead(1)