def probeVolume(self, volumeNode, rulerNode, numOfPoints):
    
    #get ruler end points in RAS coordinates system
    p0ras = rulerNode.GetPolyData().GetPoint(0) + (1,)
    p1ras = rulerNode.GetPolyData().GetPoint(1) + (1,)
    import math, numpy
    lineLength = math.sqrt((p0ras[0]-p1ras[0])*(p0ras[0]-p1ras[0]) + (p0ras[1]-p1ras[1])*(p0ras[1]-p1ras[1]) + (p0ras[2]-p1ras[2])*(p0ras[2]-p1ras[2]))
    distanceArray = [0]
    if (numOfPoints > 1):
      distanceArray = numpy.linspace(0,lineLength,numOfPoints)


    #The transformation matrix from RAS to IJK coordinates systems
    ras2ijk = vtk.vtkMatrix4x4()
    volumeNode.GetRASToIJKMatrix(ras2ijk)
    p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]]
    p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]]

    #Create the VTK sampling line
    line = vtk.vtkLineSource()
    line.SetResolution(numOfPoints)
    line.SetPoint1(p0ijk[0], p0ijk[1], p0ijk[2])
    line.SetPoint2(p1ijk[0], p1ijk[1], p1ijk[2])

    #Creat the VTK probe filter
    probe = vtk.vtkProbeFilter()
    probe.SetInputConnection(line.GetOutputPort())
    probe.SetSourceData(volumeNode.GetImageData())
    probe.Update()

    # return the sampled array
    return probe.GetOutput().GetPointData().GetArray('ImageScalars'), distanceArray
  def probeVolume(self,volumeNode,rulerNode):

    # get ruler endpoints coordinates in RAS
    p0ras = rulerNode.GetPolyData().GetPoint(0)+(1,)
    p1ras = rulerNode.GetPolyData().GetPoint(1)+(1,)
    
    # convert RAS to IJK coordinates of the vtkImageData
    ras2ijk = vtk.vtkMatrix4x4()
    volumeNode.GetRASToIJKMatrix(ras2ijk)
    p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]]
    p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]]

    # create VTK line that will be used for sampling
    line = vtk.vtkLineSource()
    line.SetResolution(100)
    line.SetPoint1(p0ijk[0], p0ijk[1], p0ijk[2])
    line.SetPoint2(p1ijk[0], p1ijk[1], p1ijk[2])
    
    # create VTK probe filter and sample the image
    probe = vtk.vtkProbeFilter()
    probe.SetInputConnection(line.GetOutputPort())
    probe.SetSourceData(volumeNode.GetImageData())
    probe.Update()

    # return VTK array
    return probe.GetOutput().GetPointData().GetArray('ImageScalars')
  def probeVolume(self, volumeNode, rulerNode):

    # initialize vtkLineSource from Slicer ruler
    # (ruler endpoints are in RAS)
    p0ras4 = rulerNode.GetPolyData().GetPoint(0)+(1,)
    p1ras4 = rulerNode.GetPolyData().GetPoint(1)+(1,)

    # convert to vtkImageData IJK coordinates
    ras2ijk = vtk.vtkMatrix4x4()
    volumeNode.GetRASToIJKMatrix(ras2ijk)

    p0ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras4)[:3]]
    p1ijk = [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras4)[:3]]

    # initialize vtkLineSource
    line = vtk.vtkLineSource()
    line.SetResolution(100)   # TODO: make this a parameter!
    line.SetPoint1(p0ijk[0], p0ijk[1], p0ijk[2])
    line.SetPoint2(p1ijk[0], p1ijk[1], p1ijk[2])

    # ready to probe the volume
    probe = vtk.vtkProbeFilter()
    probe.SetInputConnection(line.GetOutputPort())
    probe.SetSourceData(volumeNode.GetImageData())
    probe.Update()

    data = probe.GetOutput().GetPointData().GetArray('ImageScalars')
    for p in range(data.GetNumberOfTuples()):
      print data.GetTuple1(p),
    print

    return data
Exemple #4
0
    def lineModel(self, scene, point1, point2, name, color):

        """ Create a line to reflect the puncture path"""

        #Line mode source

        line = vtk.vtkLineSource()

        line.SetPoint1(point1)#(point1[0][0], point1[0][1], point1[0][2])

        line.SetPoint2(point2)#(point2[0][0], point2[0][1], point2[0][2])

        

        # Create model node

        lineModel = slicer.vtkMRMLModelNode()

        lineModel.SetScene(scene)

        lineModel.SetName(name)

        lineModel.SetAndObservePolyData(line.GetOutput())



        # Create display node

        lineModelDisplay = slicer.vtkMRMLModelDisplayNode()

        lineModelDisplay.SetColor(color)

        lineModelDisplay.SetScene(scene)

        scene.AddNode(lineModelDisplay)

        lineModel.SetAndObserveDisplayNodeID(lineModelDisplay.GetID())



        #Add to scene

