How to register two models using Python?

I went to calculater a transform between two models.
Then I searched and found such module :https://github.com/SlicerIGT/SlicerIGT/blob/master/ModelRegistration/ModelRegistration.py

but when I run this code in python cli, I get an error just like the post title.

def MR(inputSourceModel, inputTargetModel, outputSourceToTargetTransform, transformType=0, numIterations=100 ):    
    
  delayDisplay('Running iterative closest point registration')
  
  icpTransform = vtk.vtkIterativeClosestPointTransform()
  icpTransform.SetSource(inputSourceModel.GetPolyData() )
  icpTransform.SetTarget(inputTargetModel.GetPolyData() )
  icpTransform.GetLandmarkTransform().SetModeToRigidBody()
  if transformType == 1:
    icpTransform.GetLandmarkTransform().SetModeToSimilarity()
  if transformType == 2:
    icpTransform.GetLandmarkTransform().SetModeToAffine()
  icpTransform.SetMaximumNumberOfIterations( numIterations )
  icpTransform.Modified()
  icpTransform.Update()
  
  outputSourceToTargetTransform.SetAndObserveMatrixTransformToParent(vtk.vtkMatrix4x4())
          
  if slicer.app.majorVersion >= 5 or (slicer.app.majorVersion >= 4 and slicer.app.minorVersion >= 11):
    outputSourceToTargetTransform.AddNodeReferenceID(slicer.vtkMRMLTransformNode.GetMovingNodeReferenceRole(), inputSourceModel.GetID())
    outputSourceToTargetTransform.AddNodeReferenceID(slicer.vtkMRMLTransformNode.GetFixedNodeReferenceRole(), inputTargetModel.GetID())
  
  return True


inputSourceModel = getNode("a")
inputTargetModel = getNode("b")
 
MR(inputSourceModel, inputTargetModel, "aTob", transformType=0, numIterations=100)

If I went to calculate a transform between two models, and which code is right?

Thanks.

A transform node was expected and you passed a string instead. You don’t need to copy-paste code from modules but you can use module logic from another module or from the Python console. For example, this should do everything you need:

# Get input and output nodes
sourceModel = getNode('Segment_1')
targetModel = getNode('Segment_2')
sourceToTargetTransform = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLLinearTransformNode")

# Register
import ModelRegistration
mrLogic = ModelRegistration.ModelRegistrationLogic()
mrLogic.run(sourceModel, targetModel, sourceToTargetTransform)

# Show results
sourceModel.SetAndObserveTransformNodeID(sourceToTargetTransform.GetID())
sourceModel.GetDisplayNode().SetOpacity(0.5)
targetModel.GetDisplayNode().SetOpacity(0.5)

If you need non-linear (warping) registration of nodes then you can use SegmentRegistration extension.

1 Like