Esempio n. 1
0
def computeFemoralLandMarkMatrix(txtPath: str):
    '''
    计算将solidWorks中的假体平移和旋转到原点附近
    '''

    pSourcePoints = vtk.vtkPoints()
    pSourcePoints.InsertPoint(0, -73.292, 1.468, -186.725)
    pSourcePoints.InsertPoint(1, -73.6702, 0.964468, -171.738)
    pSourcePoints.InsertPoint(2, -73.292, 1.468, -156.725)
    # pSourcePoints.InsertPoint(3, 57.6515, 29.5704 ,  -171.2451)
    # pSourcePoints.InsertPoint(4, 115.8690, 3.24210 ,  -160.804)

    pTargetPoints = vtk.vtkPoints()
    pTargetPoints.InsertPoint(0, -73.292, 1.468, -186.725)
    pTargetPoints.InsertPoint(1, -73.292, 1.468, -171.725)
    pTargetPoints.InsertPoint(2, -73.292, 1.468, -156.725)  # -y 横向的   后端切平面的法线
    # pTargetPoints.InsertPoint(3, -48.651500,  21.57049,  -208.7548)
    # pTargetPoints.InsertPoint(4, -106.8690,  -4.7579,  -219.1959)   # -z 轴向的   远端切平面的法线

    landmarkTransform = vtk.vtkLandmarkTransform()
    landmarkTransform.SetSourceLandmarks(pSourcePoints)
    landmarkTransform.SetTargetLandmarks(pTargetPoints)
    landmarkTransform.SetModeToRigidBody()
    landmarkTransform.Update()

    matrix = landmarkTransform.GetMatrix()

    nparray = arrayFromVTKMatrix(matrix)
    for i in range(4):
        for j in range(4):
            print("{:10.2f}".format(matrix.GetElement(i, j)), end=", ")
        print("")

    np.set_printoptions(precision=3)
    np.savetxt(txtPath, nparray, fmt='%1.3f')
Esempio n. 2
0
    def __init__(self, module_manager):
        ModuleBase.__init__(self, module_manager)

        self._input_points = [None, None]

        self._source_landmarks = None
        self._target_landmarks = None

        self._config.mode = 'Rigid'

        configList = [('Transformation mode:', 'mode', 'base:str', 'choice',
                       'Rigid: rotation + translation;\n'
                       'Similarity: rigid + isotropic scaling\n'
                       'Affine: rigid + scaling + shear',
                       ('Rigid', 'Similarity', 'Affine'))]

        self._landmark_transform = vtk.vtkLandmarkTransform()

        ScriptedConfigModuleMixin.__init__(
            self, configList, {
                'Module (self)': self,
                'vtkLandmarkTransform': self._landmark_transform
            })

        self.sync_module_logic_with_config()
Esempio n. 3
0
def getRigidTransform(fix, mov): # In real resolution
    LandmarkTransform = vtk.vtkLandmarkTransform()
    LandmarkTransform.SetModeToRigidBody()
    
    n = fix.shape[0]
    fix_point = vtk.vtkPoints()
    fix_point.SetNumberOfPoints(n)
    mov_point = vtk.vtkPoints()
    mov_point.SetNumberOfPoints(n)

    for i in range(n):
        fix_point.SetPoint(i, fix[i, 0], fix[i, 1], fix[i, 2])
        mov_point.SetPoint(i, mov[i, 0], mov[i, 1], mov[i, 2])

    LandmarkTransform.SetSourceLandmarks(mov_point)
    LandmarkTransform.SetTargetLandmarks(fix_point)
    LandmarkTransform.Update()

    matrix = LandmarkTransform.GetMatrix()
    T = ml.zeros([4, 4], dtype = npy.float32)
    for i in range(4):
        for j in range(4):
            T[i, j] = matrix.GetElement(j, i)

    p1 = mov[0, :].tolist()
    p2 = [0.0, 0, 0]
    LandmarkTransform.InternalTransformPoint(p1, p2)
    
    return T, npy.array(p2)
Esempio n. 4
0
def computeTibiaTrayLandMarkMatrix(txtPath: str):
    '''
    计算将solidWorks中的假体平移和旋转到原点附近
    '''
    pSourcePoints = vtk.vtkPoints()
    pSourcePoints.InsertPoint(0, 0, 0, 0)
    pSourcePoints.InsertPoint(1, 0.5, 0, 0)
    pSourcePoints.InsertPoint(2, 1.0, 0, 0)
    pSourcePoints.InsertPoint(3, 0, 0.5, 0)
    pSourcePoints.InsertPoint(4, 0, 1.0, 0)

    pTargetPoints = vtk.vtkPoints()
    pTargetPoints.InsertPoint(0, 0, 0, 0)
    pTargetPoints.InsertPoint(1, -0.5, 0, 0)
    pTargetPoints.InsertPoint(2, -1.0, 0, 0)
    pTargetPoints.InsertPoint(3, 0, 0.5, 0)
    pTargetPoints.InsertPoint(4, 0, 1.0, 0)

    landmarkTransform = vtk.vtkLandmarkTransform()
    landmarkTransform.SetSourceLandmarks(pSourcePoints)
    landmarkTransform.SetTargetLandmarks(pTargetPoints)
    landmarkTransform.SetModeToRigidBody()
    landmarkTransform.Update()

    matrix = landmarkTransform.GetMatrix()

    nparray = arrayFromVTKMatrix(matrix)
    for i in range(4):
        for j in range(4):
            print("{:10.2f}".format(matrix.GetElement(i, j)), end=", ")
        print("")

    np.set_printoptions(precision=3)
    np.savetxt(txtPath, nparray, fmt='%1.3f')
Esempio n. 5
0
def getRigidTransform(fix, mov):  # In real resolution
    LandmarkTransform = vtk.vtkLandmarkTransform()
    LandmarkTransform.SetModeToRigidBody()

    n = fix.shape[0]
    fix_point = vtk.vtkPoints()
    fix_point.SetNumberOfPoints(n)
    mov_point = vtk.vtkPoints()
    mov_point.SetNumberOfPoints(n)

    for i in range(n):
        fix_point.SetPoint(i, fix[i, 0], fix[i, 1], fix[i, 2])
        mov_point.SetPoint(i, mov[i, 0], mov[i, 1], mov[i, 2])

    LandmarkTransform.SetSourceLandmarks(mov_point)
    LandmarkTransform.SetTargetLandmarks(fix_point)
    LandmarkTransform.Update()

    matrix = LandmarkTransform.GetMatrix()
    T = ml.zeros([4, 4], dtype=npy.float32)
    for i in range(4):
        for j in range(4):
            T[i, j] = matrix.GetElement(j, i)

    p1 = mov[0, :].tolist()
    p2 = [0.0, 0, 0]
    LandmarkTransform.InternalTransformPoint(p1, p2)

    return T, npy.array(p2)
Esempio n. 6
0
  def onLandmarkMoved_NOT(self,state):
    """Perform the linear transform using the vtkLandmarkTransform class"""
    if state.transformed.GetTransformNodeID() != state.linearTransform.GetID():
      state.transformed.SetAndObserveTransformNodeID(state.linearTransform.GetID())

    self.linearMode = "Rigid"

    # try to use user selection, but fall back if not enough points are available
    landmarkTransform = vtk.vtkLandmarkTransform()
    if self.linearMode == 'Rigid':
      landmarkTransform.SetModeToRigidBody()
    if self.linearMode == 'Similarity':
      landmarkTransform.SetModeToSimilarity()
    if self.linearMode == 'Affine':
      landmarkTransform.SetModeToAffine()
    if state.fixedFiducials.GetNumberOfFiducials() < 3:
      landmarkTransform.SetModeToRigidBody()

    points = {}
    point = [0,]*3
    for volumeNode in (state.fixed,state.moving):
      points[volumeNode] = vtk.vtkPoints()
    indices = range(state.fixedFiducials.GetNumberOfFiducials())
    fiducialLists = (state.fixedFiducials,state.movingFiducials)
    volumeNodes = (state.fixed,state.moving)
    for fiducials,volumeNode in zip(fiducialLists,volumeNodes):
      for index in indices:
        fiducials.GetNthFiducialPosition(index,point)
        points[volumeNode].InsertNextPoint(point)
    landmarkTransform.SetSourceLandmarks(points[state.moving])
    landmarkTransform.SetTargetLandmarks(points[state.fixed])
    landmarkTransform.Update()
    t = state.linearTransform
    t.SetAndObserveMatrixTransformToParent(landmarkTransform.GetMatrix())
Esempio n. 7
0
  def onLandmarkMoved(self,state):
    """Perform the linear transform using the vtkLandmarkTransform class"""
    if state.transformed:
      if state.transformed.GetTransformNodeID() != state.transform.GetID():
        state.transformed.SetAndObserveTransformNodeID(state.transform.GetID())

    if not state.fixedFiducials or not state.movingFiducials:
      return

    # try to use user selection, but fall back if not enough points are available
    landmarkTransform = vtk.vtkLandmarkTransform()
    if self.linearMode == 'Rigid':
      landmarkTransform.SetModeToRigidBody()
    if self.linearMode == 'Similarity':
      landmarkTransform.SetModeToSimilarity()
    if self.linearMode == 'Affine':
      landmarkTransform.SetModeToAffine()
    if state.fixedFiducials.GetNumberOfFiducials() < 3:
      landmarkTransform.SetModeToRigidBody()

    volumeNodes = (state.fixed, state.moving)
    fiducialNodes = (state.fixedFiducials,state.movingFiducials)
    points = state.logic.vtkPointsForVolumes( volumeNodes, fiducialNodes )
    landmarkTransform.SetSourceLandmarks(points[state.moving])
    landmarkTransform.SetTargetLandmarks(points[state.fixed])
    landmarkTransform.Update()
    state.transform.SetAndObserveTransformToParent(landmarkTransform)
Esempio n. 8
0
    def onLandmarkMoved(self, state):
        """Perform the linear transform using the vtkLandmarkTransform class"""
        if state.transformed:
            if state.transformed.GetTransformNodeID() != state.transform.GetID(
            ):
                state.transformed.SetAndObserveTransformNodeID(
                    state.transform.GetID())

        if not state.fixedFiducials or not state.movingFiducials:
            return

        # try to use user selection, but fall back if not enough points are available
        landmarkTransform = vtk.vtkLandmarkTransform()
        if self.linearMode == 'Rigid':
            landmarkTransform.SetModeToRigidBody()
        if self.linearMode == 'Similarity':
            landmarkTransform.SetModeToSimilarity()
        if self.linearMode == 'Affine':
            landmarkTransform.SetModeToAffine()
        if state.fixedFiducials.GetNumberOfFiducials() < 3:
            landmarkTransform.SetModeToRigidBody()

        volumeNodes = (state.fixed, state.moving)
        fiducialNodes = (state.fixedFiducials, state.movingFiducials)
        points = state.logic.vtkPointsForVolumes(volumeNodes, fiducialNodes)
        landmarkTransform.SetSourceLandmarks(points[state.moving])
        landmarkTransform.SetTargetLandmarks(points[state.fixed])
        landmarkTransform.Update()
        state.transform.SetAndObserveTransformToParent(landmarkTransform)
Esempio n. 9
0
  def performLandmarkRegistion(self, fromFiducialsNode, toFiducialsNode, outputTransformNode):
    fromPoints = vtk.vtkPoints()
    toPoints = vtk.vtkPoints()

    nFrom = fromFiducialsNode.GetNumberOfFiducials()
    nTo = toFiducialsNode.GetNumberOfFiducials()

    if nFrom != nTo:
      logging.error('Number of fiducials in lists are not equal.')
      return

    for i in range(nFrom):
      p = [0, 0, 0]
      fromFiducialsNode.GetNthFiducialPosition(i, p)
      fromPoints.InsertNextPoint( p )
      toFiducialsNode.GetNthFiducialPosition(i, p)
      toPoints.InsertNextPoint( p )

    lt = vtk.vtkLandmarkTransform()
    lt.SetSourceLandmarks(fromPoints)
    lt.SetTargetLandmarks(toPoints)
    lt.SetModeToRigidBody()
    lt.Update()
    m = vtk.vtkMatrix4x4()
    lt.GetMatrix(m)

    #Check for stability of registration
    det = m.Determinant()
    if det < 1e-8:
      logging.error('Unstable registration. Check input for collinear points.')
      return

    outputTransformNode.SetMatrixTransformToParent(m)
Esempio n. 10
0
  def onLandmarkMoved_NOT(self,state):
    """Perform the linear transform using the vtkLandmarkTransform class"""
    if state.transformed.GetTransformNodeID() != state.linearTransform.GetID():
      state.transformed.SetAndObserveTransformNodeID(state.linearTransform.GetID())

    self.linearMode = "Rigid"

    # try to use user selection, but fall back if not enough points are available
    landmarkTransform = vtk.vtkLandmarkTransform()
    if self.linearMode == 'Rigid':
      landmarkTransform.SetModeToRigidBody()
    if self.linearMode == 'Similarity':
      landmarkTransform.SetModeToSimilarity()
    if self.linearMode == 'Affine':
      landmarkTransform.SetModeToAffine()
    if state.fixedFiducials.GetNumberOfFiducials() < 3:
      landmarkTransform.SetModeToRigidBody()

    points = {}
    point = [0,]*3
    for volumeNode in (state.fixed,state.moving):
      points[volumeNode] = vtk.vtkPoints()
    indices = range(state.fixedFiducials.GetNumberOfFiducials())
    fiducialLists = (state.fixedFiducials,state.movingFiducials)
    volumeNodes = (state.fixed,state.moving)
    for fiducials,volumeNode in zip(fiducialLists,volumeNodes):
      for index in indices:
        fiducials.GetNthFiducialPosition(index,point)
        points[volumeNode].InsertNextPoint(point)
    landmarkTransform.SetSourceLandmarks(points[state.moving])
    landmarkTransform.SetTargetLandmarks(points[state.fixed])
    landmarkTransform.Update()
    t = state.linearTransform
    t.SetAndObserveMatrixTransformToParent(landmarkTransform.GetMatrix())
