[vtkusers] Help with vtkIterativeClosestPointTransform

Mark K. Batesole, DDS, MS mbatesole at yahoo.com
Thu Jun 24 23:04:55 EDT 2010


Hi Everyone, 

Thanks ahead of time for your help.  Here's my situation: I'm really struggling getting the vtkIterativeClosestPointTransform to work as I expect. What I'd like to do, is load two polydata sets that have multiple regions. The two sets differ just slightly, but there is a region that is the reference (anchor) that remains unchanged between the sets. I'm trying to manually choose that reference in each data set and then find the transformation between the two references and then transfer the whole data accordingly. This way the references line up although the remaining data may not.  

I've created two different wxVTKRenderWindowInteractors to load each data set, one in the right window interactor, and one in the left. (Currently I'm just loading the same dataset into each window as I don't have another dataset as of yet.) Then I pick a particular actor in one wxVTKRenderWindowInteractor and pick another in the other wxVTKRenderWindowInteractor. These two actors are supposed to me my anchors or reference points. When two have been chosen I hit the anchor button in the toolbar which finds the transformation matrix from the one actor's dataset to the other. Then for debugging purposes draws another actor of the transformed dataset in the right window. (you have to interact with the mouse for the window to be redrawn... I haven't figured this one out yet)

What I expect to see is the new actor in the right window drawn over the actor that was picked in the left window. But instead the actor is drawn completely in the wrong place. Obviously I'm making a mistake, but I have no idea where. I've attached an image to hopefully make things more clear.

Please be nice. I'm still in the "figuring-it-out" stage so forgive the elementary code.... my training is teeth not computers ;)


<code  follows >

import vtk
from vtk.wx.wxVTKRenderWindowInteractor import *
# every wx app needs an app
app = wx.PySimpleApp()

# create the top-level frame, sizer and wxVTKRWI
frame = wx.Frame(None, -1, "wxVTKRenderWindowInteractor", size=(850,400))
widgetLeft = wxVTKRenderWindowInteractor(frame, -1)
widgetRight = wxVTKRenderWindowInteractor(frame, -1)

toolbar = frame.CreateToolBar()
#toolbar = wx.ToolBar(frame, -1)
toolbar.AddLabelTool(wx.ID_ANY, 'Test', wx.Bitmap('../icons/anchor.png'))
toolbar.SetToolTip(wx.ToolTip("click to hide"))
toolbar.Realize()

sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(widgetLeft, 1, wx.EXPAND)
sizer.Add(widgetRight, 1, wx.EXPAND)
#sizer.Add(toolbar)
frame.SetSizer(sizer)
frame.Layout()

widgetLeft.Enable(1)
widgetRight.Enable(1)
widgetLeft.AddObserver("ExitEvent", lambda o,e,f=frame: f.Close())
widgetRight.AddObserver("ExitEvent", lambda o,e,f=frame: f.Close())

renLeft = vtk.vtkRenderer()
widgetLeft.GetRenderWindow().AddRenderer(renLeft)

renRight = vtk.vtkRenderer()
widgetRight.GetRenderWindow().AddRenderer(renRight)

styleLeft = vtk.vtkInteractorStyleTrackballCamera()
styleRight = vtk.vtkInteractorStyleTrackballCamera()

widgetLeft.SetInteractorStyle(styleLeft)
widgetRight.SetInteractorStyle(styleRight)

pickerLeft = widgetLeft.GetPicker()
pickerRight = widgetRight.GetPicker()

rightActor = None
leftActor= None


def collectActorLeft(object, event):
    global leftActor
    leftActor = pickerLeft.GetActor()
    if leftActor == None:
        print "Try Again"
    else:
        print "Left Anchor Found", pickerLeft.GetActor().GetCenter()
        #pickerLeft.GetActor().SetOrigin(pickerLeft.GetActor().GetCenter())
    
def collectActorRight(object, event):
    global rightActor
    rightActor = pickerRight.GetActor()
    if rightActor == None:
        print "Try Again"
    else:
        
        print "Right Anchor Found", pickerRight.GetActor().GetCenter()
        #pickerRight.GetActor().SetOrigin(pickerRight.GetActor().GetCenter())

def processAnchors(event):
    if ((rightActor == None) or (leftActor == None)):
        print "Try again sucker"
    else:
        leftMapper = leftActor.GetMapper()
        rightMapper = rightActor.GetMapper()
        
        leftData = leftMapper.GetInput()
        rightData = rightMapper.GetInput()
        
        transformAnchors(leftData, rightData)
        
        
def transformAnchors(fixed, moving):
    ## Setup Iterative Closest Point Transform
    icpTransform = vtk.vtkIterativeClosestPointTransform()
    icpTransform.SetSource(moving)
    icpTransform.SetTarget(fixed)
    icpTransform.StartByMatchingCentroidsOn()
    icpTransform.GetLandmarkTransform().SetModeToRigidBody()
    icpTransform.SetMaximumNumberOfIterations(10000)
    icpTransform.CheckMeanDistanceOn()
    icpTransform.SetMaximumMeanDistance(.01)
    icpTransform.SetMeanDistanceModeToRMS()
    icpTransform.SetMaximumNumberOfLandmarks(1000)
    icpTransform.Modified()
    icpTransform.Update()

    print "Transformation Matrix Created"
    print "Transformation Matrix", icpTransform.GetLandmarkTransform().GetMatrix()
    
    ## Perform the transform
    resampleMeshFilter = vtk.vtkTransformPolyDataFilter()
    #resampleMeshFilter.SetInput( fixed )
    resampleMeshFilter.SetInput( moving )
    #resampleMeshFilter.SetInput(reader.GetOutput())
    resampleMeshFilter.SetTransform( icpTransform )
    resampleMeshFilter.Update()
    print "Transformation Completed"
    
    ## View the transformation
    meshMapper = vtk.vtkPolyDataMapper()
    #meshMapper.SetInput(moving)
    meshMapper.SetInput(resampleMeshFilter.GetOutput())
    meshActor = vtk.vtkActor()
    meshActor.SetMapper(meshMapper)
    meshActor.GetProperty().SetColor(1,0,0);
    
    renRight.AddActor(meshActor)
    renRight.ResetCamera()

pickerLeft.AddObserver("EndPickEvent", collectActorLeft )
pickerRight.AddObserver("EndPickEvent", collectActorRight )

def splitParts(polydata):

    conn = vtk.vtkPolyDataConnectivityFilter()
    conn.SetInput(polydata)
    conn.SetExtractionModeToAllRegions()
    conn.Update()

    nregions = conn.GetNumberOfExtractedRegions()

    conn.SetExtractionModeToSpecifiedRegions()
    conn.Update()

    polydata_collection = []

    for region in xrange(nregions):
        conn.InitializeSpecifiedRegionList()
        conn.AddSpecifiedRegion(region)
        conn.Update()

        p = vtk.vtkPolyData()
        p.DeepCopy(conn.GetOutput())
        p.Update()

        polydata_collection.append(p)

    return polydata_collection


reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName('/newModel.vtp') 
reader.Update();

polydataCollection = splitParts(reader.GetOutput())
actorCollection = []    

for item in xrange(len(polydataCollection)):
    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInput(polydataCollection[item])
    #mapperCollection.append(mapper)
    
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    #print actor.GetPosition()
    actorCollection.append(actor)
    
    #actorCollection.append(actor)
    #renLeft.AddActor(actor)
    #renRight.AddActor(actor)
    #actor.SetPosition(actor.GetCenter())
    
for actor in xrange(len(actorCollection)):
    #print actorCollection[actor].GetPosition()
    renLeft.AddActor(actorCollection[actor])
    renRight.AddActor(actorCollection[actor])

frame.Bind(wx.EVT_TOOL, processAnchors, id=-1)

# show the window
frame.Show()
app.MainLoop()


      
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ICP.jpg
Type: image/jpeg
Size: 13049 bytes
Desc: not available
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100624/acab2f89/attachment.jpg>


More information about the vtkusers mailing list