#        lineModelDisplay.SetInputPolyData(line.GetOutput())
        lineModelDisplay.SetInputPolyDataConnection(line.GetOutputPort())

        scene.AddNode(lineModel)

        return line
  def createOptionalPathModel(self, pos, holeInfoList, intNumOfOptionalPath):
    if intNumOfOptionalPath == 1:
      self.setOptionalPathVisibility(1)

    pathListRAS = []

    for i in range(len(holeInfoList)):
      pathListRAS.append(self.templateRAS[holeInfoList[i][3]])

    print "pathListRAS: ", pathListRAS

    #(not generate path -> pass, otherwise go on)

    self.optModelNode = slicer.mrmlScene.GetNodeByID(self.optionalPathModelNodeID)
    if self.optModelNode == None:
      self.optModelNode = slicer.vtkMRMLModelNode()
      self.optModelNode.SetName('AllOptionalPaths')
      slicer.mrmlScene.AddNode(self.optModelNode)
      self.optionalPathModelNodeID = self.optModelNode.GetID()

      self.dnodeOpt = slicer.vtkMRMLModelDisplayNode()
      self.dnodeOpt.SetColor(0.96,0.92,0.56)
      slicer.mrmlScene.AddNode(self.dnodeOpt)
      self.optModelNode.SetAndObserveDisplayNodeID(self.dnodeOpt.GetID())

    optModelAppend = vtk.vtkAppendPolyData()

    #for path in pathListRAS:
    for index in range(len(pathListRAS)):
      optLineSource = vtk.vtkLineSource()
      optLineSource.SetPoint1(pos)
      optLineSource.SetPoint2(pathListRAS[index])

      optTubeFilter = vtk.vtkTubeFilter()
      optTubeFilter.SetInputConnection(optLineSource.GetOutputPort())
      optTubeFilter.SetRadius(1.0)
      optTubeFilter.SetNumberOfSides(10)
      optTubeFilter.CappingOn()
      optTubeFilter.Update()

      if vtk.VTK_MAJOR_VERSION <= 5:
        optModelAppend.AddInput(optTubeFilter.GetOutput())
      else:
        optModelAppend.AddInputData(optTubeFilter.GetOutput())

      optModelAppend.Update()
      self.optModelNode.SetAndObservePolyData(optModelAppend.GetOutput())