Esempio n. 11
0
def LandmarkSimilitudRegistration(fix, mov):
    """ landmarks registration from two vtkPoints """
    transform = vtk.vtkLandmarkTransform()
    transform.SetSourceLandmarks(mov)
    transform.SetTargetLandmarks(fix)
    transform.SetModeToSimilarity()
    transform.Update()
    return transform
 def onCalculateButtonClicked(self):
     self.landmarkTransform = vtk.vtkLandmarkTransform()
     self.landmarkTransform.SetSourceLandmarks(self.collectedPoints)
     self.landmarkTransform.SetTargetLandmarks(self.points)
     self.landmarkTransform.SetModeToRigidBody()
     self.landmarkTransform.Update()
     self.outputMatrix = vtk.vtkMatrix4x4()
     self.landmarkTransform.GetMatrix(self.outputMatrix)
     self.transformTable.setItem(
         0, 0, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(0, 0))))
     self.transformTable.setItem(
         0, 1, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(0, 1))))
     self.transformTable.setItem(
         0, 2, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(0, 2))))
     self.transformTable.setItem(
         0, 3, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(0, 3))))
     self.transformTable.setItem(
         1, 0, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(1, 0))))
     self.transformTable.setItem(
         1, 1, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(1, 1))))
     self.transformTable.setItem(
         1, 2, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(1, 2))))
     self.transformTable.setItem(
         1, 3, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(1, 3))))
     self.transformTable.setItem(
         2, 0, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(2, 0))))
     self.transformTable.setItem(
         2, 1, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(2, 1))))
     self.transformTable.setItem(
         2, 2, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(2, 2))))
     self.transformTable.setItem(
         2, 3, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(2, 3))))
     self.transformTable.setItem(
         3, 0, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(3, 0))))
     self.transformTable.setItem(
         3, 1, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(3, 1))))
     self.transformTable.setItem(
         3, 2, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(3, 2))))
     self.transformTable.setItem(
         3, 3, qt.QTableWidgetItem(str(self.outputMatrix.GetElement(3, 3))))
     self.transformTable.resizeColumnToContents(0)
     self.transformTable.resizeColumnToContents(1)
     self.transformTable.resizeColumnToContents(2)
     self.transformTable.resizeColumnToContents(3)
     self.calNode = slicer.mrmlScene.AddNewNodeByClass(
         'vtkMRMLLinearTransformNode', 'JigSensorToJig')
     self.calNode.SetMatrixTransformToParent(self.outputMatrix)
     self.collectionNode.SetAndObserveTransformNodeID(self.calNode.GetID())
     self.array = np.ones(4)
     self.transformedArray = np.array(
         [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
         np.float64())
     for i in range(0, 6):
         self.collectionNode.GetMarkupPointWorld(i, 0, self.array)
         self.transformedArray[i] = self.array[0:3]
     self.error = np.linalg.norm(self.jigArray - self.transformedArray)
     self.errorString.text = "RMSE: " + str(self.error)
    def MRIXRayRegistration(self, mriLMReader, wrlLMReader, mriReader):

        Transrigid = vtk.vtkLandmarkTransform()
        Transrigid.SetSourceLandmarks(mriLMReader.points)
        Transrigid.SetTargetLandmarks(wrlLMReader.vertebrae_points)
        Transrigid.SetModeToRigidBody()
        Transrigid.Update()
        mriReader.actor.SetUserTransform(Transrigid)
        mriLMReader.actor.SetUserTransform(Transrigid)
        print("-----Performance Metrics of MRI to X-Ray using Rigid Registration-----")
        self.getMetrics(mriLMReader, wrlLMReader, Transrigid)
Esempio n. 14
0
def landmark_registration(src, tgt):
    '''
    src: moving points
    tgt: fix points
    '''
    reg = vtk.vtkLandmarkTransform()
    reg.SetSourceLandmarks(src.GetPoints())
    reg.SetTargetLandmarks(tgt.GetPoints())
    reg.SetModeToRigidBody()
    reg.Update()

    return reg.GetMatrix()
def vtk_ellipsoid_topomesh(ellipsoid_radius=50.0, ellipsoid_scales=[1,1,1], ellipsoid_axes=np.diag(np.ones(3)), ellipsoid_center=np.zeros(3)):
    """
    """      
    import vtk
    from openalea.cellcomplex.property_topomesh.utils.image_tools import vtk_polydata_to_triangular_mesh

    ico = vtk.vtkPlatonicSolidSource()
    ico.SetSolidTypeToIcosahedron()
    ico.Update()

    subdivide = vtk.vtkLoopSubdivisionFilter()
    subdivide.SetNumberOfSubdivisions(3)
    subdivide.SetInputConnection(ico.GetOutputPort())
    subdivide.Update()

    scale_transform = vtk.vtkTransform()
    scale_factor = ellipsoid_radius/(np.sqrt(2)/2.)
    scale_transform.Scale(scale_factor,scale_factor,scale_factor)

    ellipsoid_sphere = vtk.vtkTransformPolyDataFilter()
    ellipsoid_sphere.SetInput(subdivide.GetOutput())
    ellipsoid_sphere.SetTransform(scale_transform)
    ellipsoid_sphere.Update()

    ellipsoid_transform = vtk.vtkTransform()
    axes_transform = vtk.vtkLandmarkTransform()
    source_points = vtk.vtkPoints()
    source_points.InsertNextPoint([1,0,0])
    source_points.InsertNextPoint([0,1,0])
    source_points.InsertNextPoint([0,0,1])
    target_points = vtk.vtkPoints()
    target_points.InsertNextPoint(ellipsoid_axes[0])
    target_points.InsertNextPoint(ellipsoid_axes[1])
    target_points.InsertNextPoint(ellipsoid_axes[2])
    axes_transform.SetSourceLandmarks(source_points)
    axes_transform.SetTargetLandmarks(target_points)
    axes_transform.SetModeToRigidBody()
    axes_transform.Update()
    ellipsoid_transform.SetMatrix(axes_transform.GetMatrix())
    ellipsoid_transform.Scale(ellipsoid_scales[0],ellipsoid_scales[1],ellipsoid_scales[2])
    center_transform = vtk.vtkTransform()
    center_transform.Translate(ellipsoid_center[0],ellipsoid_center[1],ellipsoid_center[2])
    center_transform.Concatenate(ellipsoid_transform)
    ellipsoid_ellipsoid = vtk.vtkTransformPolyDataFilter()
    ellipsoid_ellipsoid.SetInput(ellipsoid_sphere.GetOutput())
    ellipsoid_ellipsoid.SetTransform(center_transform)
    ellipsoid_ellipsoid.Update()

    ellipsoid_mesh = vtk_polydata_to_triangular_mesh(ellipsoid_ellipsoid.GetOutput())

    topomesh = triangle_topomesh(ellipsoid_mesh.triangles.values(),ellipsoid_mesh.points)

    return topomesh
Esempio n. 16
0
def ICPSimilitudRegistration(fix, mov, fix_ldm=None, mov_ldm=None, do_rigid=False):
    """
    IterativeClosestPoint registration between two vtkPolyData
    return the vtkTransform

    can be initialized using landmarks
    (then return a composed vtkTransform instead of a vtkIterativeClosestPointTransform)
    """
    transform = vtk.vtkIterativeClosestPointTransform()
    if do_rigid:
        transform.GetLandmarkTransform().SetModeToRigidBody()
    else:
        transform.GetLandmarkTransform().SetModeToSimilarity()
    transform.SetTarget(fix)

    #transform.SetMaximumNumberOfIterations(10)
    #transform.SetMaximumNumberOfLandmarks(100)

    # initialize using landmarks
    if fix_ldm is not None and mov_ldm is not None:
        ldm_transform = vtk.vtkLandmarkTransform()
        ldm_transform.SetSourceLandmarks(mov_ldm)
        ldm_transform.SetTargetLandmarks(fix_ldm)

        if do_rigid:
            ldm_transform.SetModeToRigidBody()
        else:
            ldm_transform.SetModeToSimilarity()
        ldm_transform.Update()

        warper = vtk.vtkTransformPolyDataFilter()
        warper.SetTransform(ldm_transform)
        warper.SetInputData(mov)
        warper.Update()

        # ICP registration
        transform.SetSource(warper.GetOutput())
        transform.Update()

        composed = vtk.vtkTransform()
        composed.SetInput(transform)
        composed.PreMultiply()
        composed.Concatenate(ldm_transform)
        return composed

    else:
        transform.SetStartByMatchingCentroids(True)

        # ICP registration
        transform.SetSource(mov)
        transform.Update()
        return transform
Esempio n. 17
0
 def constraint(self, x_current):
     # Make sure the optimizer is searching in a reasonable region.
     # aim to preserve volume using the determinant of the overall affine transform
     affine_part = vtk.vtkLandmarkTransform()
     source_landmarks = convert_numpy_array_to_vtk_points(x_current)
     target_landmarks = convert_numpy_array_to_vtk_points(self.target_landmarks)
     affine_part.SetSourceLandmarks(source_landmarks)
     affine_part.SetTargetLandmarks(target_landmarks)
     affine_part.SetModeToAffine()
     affine_part.Update()
     det = affine_part.GetMatrix().Determinant()
     penalty = -100 * (1 - det)
     return penalty
Esempio n. 18
0
def BestBoundingBox(axis, target, source, targetLandmarks, sourceLandmarks,
                    bestDistance, bestPoints):
    distance = vtk.vtkHausdorffDistancePointSetFilter()
    testTransform = vtk.vtkTransform()
    testTransformPD = vtk.vtkTransformPolyDataFilter()
    lmTransform = vtk.vtkLandmarkTransform()
    lmTransformPD = vtk.vtkTransformPolyDataFilter()

    lmTransform.SetModeToSimilarity()
    lmTransform.SetTargetLandmarks(targetLandmarks.GetPoints())

    sourceCenter = sourceLandmarks.GetCenter()

    delta = 90.0
    for i in range(0, 4):
        angle = delta * i
        # Rotate about center
        testTransform.Identity()
        testTransform.Translate(sourceCenter[0], sourceCenter[1],
                                sourceCenter[2])
        if axis == "X":
            testTransform.RotateX(angle)
        elif axis == "Y":
            testTransform.RotateY(angle)
        else:
            testTransform.RotateZ(angle)
        testTransform.Translate(-sourceCenter[0], -sourceCenter[1],
                                -sourceCenter[2])

        testTransformPD.SetTransform(testTransform)
        testTransformPD.SetInputData(sourceLandmarks)
        testTransformPD.Update()

        lmTransform.SetSourceLandmarks(testTransformPD.GetOutput().GetPoints())
        lmTransform.Modified()

        lmTransformPD.SetInputData(source)
        lmTransformPD.SetTransform(lmTransform)
        lmTransformPD.Update()

        distance.SetInputData(0, target)
        distance.SetInputData(1, lmTransformPD.GetOutput())
        distance.Update()

        testDistance = distance.GetOutput(0).GetFieldData().GetArray(
            "HausdorffDistance").GetComponent(0, 0)
        if testDistance < bestDistance:
            bestDistance = testDistance
            bestPoints.DeepCopy(testTransformPD.GetOutput().GetPoints())

    return bestDistance
Esempio n. 19
0
  def computeRegistration(referenceToRas, alphaPoints, betaPoints):
    landmarkTransform = vtk.vtkLandmarkTransform()
    landmarkTransform.SetSourceLandmarks(alphaPoints)
    landmarkTransform.SetTargetLandmarks(betaPoints)
    landmarkTransform.SetModeToRigidBody()
    landmarkTransform.Update()

    alphaToBetaMatrix = vtk.vtkMatrix4x4()
    landmarkTransform.GetMatrix(alphaToBetaMatrix)

    det = alphaToBetaMatrix.Determinant()
    if det < 1e-8:
      print 'Unstable registration. Check input for collinear points.'

    referenceToRas.SetMatrixTransformToParent(alphaToBetaMatrix)
    return alphaToBetaMatrix
Esempio n. 20
0
def transform_lmk(sourcepoints,targetpoints,surface,similarityon=False):
    lmktransform = vtk.vtkLandmarkTransform()
    lmktransform.SetSourceLandmarks(sourcepoints)

    lmktransform.SetTargetLandmarks(targetpoints)
    if similarityon:
        lmktransform.SetModeToSimilarity()
    else:
        lmktransform.SetModeToAffine()

    lmktransform.Update()

    transformfilter = vtk.vtkTransformPolyDataFilter()
    transformfilter.SetInputData(surface)
    transformfilter.SetTransform(lmktransform)
    transformfilter.Update()

    return transformfilter.GetOutput()
    def SurfaceXRayRegistration(self, szeLMReader, wrlLMReader, szeReader):

        # Rotate surface becsause it is not aligned with landmarks
        self.AlignSurfaceLM(szeReader)

        # find the rigid registration using correspondences
        Transrigid = vtk.vtkLandmarkTransform()
        Transrigid.SetSourceLandmarks(szeLMReader.points)
        Transrigid.SetTargetLandmarks(wrlLMReader.capteurs_points)
        Transrigid.SetModeToRigidBody()
        Transrigid.Update()
        # Apply transformation to landmarks
        self.ApplyTransform(szeLMReader.actor, Transrigid)
        print("-----Performance Metrics of Surface Topography to X-Ray using Rigid Registration-----")
        self.getMetrics(szeLMReader, wrlLMReader, Transrigid)
        # Apply transformation to surface
        self.ApplyTransform(szeReader.actorCopy, Transrigid)
        self.ApplyTransform(szeReader.actor, Transrigid)
    def _updateTransform(self):
        """
		Update the landmark transform
		"""
        if PointsSetsIsEmpty(self.landmarkPointSets):
            return

        numberOfSets = NumberOfSets(self.landmarkPointSets)
        fixedPoints = vtkPoints()
        movingPoints = vtkPoints()
        fixedPoints.SetNumberOfPoints(numberOfSets)
        movingPoints.SetNumberOfPoints(numberOfSets)

        pointsetIndex = 0
        for index in range(len(self.landmarkPointSets)):
            pointset = self.landmarkPointSets[index]
            if pointset[0] and pointset[1]:
                fixedPoint = pointset[0]
                movingPoint = pointset[1]
                # Transform the point from the moving landmark with the original transform
                transPoint = self.originalTransform.TransformPoint(movingPoint)
                fixedPoints.SetPoint(pointsetIndex, fixedPoint)
                movingPoints.SetPoint(pointsetIndex, transPoint)
                pointsetIndex += 1

        landmarkTransform = vtkLandmarkTransform()
        if self.landmarkTransformType == 0:
            landmarkTransform.SetModeToRigidBody()
        elif self.landmarkTransformType == 1:
            landmarkTransform.SetModeToSimilarity()
        elif self.landmarkTransformType == 2:
            landmarkTransform.SetModeToAffine()
        landmarkTransform.SetSourceLandmarks(fixedPoints)
        landmarkTransform.SetTargetLandmarks(movingPoints)
        landmarkTransform.Update()

        transform = TransformWithMatrix(landmarkTransform.GetMatrix())
        transform.Inverse()

        transformation = self.multiWidget.transformations[-1]
        assert transformation.transformType == Transformation.TypeLandmark
        transformation.transform = transform
        self.multiWidget.transformations[-1] = transformation
        self._updateLandmarkTransforms()
	def _updateTransform(self):
		"""
		Update the landmark transform
		"""
		if PointsSetsIsEmpty(self.landmarkPointSets):
			return

		numberOfSets = NumberOfSets(self.landmarkPointSets)
		fixedPoints = vtkPoints()
		movingPoints = vtkPoints()
		fixedPoints.SetNumberOfPoints(numberOfSets)
		movingPoints.SetNumberOfPoints(numberOfSets)

		pointsetIndex = 0
		for index in range(len(self.landmarkPointSets)):
			pointset = self.landmarkPointSets[index]
			if pointset[0] and pointset[1]:
				fixedPoint = pointset[0]
				movingPoint = pointset[1]
				# Transform the point from the moving landmark with the original transform
				transPoint = self.originalTransform.TransformPoint(movingPoint)
				fixedPoints.SetPoint(pointsetIndex, fixedPoint)
				movingPoints.SetPoint(pointsetIndex, transPoint)
				pointsetIndex += 1

		landmarkTransform = vtkLandmarkTransform()
		if self.landmarkTransformType == 0:
			landmarkTransform.SetModeToRigidBody()
		elif self.landmarkTransformType == 1:
			landmarkTransform.SetModeToSimilarity()
		elif self.landmarkTransformType == 2:
			landmarkTransform.SetModeToAffine()
		landmarkTransform.SetSourceLandmarks(fixedPoints)
		landmarkTransform.SetTargetLandmarks(movingPoints)
		landmarkTransform.Update()

		transform = TransformWithMatrix(landmarkTransform.GetMatrix())
		transform.Inverse()
		
		transformation = self.multiWidget.transformations[-1]
		assert transformation.transformType == Transformation.TypeLandmark
		transformation.transform = transform
		self.multiWidget.transformations[-1] = transformation
		self._updateLandmarkTransforms()
Esempio n. 24
0
def AlignBoundingBoxes(source, target):
    # Use OBBTree to create an oriented bounding box for target and source
    sourceOBBTree = vtk.vtkOBBTree()
    sourceOBBTree.SetDataSet(source)
    sourceOBBTree.SetMaxLevel(1)
    sourceOBBTree.BuildLocator()

    targetOBBTree = vtk.vtkOBBTree()
    targetOBBTree.SetDataSet(target)
    targetOBBTree.SetMaxLevel(1)
    targetOBBTree.BuildLocator()

    sourceLandmarks = vtk.vtkPolyData()
    sourceOBBTree.GenerateRepresentation(0, sourceLandmarks)

    targetLandmarks = vtk.vtkPolyData()
    targetOBBTree.GenerateRepresentation(0, targetLandmarks)

    lmTransform = vtk.vtkLandmarkTransform()
    lmTransform.SetModeToSimilarity()
    lmTransform.SetTargetLandmarks(targetLandmarks.GetPoints())
    # lmTransformPD = vtk.vtkTransformPolyDataFilter()
    bestDistance = vtk.VTK_DOUBLE_MAX
    bestPoints = vtk.vtkPoints()
    bestDistance = BestBoundingBox("X", target, source, targetLandmarks,
                                   sourceLandmarks, bestDistance, bestPoints)
    bestDistance = BestBoundingBox("Y", target, source, targetLandmarks,
                                   sourceLandmarks, bestDistance, bestPoints)
    bestDistance = BestBoundingBox("Z", target, source, targetLandmarks,
                                   sourceLandmarks, bestDistance, bestPoints)

    lmTransform.SetSourceLandmarks(bestPoints)
    lmTransform.Modified()

    transformPD = vtk.vtkTransformPolyDataFilter()
    transformPD.SetInputData(source)
    transformPD.SetTransform(lmTransform)
    transformPD.Update()

    source.DeepCopy(transformPD.GetOutput())

    return
    def landmarkRegistration(self, fromMarkupsNode, toMarkupsNode,
                             outputTransformNode):
        logging.debug('landmarkRegistration')

        fromPoints = vtk.vtkPoints()
        toPoints = vtk.vtkPoints()

        nFromPoints = fromMarkupsNode.GetNumberOfFiducials()
        nToPoints = toMarkupsNode.GetNumberOfFiducials()

        if nFromPoints != nToPoints:
            return 'Number of points in markups nodes are not equal. Error {0:.2f}', 1

        if nFromPoints < 3:
            return 'Insufficient number of points in markups nodes. Error {0:.2f}', 2

        for i in range(nFromPoints):
            p = [0, 0, 0]
            fromMarkupsNode.GetNthControlPointPositionWorld(i, p)
            fromPoints.InsertNextPoint(p)
            toMarkupsNode.GetNthControlPointPositionWorld(i, p)
            toPoints.InsertNextPoint(p)

        lt = vtk.vtkLandmarkTransform()
        lt.SetSourceLandmarks(fromPoints)
        lt.SetTargetLandmarks(toPoints)
        lt.SetModeToSimilarity()
        lt.Update()

        resultsMatrix = vtk.vtkMatrix4x4()
        lt.GetMatrix(resultsMatrix)

        det = resultsMatrix.Determinant()
        if det < 1e-8:
            return 'Unstable registration. Check input for collinear points. Error {0:.2f}', 3

        outputTransformNode.SetMatrixTransformToParent(resultsMatrix)

        return self.calculateRMSE(nFromPoints, fromPoints, toPoints,
                                  resultsMatrix)
Esempio n. 26
0
    def matrixError(self, pre, post):
        pSourcePoints = vtk.vtkPoints()
        pTargetPoints = vtk.vtkPoints()

        # 求取术前空间到术后空间的转换矩阵
        for i in range(5):
            pTargetPoints.InsertPoint(i, post[i][0], post[i][1], post[i][2])
            pSourcePoints.InsertPoint(i, pre[i][0], pre[i][1], pre[i][2])

        landmarkTransform = vtk.vtkLandmarkTransform()
        landmarkTransform.SetSourceLandmarks(pSourcePoints)
        landmarkTransform.SetTargetLandmarks(pTargetPoints)
        landmarkTransform.SetModeToRigidBody()
        landmarkTransform.Update()

        matrix = landmarkTransform.GetMatrix()
        matrix_np = self.arrayFromVTKMatrix(matrix)

        temp_five = np.ones([5, 3], dtype=float)
        temp_dist = []
        for i in range(5):
            post_temp = np.array([pre[i][0], pre[i][1], pre[i][2], 1])
            post_temp_transform = np.matmul(matrix_np, post_temp)

            temp_five[i] = post_temp_transform[0:3]
            dist = np.linalg.norm(post[i] - post_temp_transform[0:3])
            temp_dist.append(dist)

        # print("post ", post)
        # print("temp_five ", temp_five)
        # print("temp_dist ", temp_dist)

        temp_dist = np.array(temp_dist)

        # print("max error ", np.max(temp_dist))

        # 返回最大的偏差
        return np.max(temp_dist), matrix_np
Esempio n. 27
0
 def applyLandmarkTransform(self):
     if (self.in2_pipe != None):
         in1_pts = self.pickerstyle.getNumberOfPoints("in1_pipeline")
         in2_pts = self.pickerstyle.getNumberOfPoints("in2_pipeline")
         if (in1_pts == in2_pts and in1_pts >= 3):
             lm = vtk.vtkLandmarkTransform()
             lm.SetTargetLandmarks(
                 self.pickerstyle.getPoints("in1_pipeline"))
             lm.SetSourceLandmarks(
                 self.pickerstyle.getPoints("in2_pipeline"))
             lm.SetModeToRigidBody()
             lm.Update()
             mat = lm.GetMatrix()
             self.in2_pipe.setRigidBodyTransformConcatenateMatrix(mat)
             self.pickerstyle.removePoints("in1_pipeline")
             self.pickerstyle.removePoints("in2_pipeline")
             self.refreshRenderWindow()
             self.updateGUI()
             self.statusBar().showMessage(
                 f"Landmark transform complete based on {in1_pts}", 4000)
         else:
             self.statusBar().showMessage(
                 "ERROR: Landmark transform could not be executed", 4000)
def affine_alignment(source_mesh, source_landmarks, target_landmarks):
    """
    Applies an affine transformation to the source mesh and landmarks

    :param source_mesh: vtkPolyData to be transformed
    :param source_landmarks: array of shape [n,3]
    :param target_landmarks: array of shape [n,3]

    :return: (transformed source_mesh, transformed source_landmarks)
    """
    tar = utils.np_to_vtkPoints(target_landmarks)
    src = utils.np_to_vtkPoints(source_landmarks)

    src_poly = vtk.vtkPolyData()
    src_poly.SetPoints(src)

    affine = vtk.vtkLandmarkTransform()
    affine.SetSourceLandmarks(src)
    affine.SetTargetLandmarks(tar)
    affine.SetModeToAffine()
    affine.Update()

    transform_mesh = vtk.vtkTransformPolyDataFilter()
    transform_mesh.SetTransform(affine)
    transform_mesh.SetInputData(source_mesh)
    transform_mesh.Update()
    transformed_mesh = transform_mesh.GetOutput()

    transform_landmarks = vtk.vtkTransformPolyDataFilter()
    transform_landmarks.SetTransform(affine)
    transform_landmarks.SetInputData(src_poly)
    transform_landmarks.Update()
    transformed_landmarks = utils.vtkPoints_to_np(
        transform_landmarks.GetOutput().GetPoints())

    return (transformed_mesh, transformed_landmarks)
Esempio n. 29
0
    def __init__(self, master=None):
        if master is None:
            master = Toplevel()
            master.wm_title("Registration")
            Frame.__init__(self, master)
            self.pack(fill='both', expand='true')
        else:
            Frame.__init__(self, master)

        # the lists of landmarks
        self._SourceLandmarks = []
        self._TargetLandmarks = []

        # the index of the current landmark
        self._CurrentLandmark = 0

        # the transformation that matches the landmarks
        self._SourcePoints = vtk.vtkPoints()
        self._TargetPoints = vtk.vtkPoints()
        self._Transform = vtk.vtkLandmarkTransform()
        # self._Transform.SetModeToRigidBody()
        self._Transform.SetSourceLandmarks(self._SourcePoints)
        self._Transform.SetTargetLandmarks(self._TargetPoints)

        # the FiducialMarkerFactory draws the annotations on the image
        self._FiducialMarkerFactory = None

        # the OrthoPlanesFactory acts as the cursor for Source points
        self._OrthoPlanesFactory = None

        # the TrackedPointer acts as the cursor for Target points
        self._TrackedPointer = None

        # a list of 2D panes: whenever a point is chosen, these will
        # be adjusted to ensure that the point is visible
        self._Panes = []

        # build the user interface
        mframe = Frame(self)

        lframe = Frame(mframe)

        self._Scrollbar = Scrollbar(lframe, relief='sunken', bd=2)
        self._Listbox = Listbox(
            lframe,
            yscrollcommand=self._Scrollbar.set,
            # selectmode='multiple',
            exportselection='false',
            font='courier',
            width=len(toanatomic(0, 0, 0)) + 6)
        self._Listbox.bind("<ButtonRelease-1>", self._Select)
        self._Listbox.bind("<KeyRelease>", self._SelectKey)
        # self._Listbox.bind("<KeyRelease-KP_Delete>",
        #                   lambda e,f=self._Delete: f())
        self._Listbox.bind("<KeyRelease-Delete>",
                           lambda e, f=self._Delete: f())
        # self._Listbox.bind("<KeyRelease-KP_Enter>",
        #                   lambda e,f=self._Add: f())
        self._Listbox.bind("<KeyRelease-Return>", lambda e, f=self._Add: f())
        self._Scrollbar.config(command=self._Listbox.yview)

        self._Listbox.pack(side='left', fill='both', expand='true')
        self._Scrollbar.pack(side='left', fill='y')
        lframe.pack(side='left', fill='both', expand='true')

        bframe1 = Frame(mframe, bd=1)
        bframe = Frame(bframe1, relief='sunken', bd=1)

        self._AddB = Button(bframe, text='Add', command=self._Add)
        self._NextB = Button(bframe, text='Next', command=self._Next)
        self._SetB = Button(bframe, text='Set', command=self._Set)
        self._PrevB = Button(bframe, text='Prev', command=self._Prev)
        self._DeleteB = Button(bframe, text='Delete', command=self._Delete)

        self._AddB.pack(side='top', fill='both', expand='true')
        self._NextB.pack(side='top', fill='both', expand='true')
        self._SetB.pack(side='top', fill='both', expand='true')
        self._PrevB.pack(side='top', fill='both', expand='true')
        self._DeleteB.pack(side='top', fill='both', expand='true')
        bframe.pack(side='left', fill='both', expand='true')
        bframe1.pack(side='left', fill='both', expand='true')

        mframe.pack(side='top', fill='both', expand='true')

        self._StdDevLabel = Label(
            self, text='Standard Deviation:   --- mm  (0 Points)')
        self._StdDevLabel.pack(side='top', fill='y', expand='true')
Esempio n. 30
0
 def register(self, fixedData, movingData, index = -1, discard = False, delta = 0, fov = 9999999.0,
         down_fix = 1, down_mov = 1, occ = 9999999.0, op = False, useMask = False, isTime = False, MaxRate = 0.2,
         aug = False, distance_fix = 0.3, distance_mov = 0.1, w_wrong = 1.5, truth_mov = None):
     time1 = time.time()
     if index == -1:
         index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
     if index is None:
         return None, None, None
     if index == 0:
         fixed_points = fixedData.getPointSet('Contour').copy()
         moving_points = movingData.getPointSet('Contour').copy()
     else:
         fixed_points = fixedData.getPointSet('Centerline').copy()
         moving_points = movingData.getPointSet('Centerline').copy()
     if truth_mov is None:
         truth_mov = moving_points.copy()
     
     fixed_bif = db.getBifurcation(fixed_points)
     moving_bif = db.getBifurcation(moving_points)
     
     if useMask:
         mask_points = movingData.getPointSet('Mask')
         for point in mask_points:
             moving_points = npy.delete(moving_points, npy.where((npy.abs(moving_points[:, 2] - point[2]) < 0.0001) & (npy.round(moving_points[:, -1]) == point[3])), axis = 0)
         
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)]
     moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
     
     # Use the bifurcation as the initial position
     if (fixed_bif < 0) or (moving_bif < 0):
         fixed_min = 0
     
     # Augmentation of pointset
     fixed = fixed_points.copy()
     moving = moving_points.copy()
     
     if index == 1 and aug:
         fixed = util.augmentCenterline(fixed, 1, 10)
         moving = util.augmentCenterline(moving, 1, 10)
         fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix
         mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov
         fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2])
         moving = util.resampleCenterline(moving, mov_dis / moving_res[2])
     
     fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) % down_fix == 0]
     moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] - moving_bif)) % down_mov == 0]
     
     fixed[:, :3] *= fixed_res[:3]
     moving[:, :3] *= moving_res[:3]
     
     new_trans_points = truth_mov
     result_center_points = movingData.getPointSet('Centerline').copy()
     new_trans_points = new_trans_points[new_trans_points[:, 3] >= 0]
     result_center_points = result_center_points[result_center_points[:, 3] >= 0]
     new_trans_points[:, :3] *= moving_res[:3]
     result_center_points[:, :3] *= moving_res[:3]
     
     if (fixed_bif >= 0) and (moving_bif >= 0):
         fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     
     # Prepare for ICP
     
     MaxIterNum = 50
     #MaxNum = 600
     MaxNum = int(MaxRate * moving.shape[0] + 0.5)
     
     targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
     targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()]
     target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
     Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()]
     
     for i in range(3):
         for x in fixed[npy.round(fixed[:, 3]) == i]:
             id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
             targetVertices[i].InsertNextCell(1)
             targetVertices[i].InsertCellPoint(id)
         target[i].SetPoints(targetPoints[i])
         target[i].SetVerts(targetVertices[i])
         
         Locator[i].SetDataSet(target[i])
         Locator[i].SetNumberOfCellsPerBucket(1)
         Locator[i].BuildLocator()
     
     step = 1
     if moving.shape[0] > MaxNum:
         ind = moving[:, 2].argsort()
         moving = moving[ind, :]
         step = moving.shape[0] / MaxNum
     nb_points = moving.shape[0] / step
     
     points1 = vtk.vtkPoints()
     points1.SetNumberOfPoints(nb_points)
     
     label = npy.zeros([MaxNum * 2], dtype = npy.int8)
     
     j = 0
     for i in range(nb_points):
         points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2])
         label[i] = moving[j][3]
         j += step
     
     closestp = vtk.vtkPoints()
     closestp.SetNumberOfPoints(nb_points)
     points2 = vtk.vtkPoints()
     points2.SetNumberOfPoints(nb_points)
     
     id1 = id2 = vtk.mutable(0)
     dist = vtk.mutable(0.0)
     outPoint = [0.0, 0.0, 0.0]
     p1 = [0.0, 0.0, 0.0]
     p2 = [0.0, 0.0, 0.0]
     iternum = 0
     a = points1
     b = points2
     if (op and index == 0) or (not op and index == 1):
         w_mat = [[1, w_wrong, w_wrong], [w_wrong, 1, 99999999], [w_wrong, 99999999, 1]]
     else:
         w_mat = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]
     
     accumulate = vtk.vtkTransform()
     accumulate.PostMultiply()
     LandmarkTransform = vtk.vtkLandmarkTransform()
     LandmarkTransform.SetModeToRigidBody()
     
     while True:
         for i in range(nb_points):
             min_dist = 99999999
             min_outPoint = [0.0, 0.0, 0.0]
             for j in range(3):
                 Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist)
                 dis = npy.sqrt(npy.sum((npy.array(outPoint) - a.GetPoint(i)) ** 2))
                 if dis * w_mat[label[i]][j] < min_dist:
                     min_dist = dis * w_mat[label[i]][j]
                     min_outPoint = copy.deepcopy(outPoint)
                 
             closestp.SetPoint(i, min_outPoint)
             
         LandmarkTransform.SetSourceLandmarks(a)
         LandmarkTransform.SetTargetLandmarks(closestp)
         LandmarkTransform.Update()
         accumulate.Concatenate(LandmarkTransform.GetMatrix())
             
         iternum += 1
         
         for i in range(nb_points):
             a.GetPoint(i, p1)
             LandmarkTransform.InternalTransformPoint(p1, p2)
             b.SetPoint(i, p2)
         b, a = a, b
         
         if iternum >= MaxIterNum:
             break
     
     matrix = accumulate.GetMatrix()
     
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I
     result_center_points[:, :3] = util.applyTransformForPoints(result_center_points[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, ml.zeros([3, 1], dtype = npy.float32))
     new_trans_points[:, :3] = util.applyTransformForPoints(new_trans_points[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, ml.zeros([3, 1], dtype = npy.float32))
     
     LandmarkTransform = vtk.vtkThinPlateSplineTransform()
     LandmarkTransform.SetBasisToR()
     iternum = 0
     # Non-rigid
     while True:
         for i in range(nb_points):
             min_dist = 99999999
             min_outPoint = [0.0, 0.0, 0.0]
             for j in range(3):
                 Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist)
                 dis = npy.sqrt(npy.sum((npy.array(outPoint) - a.GetPoint(i)) ** 2))
                 if dis * w_mat[label[i]][j] < min_dist:
                     min_dist = dis * w_mat[label[i]][j]
                     min_outPoint = copy.deepcopy(outPoint)
                 
             closestp.SetPoint(i, min_outPoint)
             
         LandmarkTransform.SetSourceLandmarks(a)
         LandmarkTransform.SetTargetLandmarks(closestp)
         LandmarkTransform.Update()
         
         '''
         for i in range(result_center_points.shape[0]):
             LandmarkTransform.InternalTransformPoint([result_center_points[i, 0], result_center_points[i, 1], result_center_points[i, 2]], p2)
             result_center_points[i, :3] = p2
         '''
         for i in range(new_trans_points.shape[0]):
             LandmarkTransform.InternalTransformPoint([new_trans_points[i, 0], new_trans_points[i, 1], new_trans_points[i, 2]], p2)
             new_trans_points[i, :3] = p2
             
         iternum += 1
         if iternum >= 1:
             break
         
         for i in range(nb_points):
             a.GetPoint(i, p1)
             LandmarkTransform.InternalTransformPoint(p1, p2)
             b.SetPoint(i, p2)
         b, a = a, b
     
     time2 = time.time()
     
     if (fixed_bif >= 0) and (moving_bif >= 0):
         new_trans_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
         result_center_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     new_trans_points[:, :3] /= fixed_res[:3]
     result_center_points[:, :3] /= fixed_res[:3]
     resultImage = movingData.getData().copy()
     
     sa = SurfaceErrorAnalysis(None)
     dataset = db.BasicData(npy.array([[[0]]]), fixedData.getInfo(), {'Contour': new_trans_points, 'Centerline': result_center_points})
     mean_dis, mean_whole, max_dis, max_whole = sa.analysis(dataset, point_data_fix = fixedData.getPointSet('Contour').copy(), useResult = True)
     del dataset
     print mean_dis
     print mean_whole
     
     if isTime:
         return resultImage, {'Contour': new_trans_points, 'Centerline': result_center_points}, [mean_dis, mean_whole], time2 - time1
     return resultImage, {'Contour': new_trans_points, 'Centerline': result_center_points}, [mean_dis, mean_whole]
# read source landmarks
SourceLMReader = vtk.vtkPolyDataReader()
SourceLMReader.SetFileName("DefaultLandmarks.vtk");
SourceLMReader.Update()
#print SourceLMReader.GetOutput().GetPoints()

# read target landmarks
TargetLMReader = vtk.vtkPolyDataReader()
TargetLMReader.SetFileName("TargetLandmarks.vtk");
TargetLMReader.Update()
#print TargetLMReader.GetOutput().GetPoints()


# create transformation
LandmarkTransform = vtk.vtkLandmarkTransform()
LandmarkTransform.SetSourceLandmarks(SourceLMReader.GetOutput().GetPoints() )
LandmarkTransform.SetTargetLandmarks(TargetLMReader.GetOutput().GetPoints() )
LandmarkTransform.SetModeToRigidBody()
LandmarkTransform.Update()
print LandmarkTransform.GetMatrix()

# apply transform
transformFilter = vtk.vtkTransformFilter()
#transformFilter.SetInput(vtkCylinder.GetOutput() ) 
transformFilter.SetInput(trianglefilter.GetOutput() ) 
transformFilter.SetTransform( LandmarkTransform) 
transformFilter.Update()

# write model
modelWriter = vtk.vtkDataSetWriter()
    def __init__(self, master=None):
        if master is None:
            master = Toplevel()
            master.wm_title("Registration")
            Frame.__init__(self, master)
            self.pack(fill='both', expand='true')
        else:
            Frame.__init__(self, master)

        # the lists of landmarks
        self._SourceLandmarks = []
        self._TargetLandmarks = []

        # the index of the current landmark
        self._CurrentLandmark = 0

        # the transformation that matches the landmarks
        self._SourcePoints = vtk.vtkPoints()
        self._TargetPoints = vtk.vtkPoints()
        self._Transform = vtk.vtkLandmarkTransform()
        # self._Transform.SetModeToRigidBody()
        self._Transform.SetSourceLandmarks(self._SourcePoints)
        self._Transform.SetTargetLandmarks(self._TargetPoints)

        # the FiducialMarkerFactory draws the annotations on the image
        self._FiducialMarkerFactory = None

        # the OrthoPlanesFactory acts as the cursor for Source points
        self._OrthoPlanesFactory = None

        # the TrackedPointer acts as the cursor for Target points
        self._TrackedPointer = None

        # a list of 2D panes: whenever a point is chosen, these will
        # be adjusted to ensure that the point is visible
        self._Panes = []

        # build the user interface
        mframe = Frame(self)

        lframe = Frame(mframe)

        self._Scrollbar = Scrollbar(lframe,
                                    relief='sunken',
                                    bd=2)
        self._Listbox = Listbox(lframe,
                                yscrollcommand=self._Scrollbar.set,
                                # selectmode='multiple',
                                exportselection='false',
                                font='courier',
                                width=len(toanatomic(0, 0, 0)) + 6)
        self._Listbox.bind("<ButtonRelease-1>", self._Select)
        self._Listbox.bind("<KeyRelease>", self._SelectKey)
        # self._Listbox.bind("<KeyRelease-KP_Delete>",
        #                   lambda e,f=self._Delete: f())
        self._Listbox.bind("<KeyRelease-Delete>",
                           lambda e, f=self._Delete: f())
        # self._Listbox.bind("<KeyRelease-KP_Enter>",
        #                   lambda e,f=self._Add: f())
        self._Listbox.bind("<KeyRelease-Return>",
                           lambda e, f=self._Add: f())
        self._Scrollbar.config(command=self._Listbox.yview)

        self._Listbox.pack(side='left', fill='both', expand='true')
        self._Scrollbar.pack(side='left', fill='y')
        lframe.pack(side='left', fill='both', expand='true')

        bframe1 = Frame(mframe, bd=1)
        bframe = Frame(bframe1, relief='sunken', bd=1)

        self._AddB = Button(bframe, text='Add', command=self._Add)
        self._NextB = Button(bframe, text='Next', command=self._Next)
        self._SetB = Button(bframe, text='Set', command=self._Set)
        self._PrevB = Button(bframe, text='Prev', command=self._Prev)
        self._DeleteB = Button(bframe, text='Delete', command=self._Delete)

        self._AddB.pack(side='top', fill='both', expand='true')
        self._NextB.pack(side='top', fill='both', expand='true')
        self._SetB.pack(side='top', fill='both', expand='true')
        self._PrevB.pack(side='top', fill='both', expand='true')
        self._DeleteB.pack(side='top', fill='both', expand='true')
        bframe.pack(side='left', fill='both', expand='true')
        bframe1.pack(side='left', fill='both', expand='true')

        mframe.pack(side='top', fill='both', expand='true')

        self._StdDevLabel = Label(self,
                                  text='Standard Deviation:   --- mm  (0 Points)')
        self._StdDevLabel.pack(side='top', fill='y', expand='true')
Esempio n. 33
0
    def register(self,
                 fixedData,
                 movingData,
                 index=-1,
                 discard=False,
                 delta=0,
                 fov=9999999.0,
                 down_fix=1,
                 down_mov=1,
                 occ=9999999.0,
                 useMask=False,
                 isTime=False,
                 MaxRate=0.2,
                 aug=False,
                 distance_fix=0.3,
                 distance_mov=0.1,
                 w_wrong=1.5):
        time1 = time.time()
        if index == -1:
            index = self.gui.getDataIndex({
                'Contour': 0,
                'Centerline': 1
            }, 'Select the object')
        if index is None:
            return None, None, None
        if index == 0:
            fixed_points = fixedData.getPointSet('Contour').copy()
            moving_points = movingData.getPointSet('Contour').copy()
        else:
            fixed_points = fixedData.getPointSet('Centerline').copy()
            moving_points = movingData.getPointSet('Centerline').copy()

        fixed_bif = db.getBifurcation(fixed_points)
        moving_bif = db.getBifurcation(moving_points)

        if useMask:
            mask_points = movingData.getPointSet('Mask')
            for point in mask_points:
                moving_points = npy.delete(
                    moving_points,
                    npy.where(
                        (npy.abs(moving_points[:, 2] - point[2]) < 0.0001)
                        & (npy.round(moving_points[:, -1]) == point[3])),
                    axis=0)

        fixed_res = fixedData.getResolution().tolist()
        moving_res = movingData.getResolution().tolist()
        fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)]
        moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]

        # Use the bifurcation as the initial position
        if (fixed_bif < 0) or (moving_bif < 0):
            fixed_min = 0

        # Augmentation of pointset
        fixed = fixed_points.copy()
        moving = moving_points.copy()

        if index == 1 and aug:
            fixed = util.augmentCenterline(fixed, 1, 10)
            moving = util.augmentCenterline(moving, 1, 10)
            fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix
            mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov
            fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2])
            moving = util.resampleCenterline(moving, mov_dis / moving_res[2])

        fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) %
                      down_fix == 0]
        moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] -
                                                    moving_bif)) %
                        down_mov == 0]

        fixed[:, :3] *= fixed_res[:3]
        moving[:, :3] *= moving_res[:3]

        if (fixed_bif >= 0) and (moving_bif >= 0):
            fixed[:, 2] -= (fixed_bif * fixed_res[2] -
                            moving_bif * moving_res[2] + delta)

        # Prepare for ICP
        LandmarkTransform = vtk.vtkLandmarkTransform()
        LandmarkTransform.SetModeToRigidBody()
        MaxIterNum = 50
        #MaxNum = 600
        MaxNum = int(MaxRate * moving.shape[0] + 0.5)

        targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
        targetVertices = [
            vtk.vtkCellArray(),
            vtk.vtkCellArray(),
            vtk.vtkCellArray()
        ]
        target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
        Locator = [
            vtk.vtkCellLocator(),
            vtk.vtkCellLocator(),
            vtk.vtkCellLocator()
        ]

        for i in range(3):
            for x in fixed[npy.round(fixed[:, 3]) == i]:
                id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
                targetVertices[i].InsertNextCell(1)
                targetVertices[i].InsertCellPoint(id)
            target[i].SetPoints(targetPoints[i])
            target[i].SetVerts(targetVertices[i])

            Locator[i].SetDataSet(target[i])
            Locator[i].SetNumberOfCellsPerBucket(1)
            Locator[i].BuildLocator()

        step = 1
        if moving.shape[0] > MaxNum:
            ind = moving[:, 2].argsort()
            moving = moving[ind, :]
            step = moving.shape[0] / MaxNum
        nb_points = moving.shape[0] / step

        accumulate = vtk.vtkTransform()
        accumulate.PostMultiply()

        points1 = vtk.vtkPoints()
        points1.SetNumberOfPoints(nb_points)

        label = npy.zeros([MaxNum * 2], dtype=npy.int8)

        j = 0
        for i in range(nb_points):
            points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2])
            label[i] = moving[j][3]
            j += step

        closestp = vtk.vtkPoints()
        closestp.SetNumberOfPoints(nb_points)
        points2 = vtk.vtkPoints()
        points2.SetNumberOfPoints(nb_points)

        id1 = id2 = vtk.mutable(0)
        dist = vtk.mutable(0.0)
        outPoint = [0.0, 0.0, 0.0]
        p1 = [0.0, 0.0, 0.0]
        p2 = [0.0, 0.0, 0.0]
        iternum = 0
        a = points1
        b = points2
        w_mat = [[1, w_wrong, w_wrong], [w_wrong, 1, 99999999],
                 [w_wrong, 99999999, 1]]

        while True:
            for i in range(nb_points):
                min_dist = 99999999
                min_outPoint = [0.0, 0.0, 0.0]
                for j in range(3):
                    Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1,
                                                id2, dist)
                    dis = npy.sqrt(
                        npy.sum((npy.array(outPoint) - a.GetPoint(i))**2))
                    if dis * w_mat[label[i]][j] < min_dist:
                        min_dist = dis * w_mat[label[i]][j]
                        min_outPoint = copy.deepcopy(outPoint)

                closestp.SetPoint(i, min_outPoint)

            LandmarkTransform.SetSourceLandmarks(a)
            LandmarkTransform.SetTargetLandmarks(closestp)
            LandmarkTransform.Update()

            accumulate.Concatenate(LandmarkTransform.GetMatrix())

            iternum += 1
            if iternum >= MaxIterNum:
                break

            for i in range(nb_points):
                a.GetPoint(i, p1)
                LandmarkTransform.InternalTransformPoint(p1, p2)
                b.SetPoint(i, p2)
            b, a = a, b
        time2 = time.time()

        # Get the result transformation parameters
        matrix = accumulate.GetMatrix()

        T = ml.mat([
            matrix.GetElement(0, 3),
            matrix.GetElement(1, 3),
            matrix.GetElement(2, 3)
        ]).T
        R = ml.mat([[
            matrix.GetElement(0, 0),
            matrix.GetElement(0, 1),
            matrix.GetElement(0, 2)
        ],
                    [
                        matrix.GetElement(1, 0),
                        matrix.GetElement(1, 1),
                        matrix.GetElement(1, 2)
                    ],
                    [
                        matrix.GetElement(2, 0),
                        matrix.GetElement(2, 1),
                        matrix.GetElement(2, 2)
                    ]]).I

        if (fixed_bif >= 0) and (moving_bif >= 0):
            T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] +
                     delta)

        # Resample the moving contour
        moving_points = movingData.getPointSet('Contour').copy()
        moving_center = movingData.getPointSet('Centerline').copy()
        new_trans_points, result_center_points = moving_points, moving_center
        result_center_points[:, :3] = util.applyTransformForPoints(
            result_center_points[:, :3], moving_res, fixed_res, R, T,
            ml.zeros([3, 1], dtype=npy.float32))
        new_trans_points[:, :3] = util.applyTransformForPoints(
            new_trans_points[:, :3], moving_res, fixed_res, R, T,
            ml.zeros([3, 1], dtype=npy.float32))
        T = -T
        T = R * T

        transform = sitk.Transform(3, sitk.sitkAffine)
        para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
        transform.SetParameters(para)

        movingImage = movingData.getSimpleITKImage()
        fixedImage = fixedData.getSimpleITKImage()
        resultImage = sitk.Resample(movingImage, fixedImage, transform,
                                    sitk.sitkLinear, 0, sitk.sitkFloat32)

        if isTime:
            return sitk.GetArrayFromImage(resultImage), {
                'Contour': new_trans_points,
                'Centerline': result_center_points
            }, para + [0, 0, 0], time2 - time1
        return sitk.GetArrayFromImage(resultImage), {
            'Contour': new_trans_points,
            'Centerline': result_center_points
        }, para + [0, 0, 0]
