[vtkusers] Iterative Closest Point Transform - problem

z.adva adva.zair at mail.huji.ac.il
Sun Apr 14 11:00:23 EDT 2013


Hi,

I'm trying to perform registration on two PolyData objects, but the
resulting transformation is far from  being the solution. 
I used the code from 
http://www.vtk.org/Wiki/VTK/Examples/Cxx/Filtering/IterativeClosestPointsTransform 
without much changes.

For debug, I simply ran the ICP with source=target and expected to get the
identity matrix, but I got different matrix, and the transformation was bad.

When the ICP's debug-flag was on, it said that after about 29 iterations the
mean-distance was 
very small (~10^-6), although when I viewed the solution it seems not close
at all. 
 
I started with fractured bone-object and then extracted its fracture-surface
in order to match the two surfaces. When I ran the ICP on one of the
original bones it worked well ( the output was the identity matrix ) so the
odd behavior is only at the extracted PolyData.  

my code:

    // Setup ICP transform
    vtkSmartPointer<vtkIterativeClosestPointTransform> icp = 
        vtkSmartPointer<vtkIterativeClosestPointTransform>::New();
    icp->SetSource(target);
    icp->SetTarget(target);
    //icp->DebugOn();
    //icp->StartByMatchingCentroidsOn();
    icp->SetMaximumNumberOfIterations(29);
    icp->SetMaximumNumberOfLandmarks(target->GetNumberOfPoints());
    icp->SetCheckMeanDistance(1);
    icp->SetMaximumMeanDistance(0.0000001);
    icp->GetLandmarkTransform()->SetModeToRigidBody();
    icp->Modified();
    icp->Update();
    
 
    // Get the resulting transformation matrix (this matrix takes the source
points to the target points)
    vtkSmartPointer<vtkMatrix4x4> m = icp->GetMatrix();
    std::cout << "The resulting matrix is: " << *m << std::endl;
   
    
 
    // Transform the source points by the ICP solution
    vtkSmartPointer<vtkTransformPolyDataFilter> icpTransformFilter =
        vtkSmartPointer<vtkTransformPolyDataFilter>::New();
#if VTK_MAJOR_VERSION <= 5
    icpTransformFilter->SetInput(target);
#else
    icpTransformFilter->SetInputData(target);
#endif
    icpTransformFilter->SetTransform( icp );
    icpTransformFilter->Update();
 
    /*
    // If you need to take the target points to the source points, the
matrix is:
    icp->Inverse();
    vtkSmartPointer<vtkMatrix4x4> minv = icp->GetMatrix();
    std::cout << "The resulting inverse matrix is: " << *minv << std::cout;
    */
    vtkSmartPointer<vtkPolyData> output = 
vtkSmartPointer<vtkPolyData>::New();
    output = icpTransformFilter->GetOutput();
    vtkSmartPointer<vtkPolyDataWriter> writer = 
vtkSmartPointer<vtkPolyDataWriter>::New();
    writer->SetFileName( fileName );
    writer->SetInput( output );
    writer->Update();


One more worth mentioned remark is that in the process of extracting the
surface I get in the pipeline 
vtkUnstructuredGrid object that I later convert to PolyData.. 

any thoughts?

Thank you,
Adva



--
View this message in context: http://vtk.1045678.n5.nabble.com/Iterative-Closest-Point-Transform-problem-tp5720040.html
Sent from the VTK - Users mailing list archive at Nabble.com.



More information about the vtkusers mailing list