def createCylinder(name, R, H=50):
    cylinder = slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelNode')
    cylinder.SetName(slicer.mrmlScene.GetUniqueNameByString(name))
    slicer.mrmlScene.AddNode(cylinder)
    cylinder.CreateDefaultDisplayNodes()
    lineSource = vtk.vtkLineSource()
    lineSource.SetPoint1(0, 0, H / 2)
    lineSource.SetPoint2(0, 0, -H / 2)
    tubeFilter = vtk.vtkTubeFilter()
    tubeFilter.SetInputConnection(lineSource.GetOutputPort())
    tubeFilter.SetRadius(R)
    tubeFilter.SetNumberOfSides(50)
    tubeFilter.CappingOn()
    #tubeFilter.Update()
    cylinder.SetPolyDataConnection(tubeFilter.GetOutputPort())
    cylinder.SetAttribute('radius', str(R))
    cylinder.SetAttribute('height', str(H))
    return cylinder
  def probeVolume(self, volumeNode, rulerNode):
    p0ras=rulerNode.GetPolyData().GetPoint(0)+(1,)
    p1ras=rulerNode.GetPolyData().GetPoint(1)+(1,)
    
    ras2ijk=vtk.vtkMatrix4x4()
    volumeNode.GetRASToIJKMatrix(ras2ijk)
    p0ijk= [int(round(c)) for c in ras2ijk.MultiplyPoint(p0ras)[:3]]
    p1ijk= [int(round(c)) for c in ras2ijk.MultiplyPoint(p1ras)[:3]]
   
    line=vtk.vtkLineSource()
    line.SetPoint1(p0ijk[0],p0ijk[1],p0ijk[2])
    line.SetPoint2(p1ijk[0],p1ijk[1],p1ijk[2])
    line.SetResolution(100)

    probe=vtk.vtkProbeFilter()
    probe.SetInputConnection(line.GetOutputPort())
    probe.SetSourceData(volumeNode.GetImageData())
    probe.Update()

    return probe.GetOutput().GetPointData().GetArray('ImageScalars')
  def updateOutputArray(self,inputVolume,inputRuler,outputArray,numberOfLineSamples):
    rulerStartPoint_Ruler = [0,0,0]
    rulerEndPoint_Ruler = [0,0,0]
    inputRuler.GetPosition1(rulerStartPoint_Ruler)
    inputRuler.GetPosition2(rulerEndPoint_Ruler)
    rulerStartPoint_Ruler1 = [rulerStartPoint_Ruler[0], rulerStartPoint_Ruler[1], rulerStartPoint_Ruler[2], 1.0]
    rulerEndPoint_Ruler1 = [rulerEndPoint_Ruler[0], rulerEndPoint_Ruler[1], rulerEndPoint_Ruler[2], 1.0]
    
    rulerToRAS = vtk.vtkMatrix4x4()
    rulerTransformNode = inputRuler.GetParentTransformNode()
    if rulerTransformNode:
      if rulerTransformNode.IsTransformToWorldLinear():
        rulerToRAS.DeepCopy(rulerTransformNode.GetMatrixTransformToParent())
      else:
        print("Cannot handle non-linear transforms - ignoring transform of the input ruler")

    rulerStartPoint_RAS1 = [0,0,0,1]
    rulerEndPoint_RAS1 = [0,0,0,1]
    rulerToRAS.MultiplyPoint(rulerStartPoint_Ruler1,rulerStartPoint_RAS1)
    rulerToRAS.MultiplyPoint(rulerEndPoint_Ruler1,rulerEndPoint_RAS1)        
    
    rulerLengthMm = math.sqrt(vtk.vtkMath.Distance2BetweenPoints(rulerStartPoint_RAS1[0:3],rulerEndPoint_RAS1[0:3]))

    # Need to get the start/end point of the line in the IJK coordinate system
    # as VTK filters cannot take into account direction cosines        
    rasToIJK = vtk.vtkMatrix4x4()
    parentToIJK = vtk.vtkMatrix4x4()
    rasToParent = vtk.vtkMatrix4x4()
    inputVolume.GetRASToIJKMatrix(parentToIJK)
    transformNode = inputVolume.GetParentTransformNode()
    if transformNode:
      if transformNode.IsTransformToWorldLinear():
        rasToParent.DeepCopy(transformNode.GetMatrixTransformToParent())
        rasToParent.Invert()
      else:
        print ("Cannot handle non-linear transforms - ignoring transform of the input volume")
    vtk.vtkMatrix4x4.Multiply4x4(parentToIJK, rasToParent, rasToIJK)
    
    rulerStartPoint_IJK1 = [0,0,0,1]
    rulerEndPoint_IJK1 = [0,0,0,1]
    rasToIJK.MultiplyPoint(rulerStartPoint_RAS1,rulerStartPoint_IJK1)
    rasToIJK.MultiplyPoint(rulerEndPoint_RAS1,rulerEndPoint_IJK1) 
    
    lineSource = vtk.vtkLineSource()
    lineSource.SetPoint1(rulerStartPoint_IJK1[0],rulerStartPoint_IJK1[1],rulerStartPoint_IJK1[2])
    lineSource.SetPoint2(rulerEndPoint_IJK1[0], rulerEndPoint_IJK1[1], rulerEndPoint_IJK1[2])
    lineSource.SetResolution(numberOfLineSamples-1)

    probeFilter=vtk.vtkProbeFilter()
    probeFilter.SetInputConnection(lineSource.GetOutputPort())
    if vtk.VTK_MAJOR_VERSION <= 5:
      probeFilter.SetSource(inputVolume.GetImageData())
    else:
      probeFilter.SetSourceData(inputVolume.GetImageData())
    probeFilter.Update()

    probedPoints=probeFilter.GetOutput()

    # Create arrays of data  
    a = outputArray.GetArray()
    a.SetNumberOfTuples(probedPoints.GetNumberOfPoints())
    x = xrange(0, probedPoints.GetNumberOfPoints())
    xStep=rulerLengthMm/(probedPoints.GetNumberOfPoints()-1)
    probedPointScalars=probedPoints.GetPointData().GetScalars()
    for i in range(len(x)):
      a.SetComponent(i, 0, x[i]*xStep)
      a.SetComponent(i, 1, probedPointScalars.GetTuple(i)[0])
      a.SetComponent(i, 2, 0)
      
    probedPoints.GetPointData().GetScalars().Modified()
    def updateOutputTable(self, inputVolumes, inputRuler, outputTable,
                          lineResolution):
        rulerLengthMm = self.computeRulerLength(inputRuler)

        distanceArray = self.getArrayFromTable(outputTable,
                                               DISTANCE_ARRAY_NAME)

        probedPointsList = []
        intensityArrayList = []
        for inputVolume in inputVolumes:
            # Need to get the start/end point of the line in the IJK coordinate system
            # as VTK filters cannot take into account direction cosines
            rasToIJK = vtk.vtkMatrix4x4()
            parentToIJK = vtk.vtkMatrix4x4()
            rasToParent = vtk.vtkMatrix4x4()
            inputVolume.GetRASToIJKMatrix(parentToIJK)
            transformNode = inputVolume.GetParentTransformNode()
            if transformNode:
                if transformNode.IsTransformToWorldLinear():
                    rasToParent.DeepCopy(
                        transformNode.GetMatrixTransformToParent())
                    rasToParent.Invert()
                else:
                    print(
                        "Cannot handle non-linear transforms - ignoring transform of the input volume"
                    )
            vtk.vtkMatrix4x4.Multiply4x4(parentToIJK, rasToParent, rasToIJK)

            rulerStartPoint_IJK1 = [0, 0, 0, 1]
            rulerEndPoint_IJK1 = [0, 0, 0, 1]
            rasToIJK.MultiplyPoint(self.rulerStartPoint_RAS1,
                                   rulerStartPoint_IJK1)
            rasToIJK.MultiplyPoint(self.rulerEndPoint_RAS1, rulerEndPoint_IJK1)

            lineSource = vtk.vtkLineSource()
            lineSource.SetPoint1(rulerStartPoint_IJK1[0],
                                 rulerStartPoint_IJK1[1],
                                 rulerStartPoint_IJK1[2])
            lineSource.SetPoint2(rulerEndPoint_IJK1[0], rulerEndPoint_IJK1[1],
                                 rulerEndPoint_IJK1[2])
            lineSource.SetResolution(lineResolution - 1)

            probeFilter = vtk.vtkProbeFilter()
            probeFilter.SetInputConnection(lineSource.GetOutputPort())
            probeFilter.SetSourceData(inputVolume.GetImageData())
            probeFilter.Update()

            probedPoints = probeFilter.GetOutput()
            probedPointsList.append(probedPoints)

            intensityArrayName = INTENSITY_ARRAY_NAME + '_' + inputVolume.GetName(
            )
            intensityArrayList.append(
                self.getArrayFromTable(outputTable, intensityArrayName))

        # Fill tables
        for probeIndex in range(len(probedPointsList)):
            probedPoints = probedPointsList[probeIndex]
            intensityArray = intensityArrayList[probeIndex]

            # Create arrays of data
            outputTable.GetTable().SetNumberOfRows(
                probedPoints.GetNumberOfPoints())
            x = range(0, probedPoints.GetNumberOfPoints())
            xStep = rulerLengthMm / (probedPoints.GetNumberOfPoints() - 1)

            if probeIndex == 0:
                for i in range(len(x)):
                    distanceArray.SetValue(i, x[i] * xStep)

            probedPointScalars = probedPoints.GetPointData().GetScalars()
            for i in range(len(x)):
                intensityArray.SetValue(i, probedPointScalars.GetTuple(i)[0])
  def createTemplateModel(self):
    self.templatePathVectors = []
    self.templatePathOrigins = []

    tempModelNode = slicer.mrmlScene.GetNodeByID(self.templateModelNodeID)
    if tempModelNode == None:
      tempModelNode = slicer.vtkMRMLModelNode()
      tempModelNode.SetName('NeedleGuideTemplate')
      slicer.mrmlScene.AddNode(tempModelNode)
      self.templateModelNodeID = tempModelNode.GetID()

      dnode = slicer.vtkMRMLModelDisplayNode()
      slicer.mrmlScene.AddNode(dnode)
      tempModelNode.SetAndObserveDisplayNodeID(dnode.GetID())
      self.modelNodetag = tempModelNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent,
                                                    self.onTemplateTransformUpdated)

    tempModelAppend = vtk.vtkAppendPolyData()

    for row in self.templateConfig:
      p1 = numpy.array(row[0:3])
      p2 = numpy.array(row[3:6])

      tempLineSource = vtk.vtkLineSource()
      tempLineSource.SetPoint1(p1)
      tempLineSource.SetPoint2(p2)

      tempTubeFilter = vtk.vtkTubeFilter()
      tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort())
      tempTubeFilter.SetRadius(1.0)
      tempTubeFilter.SetNumberOfSides(18)
      tempTubeFilter.CappingOn()
      tempTubeFilter.Update()

      pathLineSource = vtk.vtkLineSource()
      v = p2-p1
      nl = numpy.linalg.norm(v)
      n = v/nl  # normal vector
      l = row[6]
      p3 = p1 + l * n
      pathLineSource.SetPoint1(p1)
      pathLineSource.SetPoint2(p3)

      self.templatePathOrigins.append([row[0], row[1], row[2], 1.0])
      self.templatePathVectors.append([n[0], n[1], n[2], 1.0])
      self.templateMaxDepth.append(row[6])

      pathTubeFilter = vtk.vtkTubeFilter()
      pathTubeFilter.SetInputConnection(pathLineSource.GetOutputPort())
      pathTubeFilter.SetRadius(0.8)
      pathTubeFilter.SetNumberOfSides(18)
      pathTubeFilter.CappingOn()
      pathTubeFilter.Update()

      if vtk.VTK_MAJOR_VERSION <= 5:
        tempModelAppend.AddInput(tempTubeFilter.GetOutput())