Esempio n. 34
0
    def __init__(self, comedi, config_dict):
        """
        @param comedi: Instance of comedi that will be used to update
        GUI and views.
        @param config_dict: This dict, part of the main module config,
        will be kept up to date throughout.
        """
        
        self._comedi = comedi
        self._cfg = config_dict

        # if we get an empty config dict, configure!
        if 'data1_landmarks' not in self._cfg:
            self._cfg['data1_landmarks'] = {}

        # do the list
        cp = comedi._view_frame.pane_controls.window
        r1 = comedi._data1_slice_viewer.renderer
        self._data1_landmarks = \
                LandmarkList(
                        self._cfg['data1_landmarks'], 
                        cp.data1_landmarks_olv, r1)

        if 'data2_landmarks' not in self._cfg:
            self._cfg['data2_landmarks'] = {}


        r2 = comedi._data2_slice_viewer.renderer
        self._data2_landmarks = \
                LandmarkList(
                        self._cfg['data2_landmarks'],
                        cp.data2_landmarks_olv, r2)

        self._setup_ui()
        self._bind_events()

        # we'll use this to store a binding to the current output
        self._output = None
        # and this to store a binding to the current confidence
        self._confidence = None

        # remember, this turns out to be the transform itself
        self._landmark = vtk.vtkLandmarkTransform()
        # and this guy is going to do the work
        self._trfm = vtk.vtkImageReslice()
        self._trfm.SetInterpolationModeToLinear()
        # setup a progress message:
        module_utils.setup_vtk_object_progress(
                self._comedi, self._trfm,
                'Transforming Data 2')


        # distance field will be calculated up to this distance,
        # saving you time and money!
        if KEY_MAX_DISTANCE not in self._cfg:
            self._cfg[KEY_MAX_DISTANCE] = 43

        md = self._cfg[KEY_MAX_DISTANCE]

        print "sslm starting itk init"
        # use itk fast marching to generate confidence field
        self._fm = itk.FastMarchingImageFilter.IF3IF3.New()
        self._fm.SetStoppingValue(md)
        self._fm.SetSpeedConstant(1.0)
        # setup a progress message
        print "sslm fm progress start"
        itk_kit.utils.setup_itk_object_progress(
            self, self._fm, 'itkFastMarchingImageFilter',
            'Propagating confidence front.', None,
            comedi._module_manager)
        print "sslm fm progress end"


        # and a threshold to clip off the really high values that fast
        # marching inserts after its max distance
        self._thresh = t = itk.ThresholdImageFilter.IF3.New()
        t.SetOutsideValue(md)
        # values equal to or greater than this are set to outside value
        t.ThresholdAbove(md)
        itk_kit.utils.setup_itk_object_progress(
                self, self._thresh, 'itkThresholdImageFilter',
                'Clipping high values in confidence field.', None,
                comedi._module_manager)

        t.SetInput(self._fm.GetOutput())
        # and a little something to convert it back to VTK world
        self._itk2vtk = itk.ImageToVTKImageFilter.IF3.New()
        self._itk2vtk.SetInput(t.GetOutput())
        print "sslm mm init end"
Esempio n. 35
0
## delny.Update()

# read source landmarks
SourceLMReader = vtk.vtkPolyDataReader()
SourceLMReader.SetFileName("DefaultLandmarks.vtk")
SourceLMReader.Update()
#print SourceLMReader.GetOutput().GetPoints()

# read target landmarks
TargetLMReader = vtk.vtkPolyDataReader()
TargetLMReader.SetFileName("TargetLandmarks.vtk")
TargetLMReader.Update()
#print TargetLMReader.GetOutput().GetPoints()

# create transformation
LandmarkTransform = vtk.vtkLandmarkTransform()
LandmarkTransform.SetSourceLandmarks(SourceLMReader.GetOutput().GetPoints())
LandmarkTransform.SetTargetLandmarks(TargetLMReader.GetOutput().GetPoints())
LandmarkTransform.SetModeToRigidBody()
LandmarkTransform.Update()
print LandmarkTransform.GetMatrix()

# apply transform
transformFilter = vtk.vtkTransformFilter()
#transformFilter.SetInput(vtkCylinder.GetOutput() )
transformFilter.SetInput(trianglefilter.GetOutput())
transformFilter.SetTransform(LandmarkTransform)
transformFilter.Update()

# write model
modelWriter = vtk.vtkDataSetWriter()
Esempio n. 36
0
    def distanceAndAngleCompute(self, num=7):
        pSourcePoints = vtk.vtkPoints()
        pTargetPoints = vtk.vtkPoints()

        # 求取术后空间到术前空间的转换矩阵
        for i in range(num):
            pTargetPoints.InsertPoint(i, self.preoperative[i][0],
                                      self.preoperative[i][1],
                                      self.preoperative[i][2])
            pSourcePoints.InsertPoint(i, self.postoperative[i][0],
                                      self.postoperative[i][1],
                                      self.postoperative[i][2])

        # 将种植体的植入点和跟尖点加入
        pSourcePoints.InsertPoint(num, self.ImplantPosition[0][3],
                                  self.ImplantPosition[0][4],
                                  self.ImplantPosition[0][5])
        pSourcePoints.InsertPoint(num + 1, self.ImplantPosition[1][3],
                                  self.ImplantPosition[1][4],
                                  self.ImplantPosition[1][5])

        pTargetPoints.InsertPoint(num, self.ImplantPosition[0][0],
                                  self.ImplantPosition[0][1],
                                  self.ImplantPosition[0][2])
        pTargetPoints.InsertPoint(num + 1, self.ImplantPosition[1][0],
                                  self.ImplantPosition[1][1],
                                  self.ImplantPosition[1][2])

        landmarkTransform = vtk.vtkLandmarkTransform()
        landmarkTransform.SetSourceLandmarks(pSourcePoints)
        landmarkTransform.SetTargetLandmarks(pTargetPoints)
        landmarkTransform.SetModeToRigidBody()
        landmarkTransform.Update()

        matrix = landmarkTransform.GetMatrix()

        matrix_np = self.arrayFromVTKMatrix(matrix)

        for i in range(4):
            for j in range(4):
                print("{:10.7f}".format(matrix.GetElement(i, j)), end=", ")
            print("")

        post_root = np.array([
            self.ImplantPosition[1][3], self.ImplantPosition[1][4],
            self.ImplantPosition[1][5], 1
        ])
        post_implant = np.array([
            self.ImplantPosition[0][3], self.ImplantPosition[0][4],
            self.ImplantPosition[0][5], 1
        ])

        # print("术后植入点 ", post_implant)
        # print("术后跟尖点 ", post_root)

        post_implant = np.matmul(matrix_np, post_implant)
        post_root = np.matmul(matrix_np, post_root)

        post_implant = post_implant[0:3]
        post_root = post_root[0:3]

        pre_root = np.array([
            self.ImplantPosition[1][0], self.ImplantPosition[1][1],
            self.ImplantPosition[1][2]
        ])
        pre_implant = np.array([
            self.ImplantPosition[0][0], self.ImplantPosition[0][1],
            self.ImplantPosition[0][2]
        ])

        print("术前植入点 ", pre_implant)
        print("术前跟尖点 ", pre_root)

        print("术后植入点 ", post_implant)
        print("术后跟尖点 ", post_root)

        print("植入点之间的距离偏差 ", np.linalg.norm(pre_implant - post_implant))
        print("根尖点之间的距离偏差 ", np.linalg.norm(pre_root - post_root))

        angle = vtk.vtkMath().AngleBetweenVectors(pre_root - pre_implant,
                                                  post_root - post_implant)
        print("角度偏差 ", math.degrees(angle))
        print(Style.RESET_ALL)