#        pathModelAppend.AddInput(pathTubeFilter.GetOutput())
      else:
        tempModelAppend.AddInputData(tempTubeFilter.GetOutput())
#        pathModelAppend.AddInputData(pathTubeFilter.GetOutput())

      tempModelAppend.Update()
      tempModelNode.SetAndObservePolyData(tempModelAppend.GetOutput())
  def visualNeedlePath(self, pos, pointOnTemplateRAS):
    if type(pointOnTemplateRAS) == list:
      pass
    elif type(pointOnTemplateRAS) == int:
      pointOnTemplateRAS = self.templateRAS[pointOnTemplateRAS]

    self.pathModelNode = slicer.mrmlScene.GetNodeByID(self.needlePathModelNodeID)
    if self.pathModelNode == None:
      self.pathModelNode = slicer.vtkMRMLModelNode()
      self.pathModelNode.SetName('AngulatedNeedlePath')
      slicer.mrmlScene.AddNode(self.pathModelNode)
      self.needlePathModelNodeID = self.pathModelNode.GetID()

      self.dnodeSelectedPath = slicer.vtkMRMLModelDisplayNode()
      self.dnodeSelectedPath.SetColor(0, 1, 1)
      slicer.mrmlScene.AddNode(self.dnodeSelectedPath)
      self.pathModelNode.SetAndObserveDisplayNodeID(self.dnodeSelectedPath.GetID())

    pathModelAppend = vtk.vtkAppendPolyData()

    tempLineSource = vtk.vtkLineSource()
    tempLineSource.SetPoint1(pos)  # target in RAS
    tempLineSource.SetPoint2(pointOnTemplateRAS)  # point on template in RAS

    tempTubeFilter = vtk.vtkTubeFilter()
    tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort())
    tempTubeFilter.SetRadius(1.0)
    tempTubeFilter.SetNumberOfSides(18)
    tempTubeFilter.CappingOn()
    tempTubeFilter.Update()

    self.setModelSliceIntersectionVisibilityByID(self.needlePathModelNodeID, 1)

    if vtk.VTK_MAJOR_VERSION <= 5:
      pathModelAppend.AddInput(tempTubeFilter.GetOutput())
    else:
      pathModelAppend.AddInputData(tempTubeFilter.GetOutput())

    pathModelAppend.Update()
    self.pathModelNode.SetAndObservePolyData(pathModelAppend.GetOutput())


    #
    # Reslice along with the selected needle
    #

    print "(target) pos: ", pos
    print "pointOnTemplateRAS: ", pointOnTemplateRAS

    R = pointOnTemplateRAS[0]
    A = pointOnTemplateRAS[1]
    S = pointOnTemplateRAS[2]

    deltaR = pos[0] - R
    deltaA = pos[1] - A
    deltaS = pos[2] - S

    pathVector = numpy.array([deltaR, deltaA, deltaS])
    tR = numpy.array([1.0, 0, 0])

    vectorA = numpy.cross(pathVector, tR)
    vectorS = numpy.cross(pathVector, vectorA)


    pathVectorNorm = numpy.linalg.norm(pathVector)
    vectorANorm = numpy.linalg.norm(vectorA)
    vectorSNorm = numpy.linalg.norm(vectorS)

    matrix = vtk.vtkMatrix4x4()
    matrix.Identity()

    ## TODO: if pathVector is parallel to R
    matrix.SetElement(0, 0, pathVector[0]/pathVectorNorm)
    matrix.SetElement(1, 0, pathVector[1]/pathVectorNorm)
    matrix.SetElement(2, 0, pathVector[2]/pathVectorNorm)

    matrix.SetElement(0, 1, vectorA[0]/vectorANorm)
    matrix.SetElement(1, 1, vectorA[1]/vectorANorm)
    matrix.SetElement(2, 1, vectorA[2]/vectorANorm)

    matrix.SetElement(0, 2, vectorS[0]/vectorSNorm)
    matrix.SetElement(1, 2, vectorS[1]/vectorSNorm)
    matrix.SetElement(2, 2, vectorS[2]/vectorSNorm)

    matrix.SetElement(0, 3, R)
    matrix.SetElement(1, 3, A)
    matrix.SetElement(2, 3, S)


    selectNeedleNode = slicer.mrmlScene.GetNodeByID(self.selectNeedleNodeID)
    if selectNeedleNode == None:
      selectNeedleNode = slicer.vtkMRMLLinearTransformNode()
      selectNeedleNode.SetName('SelectedNeedle')
      slicer.mrmlScene.AddNode(selectNeedleNode)
      self.selectNeedleNodeID = selectNeedleNode.GetID()

    selectNeedleNode.SetAndObserveMatrixTransformToParent(matrix)

    modelNodes = slicer.mrmlScene.GetNodesByClass("vtkMRMLModelNode")
    for index in range(modelNodes.GetNumberOfItems()):
      indexNode = modelNodes.GetItemAsObject(index)
      if indexNode.GetTransformNodeID() == selectNeedleNode.GetID():
        indexNode.SetDisplayVisibility(1)
        self.selectNeedleModelNode = indexNode
        print indexNode.GetID()

    red = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeRed")
    yellow = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeYellow")
    green = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeGreen")