Esempio n. 37
0
  def performAffineAndThinPlateRegistration(self, state, landmarks):
    """Perform Affine registration first, use the transformed result as the input of the thin plate transform"""
    
    # if state.transformed:
     # if state.transformed.GetTransformNodeID() != state.transform.GetID():
        # state.transformed.SetAndObserveTransformNodeID(state.transform.GetID())


    volumeNodes = (state.fixed, state.moving)
    fiducialNodes = (state.fixedFiducials,state.movingFiducials)
    points = state.logic.vtkPointsForVolumes( volumeNodes, fiducialNodes )
 
    #yingli debug
    #print 'self.linearMode',self.linearMode

    if not self.landmarkTransform:
        self.landmarkTransform = vtk.vtkLandmarkTransform()

    if self.linearMode == 'Rigid':
      self.landmarkTransform.SetModeToRigidBody()
    if self.linearMode == 'Similarity':
      self.landmarkTransform.SetModeToSimilarity()
    if self.linearMode == 'Affine':
      self.landmarkTransform.SetModeToAffine()
    if state.fixedFiducials.GetNumberOfFiducials() < 3:
      self.landmarkTransform.SetModeToRigidBody()
   
    self.landmarkTransform.SetSourceLandmarks(points[state.moving])
    self.landmarkTransform.SetTargetLandmarks(points[state.fixed])
    self.landmarkTransform.Update()

    #transform moving landmarks
    affine_transformed_moving_points = vtk.vtkPoints()
    self.landmarkTransform.TransformPoints(points[state.moving],affine_transformed_moving_points)

    #yingli debug
    #print self.landmarkTransform.GetMatrix()
    #print 'old moving', points[state.moving].GetPoint(0)
    #print 'new moving', affine_transformed_moving_points.GetPoint(0)

    # do thin plate, use affine transformed result as the input
    # since this is a resample transform, source is the fixed (resampling target) space
    # and moving is the target space
    if not self.thinPlateTransform:
      self.thinPlateTransform = vtk.vtkThinPlateSplineTransform()
    self.thinPlateTransform.SetBasisToR() # for 3D transform
    self.thinPlateTransform.SetSourceLandmarks(affine_transformed_moving_points)
    self.thinPlateTransform.SetTargetLandmarks(points[state.fixed])
    self.thinPlateTransform.Update()

    if points[state.moving].GetNumberOfPoints() != points[state.fixed].GetNumberOfPoints():
      raise hell

    #add nesting transfrom: order matters!
    transformSelector = slicer.qMRMLNodeComboBox()
    transformSelector.nodeTypes = ( ("vtkMRMLTransformNode"), "" )
    transformSelector.selectNodeUponCreation = True
    transformSelector.addEnabled = True
    transformSelector.removeEnabled = True
    transformSelector.noneEnabled = True
    transformSelector.showHidden = False
    transformSelector.showChildNodeTypes = False
    transformSelector.setMRMLScene( slicer.mrmlScene )
    transformSelector.setToolTip( "The transform for linear registration" )
    transformSelector.enabled = False

    # concatenate transfroms: method 1: add nesting transfrom: order matters!
    # note: this method will keep each transform(not ideal)
    
    # landmarkTransformNode = slicer.util.getNode('Affine-Transform')
    # if not landmarkTransformNode:
        # landmarkTransformNode=transformSelector.addNode()
        # landmarkTransformNode.SetName('Affine-Transform')
        # state.transform.SetAndObserveTransformNodeID(landmarkTransformNode.GetID())

    # landmarkTransformNode.ApplyTransform(self.landmarkTransform)

    # thinPlateTransformNode = slicer.util.getNode('ThinPlate-Transform')
    # if not thinPlateTransformNode:
        # thinPlateTransformNode=transformSelector.addNode()
        # thinPlateTransformNode.SetName('ThinPlate-Transform')
        # landmarkTransformNode.SetAndObserveTransformNodeID(thinPlateTransformNode.GetID())

    # # thinPlateTransformNode.ApplyTransform(self.thinPlateTransform)
    
    #state.transform.SetAndObserveTransformToParent(self.landmarkTransform)
    # #state.transform.SetAndObserveTransformToParent(self.thinPlateTransform)
    # stateTransformNodeNode = slicer.util.getNode('Transform')
    # stateTransformNodeNode.SetAndObserveTransformToParent(self.thinPlateTransform)


    #test vtk concatenate
    #self.landmarkTransform.Concatenate(self.landmarkTransform)
    #state.transform.SetAndObserveTransformToParent(self.thinPlateTransform)

    #concatenate transfroms: method 2: use vtkGeneralTransform to concatenate transfroms.
    transform = vtk.vtkGeneralTransform()
    transform.Concatenate(self.thinPlateTransform)
    transform.Concatenate(self.landmarkTransform)
    state.transform.SetAndObserveTransformToParent(transform)
Esempio n. 38
0
    def ComputeCalibration(self, usCalibrationNode, listNode,
                           eventid):  #Ignore listnode and eventid
        if (usCalibrationNode is None):
            return

        markedPointsList = usCalibrationNode.GetNodeReference(
            ImagelessUSCalibrationWidget.MARKED_POINTS_ROLE)
        unmarkedPointsList = usCalibrationNode.GetNodeReference(
            ImagelessUSCalibrationWidget.UNMARKED_POINTS_ROLE)
        if (markedPointsList is None or unmarkedPointsList is None):
            return

        if (markedPointsList.GetNumberOfFiducials() < 2):
            usCalibrationNode.SetAttribute(
                ImagelessUSCalibrationWidget.OUTPUT_MESSAGE_ROLE,
                "Insufficient number of marked corner points selected.")
            return

        if (unmarkedPointsList.GetNumberOfFiducials() < 2):
            usCalibrationNode.SetAttribute(
                ImagelessUSCalibrationWidget.OUTPUT_MESSAGE_ROLE,
                "Insufficient number of unmarked corner points selected.")
            return

        # Assume the ordering of points is:
        # Unmarked near, marked near, unmarked far, marked far

        # Find the points in the probe coordinate system
        markedCorner1 = [0, 0, 0]
        markedPointsList.GetNthFiducialPosition(0, markedCorner1)
        markedCorner2 = [0, 0, 0]
        markedPointsList.GetNthFiducialPosition(1, markedCorner2)

        unmarkedCorner1 = [0, 0, 0]
        unmarkedPointsList.GetNthFiducialPosition(0, unmarkedCorner1)
        unmarkedCorner2 = [0, 0, 0]
        unmarkedPointsList.GetNthFiducialPosition(1, unmarkedCorner2)

        # Find the near points
        markedNearPoint = [0, 0, 0]
        vtk.vtkMath.Add(markedCorner1, markedCorner2, markedNearPoint)
        vtk.vtkMath.MultiplyScalar(markedNearPoint, 0.5)

        unmarkedNearPoint = [0, 0, 0]
        vtk.vtkMath.Add(unmarkedCorner1, unmarkedCorner2, unmarkedNearPoint)
        vtk.vtkMath.MultiplyScalar(unmarkedNearPoint, 0.5)

        # Find the vector required for computing the far points
        markedUnmarkedVector = [0, 0, 0]
        vtk.vtkMath.Subtract(unmarkedNearPoint, markedNearPoint,
                             markedUnmarkedVector)

        markedCornerVector = [0, 0, 0]
        vtk.vtkMath.Subtract(markedCorner2, markedCorner1, markedCornerVector)

        unmarkedCornerVector = [0, 0, 0]
        vtk.vtkMath.Subtract(unmarkedCorner2, unmarkedCorner1,
                             unmarkedCornerVector)

        markedFarVector = [0, 0, 0]
        vtk.vtkMath.Cross(markedUnmarkedVector, markedCornerVector,
                          markedFarVector)
        vtk.vtkMath.Normalize(markedFarVector)

        unmarkedFarVector = [0, 0, 0]
        vtk.vtkMath.Cross(markedUnmarkedVector, unmarkedCornerVector,
                          unmarkedFarVector)
        vtk.vtkMath.Normalize(unmarkedFarVector)

        # Compute the far points
        try:
            depth = float(
                usCalibrationNode.GetAttribute(
                    ImagelessUSCalibrationWidget.DEPTH_ROLE))
        except TypeError:
            usCalibrationNode.SetAttribute(
                ImagelessUSCalibrationWidget.OUTPUT_MESSAGE_ROLE,
                "Depth improperly specified.")
            return

        vtk.vtkMath.MultiplyScalar(markedFarVector, depth)
        markedFarPoint = [0, 0, 0]
        vtk.vtkMath.Add(markedNearPoint, markedFarVector, markedFarPoint)

        vtk.vtkMath.MultiplyScalar(unmarkedFarVector, depth)
        unmarkedFarPoint = [0, 0, 0]
        vtk.vtkMath.Add(unmarkedNearPoint, unmarkedFarVector, unmarkedFarPoint)

        # Now, we can assemble the probe points
        probePoints = vtk.vtkPoints()
        probePoints.InsertNextPoint(unmarkedNearPoint)
        probePoints.InsertNextPoint(markedNearPoint)
        probePoints.InsertNextPoint(unmarkedFarPoint)
        probePoints.InsertNextPoint(markedFarPoint)

        # Compute the scaling factor
        usImageNode = usCalibrationNode.GetNodeReference(
            ImagelessUSCalibrationWidget.ULTRASOUND_IMAGE_ROLE)
        if (usImageNode is None or usImageNode.GetImageData() is None):
            usCalibrationNode.SetAttribute(
                ImagelessUSCalibrationWidget.OUTPUT_MESSAGE_ROLE,
                "No ultrasound image is selected.")
            return

        # The scale is the ratio of depth to y pixels
        usImageDimensions = [0, 0, 0]
        usImageNode.GetImageData().GetDimensions(usImageDimensions)

        pixelsToMmScale = depth / usImageDimensions[1]  # y dimension

        imagePixelToImageMm = vtk.vtkTransform()
        imagePixelToImageMm.Scale(
            [pixelsToMmScale, pixelsToMmScale,
             pixelsToMmScale])  # Uniform scaling - similarity transform
        print pixelsToMmScale

        # Next, we can assembla the image points
        imagePoints_ImageMm = vtk.vtkPoints()
        imagePoints_ImageMm.InsertNextPoint([0, 0, 0])
        imagePoints_ImageMm.InsertNextPoint(
            [usImageDimensions[0] * pixelsToMmScale, 0, 0])
        imagePoints_ImageMm.InsertNextPoint([0, depth, 0])
        imagePoints_ImageMm.InsertNextPoint(
            [usImageDimensions[0] * pixelsToMmScale, depth, 0])

        # Compute the transform (without the scaling)
        imageToProbeTransformNode = usCalibrationNode.GetNodeReference(
            ImagelessUSCalibrationWidget.IMAGE_TO_PROBE_TRANSFORM_ROLE)
        if (imageToProbeTransformNode is None):
            usCalibrationNode.SetAttribute(
                ImagelessUSCalibrationWidget.OUTPUT_MESSAGE_ROLE,
                "No output ImageToProbe transform specified.")
            return

        imageMmToProbe = vtk.vtkLandmarkTransform()
        imageMmToProbe.SetSourceLandmarks(imagePoints_ImageMm)
        imageMmToProbe.SetTargetLandmarks(probePoints)
        imageMmToProbe.SetModeToRigidBody()
        imageMmToProbe.Update()

        # The overall ImageToProbe = ImageMmToProbe * ImagePixelToImageMm
        imageToProbeTransform = vtk.vtkTransform()
        imageToProbeTransform.PreMultiply()
        imageToProbeTransform.Concatenate(imageMmToProbe)
        imageToProbeTransform.Concatenate(imagePixelToImageMm)

        imageToProbeMatrix = vtk.vtkMatrix4x4()
        imageToProbeTransform.GetMatrix(imageToProbeMatrix)

        imageToProbeTransformNode.SetMatrixTransformToParent(
            imageToProbeMatrix)

        usCalibrationNode.SetAttribute(
            ImagelessUSCalibrationWidget.OUTPUT_MESSAGE_ROLE, "Success!")