##   Changed by yz, Sep/25
##   If 3D Slicer includes the extension "SlicerIGT", uncomment the below code

#    vrdLogic = slicer.modules.volumereslicedriver.logic()
#    redDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), red)
#    redMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_INPLANE, red)
#    yellowDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), yellow)
#    yellowMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_INPLANE90, yellow)
#    greenDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), green)
#    greenMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_TRANSVERSE, green)
#    vrdLogic.Modified()

    return pointOnTemplateRAS
    def runSegmentation(self, elList, volume, parentPath, deetoExe, models,
                        createVTK):
        ### CHECK that both the fiducials and ct volume have been selected
        if (len(elList) == 0):
            # notify error
            slicer.util.showStatusMessage("Error, no electrode list selected")
            return
        if (volume == None):
            # notify error
            slicer.util.showStatusMessage("Error, no volume selected")
            return

        ### COMPUTE THE THRESHOLD the 45% of points not null(0.0)
        im = volume.GetImageData()
        # linearize the 3D image in a vector
        vector = vtk.util.numpy_support.vtk_to_numpy(
            im.GetPointData().GetScalars())
        # eliminate 0.0 value from the vector
        n_vector = vector[vector != 0]
        # sort the intensity values
        n_vector.sort()
        # compute the threshold as the 45% of points not null
        threshold = n_vector[int(n_vector.size * 0.45)]

        ### CREATE A NEW FIDUCIAL LIST CALLED ...... [TODO]
        mlogic = slicer.modules.markups.logic()

        ###
        ### [TODO] Accrocchio, non so come cambiare questi parametri solo
        ### per il nodo corrente, invece che di default
        mlogic.SetDefaultMarkupsDisplayNodeTextScale(1.3)
        mlogic.SetDefaultMarkupsDisplayNodeGlyphScale(1.5)
        mlogic.SetDefaultMarkupsDisplayNodeColor(0.39, 0.78, 0.78)  # AZZURRO
        mlogic.SetDefaultMarkupsDisplayNodeSelectedColor(0.39, 1.0,
                                                         0.39)  # VERDONE

        fidNode = slicer.util.getNode(mlogic.AddNewFiducialNode("recon"))

        # Save the volume as has been modified
        self.tmpVolumeFile = parentPath + "/Tmp/tmp.nii.gz"
        self.saveNode(volume, self.tmpVolumeFile)

        # Set the parameters of the progess bar and show it
        self.pb.setRange(0, len(elList))
        self.pb.show()
        self.pb.setValue(0)
        slicer.app.processEvents()

        # For each electrode "e":
        for i in xrange(len(elList)):
            tFlag = "-l" if (elList[i].tailCheckBox.isChecked()
                             == True) else "-t"
            hFlag = "-h" if (elList[i].headCheckBox.isChecked()
                             == True) else "-e"

            # Construct the cmdLine to run the segmentation on "e"
            cmdLine = [str(deetoExe), '-s', str(threshold), '-ct', str(self.tmpVolumeFile), \
                       hFlag, str(-1 * elList[i].entry[0]), str(-1 * elList[i].entry[1]), \
                       str(elList[i].entry[2]), tFlag, \
                       str(-1 * elList[i].target[0]), str(-1 * elList[i].target[1]), \
                       str(elList[i].target[2]), '-m'] + \
                      map(str, models[elList[i].model.currentText][:-1])
            print cmdLine
            # RUN the command line cmdLine.
            # [NOTE] : I have used Popen since subprocess.check_output wont work at the moment
            # It Looks a problem of returning code from deetoS
            points = subprocess.Popen(
                cmdLine, stdout=subprocess.PIPE).communicate()[0].splitlines()
            # print points

            ### For each of the point returned by deeto we add it to the new markup fiducial
            name = elList[i].name.text
            for p in range(0, (len(points) - 1), 3):
                a = fidNode.AddFiducial(float(points[p]), float(points[p + 1]),
                                        float(points[p + 2]))
                fidNode.SetNthFiducialLabel(a, name + str((p / 3) + 1))

            ### For each electrode we create a line from the start point to the last + 3mm
            ### Look for two points p1 and p3 starting from p1 and p2 (first and last point segmented
            last = len(points) - 1
            p1 = [float(points[0]), float(points[1]), float(points[2])]
            p2 = [
                float(points[last - 2]),
                float(points[last - 1]),
                float(points[last])
            ]
            delta = math.sqrt(
                math.pow((p1[0] - p2[0]), 2) + math.pow((p1[1] - p2[1]), 2) +
                math.pow((p1[2] - p2[2]), 2))
            p3 = [0.0, 0.0, 0.0]
            p3[0] = p2[0] + (p2[0] - p1[0]) / delta * 3  # distance 3mm
            p3[1] = p2[1] + (p2[1] - p1[1]) / delta * 3  # distance 3mm
            p3[2] = p2[2] + (p2[2] - p1[2]) / delta * 3  # distance 3mm
            if createVTK.checked:
                ### Create a vtk line
                lineSource = vtk.vtkLineSource()
                lineSource.SetPoint1(p1)
                lineSource.SetPoint2(p3)
                lineSource.SetResolution(100)  ## why?
                lineSource.Update()
                ### Create a model of the line to add to the scene
                model = slicer.vtkMRMLModelNode()
                model.SetName(name + "_direction")
                model.SetAndObservePolyData(lineSource.GetOutput())
                modelDisplay = slicer.vtkMRMLModelDisplayNode()
                modelDisplay.SetSliceIntersectionVisibility(
                    True)  # Hide in slice view
                modelDisplay.SetVisibility(True)  # Show in 3D view
                modelDisplay.SetColor(1, 0, 0)
                modelDisplay.SetLineWidth(2)
                slicer.mrmlScene.AddNode(modelDisplay)
                model.SetAndObserveDisplayNodeID(modelDisplay.GetID())
                slicer.mrmlScene.AddNode(model)

            # Lock all markup
            mlogic.SetAllMarkupsLocked(fidNode, True)

            # update progress bar
            self.pb.setValue(i + 1)
            slicer.app.processEvents()

        self.pb.hide()