def GetApplicatorTransform(pointtip,pointentry,SourceLandmarkFileName, TargetLandmarkFileName ):
  ApplicatorTipLength = .011 #m
  # template applicator center at coordinate       (0,                         0., 0. ) m
  # template applicator distal ends at coordinates (0,  0.,+/- ApplicatorTipLength/2. ) m
  originalOrientation = vtk.vtkPoints()
  originalOrientation.SetNumberOfPoints(2)
  originalOrientation.SetPoint(0,0.,0.,         0.            )
  originalOrientation.SetPoint(1,0.,0., ApplicatorTipLength/2.)
  slicerLength   = numpy.linalg.norm( numpy.array(pointentry) - numpy.array(pointtip) )
  unitdirection  = 1./slicerLength * (numpy.array(pointentry) - numpy.array(pointtip) ) 
  pointscaled = pointtip + ApplicatorTipLength/2. * unitdirection
  print "points", pointentry, pointtip, pointscaled, slicerLength, numpy.linalg.norm( unitdirection  ), numpy.linalg.norm( pointscaled - pointtip ) 
  slicerOrientation   = vtk.vtkPoints()
  slicerOrientation.SetNumberOfPoints(2)
  slicerOrientation.SetPoint(0,pointscaled[0],pointscaled[1],pointscaled[2] )
  slicerOrientation.SetPoint(1,pointtip[   0],pointtip[   1],pointtip[   2] )

  # write landmarks to file
  WriteVTKPoints(originalOrientation,SourceLandmarkFileName)
  WriteVTKPoints(slicerOrientation  ,TargetLandmarkFileName)

  ApplicatorLineTransform = vtk.vtkLandmarkTransform()
  ApplicatorLineTransform.SetModeToRigidBody()
  ApplicatorLineTransform.SetSourceLandmarks(originalOrientation)
  ApplicatorLineTransform.SetTargetLandmarks(slicerOrientation  )
  ApplicatorLineTransform.Update()
  print ApplicatorLineTransform.GetMatrix()

  # create model of applicator 
  ApplicatorLength   = .10 #m
  vtkCylinder = vtk.vtkCylinderSource()
  vtkCylinder.SetHeight( ApplicatorLength ); 
  vtkCylinder.SetRadius( .00075 );
  vtkCylinder.SetCenter(0.0, 0.0, 0.0 );
  vtkCylinder.SetResolution(16);
  vtkCylinder.SetCapping(1);

  # model orientation
  modelOrientation = vtk.vtkPoints()
  modelOrientation.SetNumberOfPoints(2)
  modelOrientation.SetPoint(0, 0.,         0.         ,0. )
  modelOrientation.SetPoint(1, 0.,-ApplicatorLength/2.,0. )

  ModelLineTransform = vtk.vtkLandmarkTransform()
  ModelLineTransform.SetModeToRigidBody()
  ModelLineTransform.SetSourceLandmarks(modelOrientation   )
  ModelLineTransform.SetTargetLandmarks(slicerOrientation  )
  ModelLineTransform.Update()
  print ModelLineTransform.GetMatrix()

  # transform
  slicertransformFilter = vtk.vtkTransformFilter()
  slicertransformFilter.SetInput(vtkCylinder.GetOutput() ) 
  slicertransformFilter.SetTransform( ModelLineTransform ) 
  slicertransformFilter.Update()
  apppolyData=slicertransformFilter.GetOutput();

  # write model to file
  vtkModelWriter = vtk.vtkDataSetWriter()
  vtkModelWriter.SetInput(apppolyData)
  vtkModelWriter.SetFileName("applicator.vtk")
  vtkModelWriter.SetFileTypeToBinary()
  vtkModelWriter.Write()
  # return transform
  return ApplicatorLineTransform
Esempio n. 40
0
def ICP(args):
    # This method takes one source surface files and ICP align it to a set of target surfaces.

    targetNameList = args[0]  # List of target names
    sourceSurfaceFile = args[1]  # name and full path of the source surface.
    dirSurface = args[2]  # Path of the surface files.
    dirOutputSurface = args[3]  # Output path the aligned source surfaces.
    dirLandmark = args[4]  #Path of the landmark files
    sourceLandmarkFile = args[5]
    dirOutputLandmarks = args[6]

    sourceName = sourceSurfaceFile.split('\\')[-1][:-4]

    #sourceSurfaceFile = os.path.join(dirSurface,sourceName + '.vtk')
    targetSurfaceFile = os.path.join(dirSurface, targetNameList + '.vtk')
    filename = os.path.join(dirOutputSurface, targetNameList + '.vtk')

    # Reading surfaces
    reader = vtk.vtkPolyDataReader()
    reader.SetFileName(sourceSurfaceFile)
    reader.Update()
    sourceSurface = reader.GetOutput()

    reader = vtk.vtkPolyDataReader()
    reader.SetFileName(targetSurfaceFile)
    reader.Update()
    targetSurface = reader.GetOutput()
    if targetSurface.GetNumberOfPoints() < 1:
        print('Could not read', targetSurfaceFile)
        return

    #------------------------------------------------------------------------------------------------
    # Reading landmarks
    targetLandmarkFile = os.path.join(dirLandmark, targetNameList + '.txt')

    targetLandmarks = ((np.loadtxt(targetLandmarkFile, skiprows=2)))
    if not os.path.isfile(sourceLandmarkFile):
        print('\nSource Surface: %s has no landmarks file' % sourceName)
        return np.float64(), np.float64()
    sourceLandmarks = ((np.loadtxt(sourceLandmarkFile, skiprows=2)))

    numberOfLandmarks = np.size(targetLandmarks, 0)

    # Set points in vtk
    sourcePoints = vtk.vtkPoints()
    for point in sourceLandmarks:
        sourcePoints.InsertNextPoint(point)
    source = vtk.vtkPolyData()
    source.SetPoints(sourcePoints)

    targetPoints = vtk.vtkPoints()
    for point in targetLandmarks:
        targetPoints.InsertNextPoint(point)
    target = vtk.vtkPolyData()
    target.SetPoints(targetPoints)

    #------------------------------------------------------------------------------------------------
    # Find landmark transformation
    landmarkTransform = vtk.vtkLandmarkTransform()
    landmarkTransform.SetSourceLandmarks(sourcePoints)
    landmarkTransform.SetTargetLandmarks(targetPoints)
    landmarkTransform.SetModeToSimilarity()
    landmarkTransform.Update()

    # Apply landmarks transformation to source surface
    TransformFilter = vtk.vtkTransformPolyDataFilter()
    TransformFilter.SetInputData(sourceSurface)
    TransformFilter.SetTransform(landmarkTransform)
    TransformFilter.Update()
    transformedSourceSurface = TransformFilter.GetOutput()

    # Apply landmarks transformation to source landmarks
    TransformFilter = vtk.vtkTransformPolyDataFilter()
    TransformFilter.SetInputData(source)
    TransformFilter.SetTransform(landmarkTransform)
    TransformFilter.Update()
    transformedSourceLandmarks = TransformFilter.GetOutput()

    #------------------------------------------------------------------------------------------------
    # Find icp transformation
    icp = vtk.vtkIterativeClosestPointTransform()
    icp.SetSource(transformedSourceSurface)
    icp.SetTarget(targetSurface)
    icp.GetLandmarkTransform().SetModeToRigidBody()

    icp.Modified()
    icp.Update()
    #------------------------------------------------------------------------------------------------
    # Apply icp transformation to transformed source surface
    TransformFilter = vtk.vtkTransformPolyDataFilter()
    TransformFilter.SetInputData(transformedSourceSurface)
    TransformFilter.SetTransform(icp)
    TransformFilter.Update()
    icptransformedSourceSurface = TransformFilter.GetOutput()

    # Apply icp transformation to transformed source landmarks
    TransformFilter = vtk.vtkTransformPolyDataFilter()
    TransformFilter.SetInputData(transformedSourceLandmarks)
    TransformFilter.SetTransform(icp)
    TransformFilter.Update()
    icptransformedSourceLandmarks = TransformFilter.GetOutput()

    #===========================================================================
    # RMS_transformedSurface = Metrics.RMS(icptransformedSourceSurface,targetSurface,VTKobj=True)
    # RMS_SourceTarget = Metrics.RMS(sourceSurface,targetSurface,VTKobj=True)
    #===========================================================================

    #------------------------------------------------------------------------------------------------
    # Write transformed source surface to .vtk file

    writer = vtk.vtkPolyDataWriter()
    writer.SetInputData(icptransformedSourceSurface)
    #writer.SetInputData(transformedSourceSurface)
    writer.SetFileName(filename)
    writer.Write()

    # Write transformed landmarks to .txt file readable by elastix
    npTranformedLandmarks = np.zeros([numberOfLandmarks, 3])
    for index in range(numberOfLandmarks):
        point = [0, 0, 0]
        icptransformedSourceLandmarks.GetPoint(index, point)
        #transformedSourceLandmarks.GetPoint(index, point)
        npTranformedLandmarks[index, :] = point
    filename = os.path.join(dirOutputLandmarks, targetNameList + '.txt')

    with open(filename, 'w+') as f:
        f.write('point\n')
        f.write(str(numberOfLandmarks))
        for idx in range(numberOfLandmarks):
            f.write('\n' + str(npTranformedLandmarks[idx, 0]) + ' ')
            for Val in npTranformedLandmarks[idx, 1:]:
                f.write(str(Val) + ' ')