Exemple #13
0
  def updateOutputArray(self,inputVolume,inputRuler,outputArray,lineResolution):
  
    rulerStartPoint_Ruler = [0,0,0]
    rulerEndPoint_Ruler = [0,0,0]
    inputRuler.GetPosition1(rulerStartPoint_Ruler)
    inputRuler.GetPosition2(rulerEndPoint_Ruler)
    rulerStartPoint_Ruler1 = [rulerStartPoint_Ruler[0], rulerStartPoint_Ruler[1], rulerStartPoint_Ruler[2], 1.0]
    rulerEndPoint_Ruler1 = [rulerEndPoint_Ruler[0], rulerEndPoint_Ruler[1], rulerEndPoint_Ruler[2], 1.0]
    
    rulerToRAS = vtk.vtkMatrix4x4()
    rulerTransformNode = inputRuler.GetParentTransformNode()
    if rulerTransformNode:
      if rulerTransformNode.IsTransformToWorldLinear():
        rulerToRAS.DeepCopy(rulerTransformNode.GetMatrixTransformToParent())
      else:
        print ("Cannot handle non-linear transforms - ignoring transform of the input ruler")

    rulerStartPoint_RAS1 = [0,0,0,1]
    rulerEndPoint_RAS1 = [0,0,0,1]
    rulerToRAS.MultiplyPoint(rulerStartPoint_Ruler1,rulerStartPoint_RAS1)
    rulerToRAS.MultiplyPoint(rulerEndPoint_Ruler1,rulerEndPoint_RAS1)        
    
    rulerLengthMm=math.sqrt(vtk.vtkMath.Distance2BetweenPoints(rulerStartPoint_RAS1[0:3],rulerEndPoint_RAS1[0:3]))

    # Need to get the start/end point of the line in the IJK coordinate system
    # as VTK filters cannot take into account direction cosines        
    rasToIJK = vtk.vtkMatrix4x4()
    parentToIJK = vtk.vtkMatrix4x4()
    rasToParent = vtk.vtkMatrix4x4()
    inputVolume.GetRASToIJKMatrix(parentToIJK)
    transformNode = inputVolume.GetParentTransformNode()
    if transformNode:
      if transformNode.IsTransformToWorldLinear():
        rasToParent.DeepCopy(transformNode.GetMatrixTransformToParent())
        rasToParent.Invert()
      else:
        print ("Cannot handle non-linear transforms - ignoring transform of the input volume")
    vtk.vtkMatrix4x4.Multiply4x4(parentToIJK, rasToParent, rasToIJK)
    
    rulerStartPoint_IJK1 = [0,0,0,1]
    rulerEndPoint_IJK1 = [0,0,0,1]
    rasToIJK.MultiplyPoint(rulerStartPoint_RAS1,rulerStartPoint_IJK1)
    rasToIJK.MultiplyPoint(rulerEndPoint_RAS1,rulerEndPoint_IJK1) 
    
    lineSource=vtk.vtkLineSource()
    lineSource.SetPoint1(rulerStartPoint_IJK1[0],rulerStartPoint_IJK1[1],rulerStartPoint_IJK1[2])
    lineSource.SetPoint2(rulerEndPoint_IJK1[0], rulerEndPoint_IJK1[1], rulerEndPoint_IJK1[2])
    lineSource.SetResolution(lineResolution-1)

    probeFilter=vtk.vtkProbeFilter()
    probeFilter.SetInputConnection(lineSource.GetOutputPort())
    if vtk.VTK_MAJOR_VERSION <= 5:
      probeFilter.SetSource(inputVolume.GetImageData())
    else:
      probeFilter.SetSourceData(inputVolume.GetImageData())
    probeFilter.Update()

    probedPoints=probeFilter.GetOutput()

    # Create arrays of data  
    a = outputArray.GetArray()
    a.SetNumberOfTuples(probedPoints.GetNumberOfPoints())
    x = xrange(0, probedPoints.GetNumberOfPoints())
    xStep=rulerLengthMm/(probedPoints.GetNumberOfPoints()-1)
    probedPointScalars=probedPoints.GetPointData().GetScalars()
    for i in range(len(x)):
      a.SetComponent(i, 0, x[i]*xStep)
      a.SetComponent(i, 1, probedPointScalars.GetTuple(i)[0])
      a.SetComponent(i, 2, 0)
      
    probedPoints.GetPointData().GetScalars().Modified()
Exemple #14
0
  def createTemplateModel(self):
    
    self.templatePathVectors = []
    self.templatePathOrigins = []

    self.tempModelNode = slicer.mrmlScene.GetNodeByID(self.templateModelNodeID)
    if self.tempModelNode is None:
      self.tempModelNode = slicer.vtkMRMLModelNode()
      self.tempModelNode.SetName('NeedleGuideTemplate')
      slicer.mrmlScene.AddNode(self.tempModelNode)
      self.templateModelNodeID = self.tempModelNode.GetID()

      dnode = slicer.vtkMRMLModelDisplayNode()
      #dnode.SetColor(self.ModelColor)
      slicer.mrmlScene.AddNode(dnode)
      self.tempModelNode.SetAndObserveDisplayNodeID(dnode.GetID())
      self.modelNodetag = self.tempModelNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent,
                                                         self.onTemplateTransformUpdated)
      
    self.pathModelNode = slicer.mrmlScene.GetNodeByID(self.needlePathModelNodeID)
    if self.pathModelNode is None:
      self.pathModelNode = slicer.vtkMRMLModelNode()
      self.pathModelNode.SetName('NeedleGuideNeedlePath')
      slicer.mrmlScene.AddNode(self.pathModelNode)
      self.needlePathModelNodeID = self.pathModelNode.GetID()

      dnode = slicer.vtkMRMLModelDisplayNode()
      slicer.mrmlScene.AddNode(dnode)
      self.pathModelNode.SetAndObserveDisplayNodeID(dnode.GetID())
      
    pathModelAppend = vtk.vtkAppendPolyData()
    tempModelAppend = vtk.vtkAppendPolyData()
    
    for row in self.templateConfig:

      p1 = numpy.array(row[0:3])
      p2 = numpy.array(row[3:6])
      tempLineSource = vtk.vtkLineSource()
      tempLineSource.SetPoint1(p1)
      tempLineSource.SetPoint2(p2)
 
      tempTubeFilter = vtk.vtkTubeFilter()
      tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort())
      tempTubeFilter.SetRadius(1.0)
      tempTubeFilter.SetNumberOfSides(18)
      tempTubeFilter.CappingOn()
      tempTubeFilter.Update()

      pathLineSource = vtk.vtkLineSource()
      v = p2-p1
      nl = numpy.linalg.norm(v)
      n = v/nl  # normal vector
      l = row[6]
      p3 = p1 + l * n
      pathLineSource.SetPoint1(p1)
      pathLineSource.SetPoint2(p3)

      self.templatePathOrigins.append([row[0], row[1], row[2], 1.0])
      self.templatePathVectors.append([n[0], n[1], n[2], 1.0])
      self.templateMaxDepth.append(row[6])
 
      pathTubeFilter = vtk.vtkTubeFilter()
      pathTubeFilter.SetInputConnection(pathLineSource.GetOutputPort())
      pathTubeFilter.SetRadius(0.8)
      pathTubeFilter.SetNumberOfSides(18)
      pathTubeFilter.CappingOn()
      pathTubeFilter.Update()

      if vtk.VTK_MAJOR_VERSION <= 5:
        tempModelAppend.AddInput(tempTubeFilter.GetOutput())
        pathModelAppend.AddInput(pathTubeFilter.GetOutput())
      else:
        tempModelAppend.AddInputData(tempTubeFilter.GetOutput())
        pathModelAppend.AddInputData(pathTubeFilter.GetOutput())

      tempModelAppend.Update()
      self.tempModelNode.SetAndObservePolyData(tempModelAppend.GetOutput())
      pathModelAppend.Update()
      self.pathModelNode.SetAndObservePolyData(pathModelAppend.GetOutput())
  def runSegmentation(self,elList,volume,parentPath,deetoExe,models):
    ### CHECK that both the fiducials and ct volume have been selected
    if (len(elList) == 0):
      # notify error
      slicer.util.showStatusMessage("Error, no electrode list selected")
      return
    if ( volume == None):
      # notify error
      slicer.util.showStatusMessage("Error, no volume selected")
      return

    ### COMPUTE THE THRESHOLD the 45% of points not null(0.0)  
    im = volume.GetImageData()
    # linearize the 3D image in a vector
    vector = vtk.util.numpy_support.vtk_to_numpy(im.GetPointData().GetScalars())
    # eliminate 0.0 value from the vector
    n_vector = vector[vector != 0]
    # sort the intensity values
    n_vector.sort()
    # compute the threshold as the 45% of points not null
    threshold = n_vector[int(n_vector.size * 0.45)]
    
    ### CREATE A NEW FIDUCIAL LIST CALLED ...... [TODO]
    mlogic = slicer.modules.markups.logic()   
   
    ### 
    ### [TODO] Accrocchio, non so come cambiare questi parametri solo
    ### per il nodo corrente, invece che di default
    mlogic.SetDefaultMarkupsDisplayNodeTextScale(1.3)
    mlogic.SetDefaultMarkupsDisplayNodeGlyphScale(1.5)
    mlogic.SetDefaultMarkupsDisplayNodeColor(0.39,0.78,0.78)  # AZZURRO CACCA
    mlogic.SetDefaultMarkupsDisplayNodeSelectedColor(0.39,1.0,0.39)  # VERDONE CACCA
    
    fidNode = slicer.util.getNode(mlogic.AddNewFiducialNode("recon"))

    # Save the volume as has been modified
    self.tmpVolumeFile = parentPath + "/Tmp/tmp.nii.gz"
    self.saveNode(volume,self.tmpVolumeFile)

    # Set the parameters of the progess bar and show it 
    self.pb.setRange(0,len(elList))
    self.pb.show()
    self.pb.setValue(0)
    slicer.app.processEvents()

    # For each electrode "e":
    for i in xrange(len(elList)):
      tFlag = "-l" if (elList[i].tailCheckBox.isChecked() == True) else "-t"
      hFlag = "-h" if (elList[i].headCheckBox.isChecked() == True) else "-e"
      
      # Construct the cmdLine to run the segmentation on "e"
      cmdLine = [str(deetoExe),'-s',str(threshold),'-ct',str(self.tmpVolumeFile),\
                 hFlag, str(-1*elList[i].entry[0]), str(-1*elList[i].entry[1]), \
                 str(elList[i].entry[2]), tFlag ,\
                 str(-1*elList[i].target[0]),str(-1*elList[i].target[1]),\
                 str(elList[i].target[2]),'-m'] +\
        map(str,models[elList[i].model.currentText])
      print cmdLine
      # RUN the command line cmdLine. 
      # [NOTE] : I have used Popen since subprocess.check_output wont work at the moment
      # It Looks a problem of returning code from deetoS
      points = subprocess.Popen(cmdLine,stdout=subprocess.PIPE).communicate()[0].splitlines()
      # print points

      ### For each of the point returned by deeto we add it to the new markup fiducial
      name = elList[i].name.text
      for p in range(0,(len(points) - 1),3):
        a = fidNode.AddFiducial(float(points[p]),float(points[p+1]),float(points[p+2]))
        fidNode.SetNthFiducialLabel(a, name + str((p/3) + 1))

      ### For each electrode we create a line from the start point to the last + 3mm
      ### Look for two points p1 and p3 starting from p1 and p2 (first and last point segmented
      last = len(points) - 1
      p1 = [float(points[0]), float(points[1]), float(points[2])]
      p2 = [float(points[last - 2]), float(points[last-1]), float(points[last])]
      delta = math.sqrt(math.pow((p1[0] - p2[0]),2) + math.pow((p1[1] - p2[1]),2) + math.pow((p1[2] - p2[2]),2)) 
      p3 = [0.0,0.0,0.0]
      p3[0] = p2[0] + (p2[0] - p1[0]) / delta * 3 # distance 3mm
      p3[1] = p2[1] + (p2[1] - p1[1]) / delta * 3 # distance 3mm
      p3[2] = p2[2] + (p2[2] - p1[2]) / delta * 3 # distance 3mm
      ### Create a vtk line
      lineSource = vtk.vtkLineSource()
      lineSource.SetPoint1(p1)
      lineSource.SetPoint2(p3)
      lineSource.SetResolution(100) ## why?
      lineSource.Update()
      ### Create a model of the line to add to the scene
      model = slicer.vtkMRMLModelNode()
      model.SetName(name + "_direction")
      model.SetAndObservePolyData(lineSource.GetOutput())
      modelDisplay = slicer.vtkMRMLModelDisplayNode()
      modelDisplay.SetSliceIntersectionVisibility(True) # Hide in slice view
      modelDisplay.SetVisibility(True) # Show in 3D view
      modelDisplay.SetColor(1,0,0)
      modelDisplay.SetLineWidth(2)
      slicer.mrmlScene.AddNode(modelDisplay)
      model.SetAndObserveDisplayNodeID(modelDisplay.GetID())
      slicer.mrmlScene.AddNode(model)
      
      # update progress bar
      self.pb.setValue(i+1)
      slicer.app.processEvents()

    self.pb.hide()