Esempio n. 41
0
 def register(self, fixedData, movingData, index = -1, discard = False, delta = 0, fov = 9999999.0,
         down_fix = 1, down_mov = 1, occ = 9999999.0, op = False, useMask = False, isTime = False, MaxRate = 0.2,
         aug = False, distance_fix = 0.3, distance_mov = 0.1):
     time1 = time.time()
     if index == -1:
         index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
     if index is None:
         return None, None, None
     if index == 0:
         fixed_points = fixedData.getPointSet('Contour').copy()
         moving_points = movingData.getPointSet('Contour').copy()
     else:
         fixed_points = fixedData.getPointSet('Centerline').copy()
         moving_points = movingData.getPointSet('Centerline').copy()
     
     fixed_bif = db.getBifurcation(fixed_points)
     moving_bif = db.getBifurcation(moving_points)
     
     if useMask:
         mask_points = movingData.getPointSet('Mask')
         for point in mask_points:
             moving_points = npy.delete(moving_points, npy.where((npy.abs(moving_points[:, 2] - point[2]) < 0.0001) & (npy.round(moving_points[:, -1]) == point[3])), axis = 0)
         
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)]
     moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
     
     # Use the bifurcation as the initial position
     if (fixed_bif < 0) or (moving_bif < 0):
         fixed_min = 0
     
     # Augmentation of pointset
     fixed = fixed_points.copy()
     moving = moving_points.copy()
     
     if index == 1 and aug:
         fixed = util.augmentCenterline(fixed, 1, 10)
         moving = util.augmentCenterline(moving, 1, 10)
         fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix
         mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov
         fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2])
         moving = util.resampleCenterline(moving, mov_dis / moving_res[2])
     
     fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) % down_fix == 0]
     moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] - moving_bif)) % down_mov == 0]
     
     fixed[:, :3] *= fixed_res[:3]
     moving[:, :3] *= moving_res[:3]
     
     if (fixed_bif >= 0) and (moving_bif >= 0):
         fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     
     # Prepare for ICP
     LandmarkTransform = vtk.vtkLandmarkTransform()
     LandmarkTransform.SetModeToRigidBody()
     MaxIterNum = 50
     #MaxNum = 600
     MaxNum = int(MaxRate * moving.shape[0] + 0.5)
     
     targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
     targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()]
     target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
     Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()]
     if index == 0:
         if not op:
             label_dis = [3, 3, 3]
         else:
             label_dis = [3, 2, 1]
     else:
         if op:
             label_dis = [3, 3, 3]
         else:
             label_dis = [3, 2, 1]
         
     
     for i in range(3):
         for x in fixed[npy.round(fixed[:, 3]) != label_dis[i]]:
             id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
             targetVertices[i].InsertNextCell(1)
             targetVertices[i].InsertCellPoint(id)
         target[i].SetPoints(targetPoints[i])
         target[i].SetVerts(targetVertices[i])
         
         Locator[i].SetDataSet(target[i])
         Locator[i].SetNumberOfCellsPerBucket(1)
         Locator[i].BuildLocator()
     
     step = 1
     if moving.shape[0] > MaxNum:
         ind = moving[:, 2].argsort()
         moving = moving[ind, :]
         step = moving.shape[0] / MaxNum
     nb_points = moving.shape[0] / step
     
     accumulate = vtk.vtkTransform()
     accumulate.PostMultiply()
     
     points1 = vtk.vtkPoints()
     points1.SetNumberOfPoints(nb_points)
     
     label = npy.zeros([MaxNum * 2], dtype = npy.int8)
     
     j = 0
     for i in range(nb_points):
         points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2])
         label[i] = moving[j][3]
         j += step
     
     closestp = vtk.vtkPoints()
     closestp.SetNumberOfPoints(nb_points)
     points2 = vtk.vtkPoints()
     points2.SetNumberOfPoints(nb_points)
     
     id1 = id2 = vtk.mutable(0)
     dist = vtk.mutable(0.0)
     outPoint = [0.0, 0.0, 0.0]
     p1 = [0.0, 0.0, 0.0]
     p2 = [0.0, 0.0, 0.0]
     iternum = 0
     a = points1
     b = points2
     
     '''
     path = sys.argv[0]
     if os.path.isfile(path):
         path = os.path.dirname(path)
     path += '/Data/Transform'
     wfile = open("%s/transform.txt" % path, 'w')
     
     matrix = accumulate.GetMatrix()
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T;
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I
     if (fixed_bif >= 0) and (moving_bif >= 0):
         T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     saveTransform(wfile, T, R)
     '''
     
     while True:
         for i in range(nb_points):
             Locator[label[i]].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist)
             closestp.SetPoint(i, outPoint)
             
         LandmarkTransform.SetSourceLandmarks(a)
         LandmarkTransform.SetTargetLandmarks(closestp)
         LandmarkTransform.Update()
         
         accumulate.Concatenate(LandmarkTransform.GetMatrix())
         
         iternum += 1
         if iternum >= MaxIterNum:
             break
         
         dist_err = 0
         for i in range(nb_points):
             a.GetPoint(i, p1)
             LandmarkTransform.InternalTransformPoint(p1, p2)
             b.SetPoint(i, p2)
             dist_err += npy.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 + (p1[2] - p2[2]) ** 2)
         dist_err /= nb_points
         print "iter = %d: %f" % (iternum, dist_err)
         '''
         matrix = accumulate.GetMatrix()
         T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T;
         R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                     [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                     [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I;
         if (fixed_bif >= 0) and (moving_bif >= 0):
             T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
         saveTransform(wfile, T, R)
         '''
         b, a = a, b
     time2 = time.time()
     #wfile.close()
     # Get the result transformation parameters
     matrix = accumulate.GetMatrix()
     
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I
     
     #T = ml.mat([0, 0, 0]).T
     #R = ml.mat([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).T
     if (fixed_bif >= 0) and (moving_bif >= 0):
         T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     
     # Resample the moving contour
     moving_points = movingData.getPointSet('Contour').copy()
     moving_center = movingData.getPointSet('Centerline').copy()
     #new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T)
     new_trans_points, result_center_points = moving_points, moving_center
     result_center_points[:, :3] = util.applyTransformForPoints(result_center_points[:, :3], moving_res, fixed_res, R, T, ml.zeros([3, 1], dtype = npy.float32))
     new_trans_points[:, :3] = util.applyTransformForPoints(new_trans_points[:, :3], moving_res, fixed_res, R, T, ml.zeros([3, 1], dtype = npy.float32))
     T = -T
     T = R * T
     
     transform = sitk.Transform(3, sitk.sitkAffine)
     para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
     transform.SetParameters(para)
     
     movingImage = movingData.getSimpleITKImage()
     fixedImage = fixedData.getSimpleITKImage()
     resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32)
     
     if isTime:
         return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + [0, 0, 0], time2 - time1
     return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + [0, 0, 0]
Esempio n. 42
0
def createMorph(selectedImages,selectedPMs):
  """
  Translates and rotate the bitmaps based on the shapedefining landmarks (selectedPMs)
  of the associated image to the target image (first image).
  Morphs the result so that the bitmap overlay on the first image is valid for the first image.  
  """
  
  #save the temporary results here later:
  os_temp_path = tempfile.gettempdir()
  
  #get the measurements for the first image (our targets)
  mainImage = OriginalImage.objects.all().get(id=selectedImages[0])
  potentialids = [] 
  #now get the associated measurements
  measures = Measurement.objects.all().filter(id__in=selectedPMs[0]).filter(mogelijkemeting__shapedefining=True)
  measures = [j for j in measures]
  measures.sort(key=lambda x: x.mogelijkemeting.name)
   
  coordsx = []
  coordsy = []
  for k, measurement in enumerate(measures):
    coordsx.append(float(measurement.x))
    coordsy.append(float(measurement.y))
    potentialids.append(measurement.mogelijkemeting.id)
  r1 = vtk.vtkJPEGReader()
  r1.SetFileName(settings.DATADIR + mainImage.id + ".jpg")
  r1.Update() 

  # flip y coord (VTK has opposite convention), create 3-d coords (z=0)
  ydim = r1.GetOutput().GetDimensions()[1]
  coords = [(x, ydim - y, 0) for (x,y) in zip(coordsx, coordsy)]
  
  # convert everything to vtkPoints
  lmt = vtk.vtkPoints()
  lmt.SetNumberOfPoints(len(coords))
  for i, coord in enumerate(coords):
    lmt.SetPoint(i,coord)
  
  #The target is clear, let's get to work, get the source images...
  images = []
  #we don't need the first image or its measures anymore, because they don't need to be transformed or morphed
  selectedImages.pop(0)
  selectedPMs.pop(0)
  for id in selectedImages:
    images.append(OriginalImage.objects.all().get(id=id))

  transformations = []
  morphtransformations = []
  
  #Create a new database object for the target image to associate the bitmaps with
  img = OriginalImage(project=mainImage.project, name='MorphedImage')
  img.save()
  imp = Image.open(settings.DATADIR + mainImage.id + '.jpg')
  imp.save(settings.DATADIR + img.id + '.jpg', 'JPEG')  
  orig_bitmaps = Bitmap.objects.all().filter(image=mainImage)
  
  for bm in orig_bitmaps:
    #store bitmaps of mainImage as sub of img
    bitmap = Bitmap(project=img.project, name='warpedbitmap', image=img, 
                      mogelijkemeting=bm.mogelijkemeting, imagewidth=bm.imagewidth, 
                      imageheight=bm.imageheight, minx=bm.minx, miny=bm.miny, maxx=bm.maxx, maxy=bm.maxy)
    bitmap.save()
      
    bitmap_image = Image.open(settings.DATADIR + bm.id + '.gif')
    bitmap_image = bitmap_image.convert("RGBA")
    bitmap_image.save(settings.DATADIR + bitmap.id + '.gif', transparency=0)
    
  #now get the other images and perform our transformations
  for i in range(len(images)):
    measures = Measurement.objects.all().filter(id__in=selectedPMs[i]).filter(mogelijkemeting__shapedefining=True)#get measurements
    measures = [j for j in measures]
    measures.sort(key=lambda x: x.mogelijkemeting.name)
    coordsx = []
    coordsy = []    
    for k, measurement in enumerate(measures):
      coordsx.append(float(measurement.x))
      coordsy.append(float(measurement.y))
      if potentialids[k] != measurement.mogelijkemeting.id: #the potentialmeasurements do not match up to the ones in the target image
        return img, 0
    r = vtk.vtkJPEGReader()
    r.SetFileName(settings.DATADIR + images[i].id + ".jpg")
    r.Update()

    ydim = r.GetOutput().GetDimensions()[1]
    coordso = [(x, ydim - y, 0) for (x,y) in zip(coordsx, coordsy)]
    lms = vtk.vtkPoints()
    lms.SetNumberOfPoints(len(coordso))
    for k, coord in enumerate(coordso):
      lms.SetPoint(k,coord)

    transformation = vtk.vtkLandmarkTransform()
    transformation.SetTargetLandmarks(lmt)  
    lmt.Modified()
    transformation.SetSourceLandmarks(lms)
    lms.Modified()
    #size matters, so set the mode to Rigid Body (also known as do not scale please)
    transformation.SetModeToRigidBody()
    transformation.Inverse()
    transformation.Update()
    out = vtk.vtkPoints()#this will be the source of our morph transform
    transformation.TransformPoints(lms,out)
    transformations.append(transformation)
    ir = vtk.vtkImageReslice()
    # we're not using linear, because we want to improve the quality of the bitmaps
    ir.SetInterpolationModeToNearestNeighbor()
    ir.SetResliceTransform(transformation)
    ir.SetInput(r.GetOutput())
    ir.SetInformationInput(r1.GetOutput())
    w = vtk.vtkJPEGWriter()
    w.SetFileName(os_temp_path+'/translated'+images[i].id+'.jpg')
    w.SetInput(ir.GetOutput())
    w.Write()
    r2 = vtk.vtkJPEGReader()
    r2.SetFileName(os_temp_path+'/translated'+images[i].id+'.jpg')
    r2.Update()  
 
    # the mighty morphing ThinPlateSplineTransform
    morphtransform = vtk.vtkThinPlateSplineTransform()
    morphtransform.SetBasisToR2LogR()
    morphtransform.SetSourceLandmarks(lms)
    lms.Modified()
    morphtransform.SetTargetLandmarks(lmt)
    lmt.Modified()
    morphtransform.Inverse()
    morphtransform.Update()
    morphtransformations.append(morphtransform)

    #ir.SetInput(r2.GetOutput())
    #ir.SetInformationInput(r1.GetOutput())
    
    bitmaps = Bitmap.objects.all().filter(image=images[i])
    
    #now perform the total transformation on all bitmaps
    for bm in bitmaps:
      location = settings.DATADIR + bm.id + ".gif"
      im = Image.open(location)
      im = im.convert("RGBA")
      im.save(settings.DATADIR + bm.id + ".png", "PNG")

      r3 = vtk.vtkPNGReader()
      r3.SetFileName(settings.DATADIR + bm.id + '.png')
      r3.Update()
      
      ir2 = vtk.vtkImageReslice()
      ir2.SetInterpolationModeToNearestNeighbor()
      ir2.SetResliceTransform(morphtransform)
      ir2.SetInput(r3.GetOutput())
      ir2.SetInformationInput(r2.GetOutput())
      
      w3 = vtk.vtkPNGWriter()
      w3.SetFileName(os_temp_path+'/morphed'+bm.id+'.png')
      w3.SetInput(ir2.GetOutput())
      w3.Write()
      
      bitmap = Bitmap(project=img.project, name='warpedbitmap', image=img, 
                      mogelijkemeting=bm.mogelijkemeting, imagewidth=bm.imagewidth, 
                      imageheight=bm.imageheight, minx=bm.minx, miny=bm.miny, maxx=bm.maxx, maxy=bm.maxy)
      bitmap.save()
      
      im = Image.open(os_temp_path+'/morphed'+bm.id+'.png')
      im = im.convert("RGBA")
      im.save(settings.DATADIR + bitmap.id + '.gif', transparency=0)
      

  return img, 1
LandmarkDistanceList = np.array(LandmarkDistanceList)
SubjectList = np.array(SubjectList)
LabelList = np.array(LabelList)

distArrInd = LandmarkDistanceList.argsort()
sortedDistList = LandmarkDistanceList[distArrInd[::-1]]
sortedSubjectList = SubjectList[distArrInd[::-1]]
sortedLabelList = LabelList[distArrInd[::-1]]
sortedCMRepSurfaceList = CMRepSurfaceList[distArrInd[::-1]]

cntFlip = 0

for i in range(len(sortedCMRepSurfaceList)):
    dataTest = sortedCMRepSurfaceList[i]

    landmarktransformCheck = vtk.vtkLandmarkTransform()
    landmarktransformCheck.SetSourceLandmarks(dataTest.GetPoints())
    landmarktransformCheck.SetTargetLandmarks(mu.GetPoints())
    landmarktransformCheck.SetModeToRigidBody()
    landmarktransformCheck.Update()

    transformCheck = vtk.vtkTransform()
    transformCheck.SetMatrix(landmarktransformCheck.GetMatrix())
    transformCheck.Update()

    if np.abs(transformCheck.GetOrientation()[0]) >= 90:
        print(sortedSubjectList[i])
        cntFlip += 1
    if np.abs(transformCheck.GetOrientation()[1]) >= 90:
        print(sortedSubjectList[i])
        cntFlip += 1