VTK/Examples/Boneyard/Cxx/Filters/ICPRealData

From KitwarePublic
< VTK‎ | Examples
Jump to navigationJump to search

ICPRealData.cxx

#include <vtkSmartPointer.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkIterativeClosestPointTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkLandmarkTransform.h>
#include <vtkMath.h>
#include <vtkMatrix4x4.h>
#include <vtkXMLPolyDataWriter.h>
#include <vtkXMLPolyDataReader.h>

int main(int argc, char *argv[])
{
  // Ensure a filename was specified
  if ( argc != 4 )
    {
    std::cout << "Required arguments: source.vtp target.vtp output.vtp" << std::endl;
    return EXIT_FAILURE;
    }

  std::string strSource = argv[1];
  std::string strTarget = argv[2];
  std::string strOutput = argv[3];
  vtkSmartPointer<vtkXMLPolyDataReader> sourceReader = 
    vtkSmartPointer<vtkXMLPolyDataReader>::New();
  sourceReader->SetFileName(strSource.c_str());
  sourceReader->Update();
  
  vtkSmartPointer<vtkXMLPolyDataReader> targetReader = 
    vtkSmartPointer<vtkXMLPolyDataReader>::New();
  targetReader->SetFileName(strTarget.c_str());
  targetReader->Update();
    
  //setup ICP transform
  vtkSmartPointer<vtkIterativeClosestPointTransform> icp = 
    vtkSmartPointer<vtkIterativeClosestPointTransform>::New();
  icp->SetSource(sourceReader->GetOutput());
  icp->SetTarget(targetReader->GetOutput());
  icp->GetLandmarkTransform()->SetModeToRigidBody();
  //icp->DebugOn();
  icp->SetMaximumNumberOfIterations(20);
  icp->StartByMatchingCentroidsOn();
  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::cout;
  
  //transform the source points by the ICP solution
  vtkSmartPointer<vtkTransformPolyDataFilter> iCPTransFilter = 
    vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  iCPTransFilter->SetInput(sourceReader->GetOutput());
  iCPTransFilter->SetTransform(icp);
  iCPTransFilter->Update();
  
  vtkSmartPointer<vtkPolyData> resultPolydata = iCPTransFilter->GetOutput();
  vtkSmartPointer<vtkXMLPolyDataWriter> writer = 
    vtkSmartPointer<vtkXMLPolyDataWriter>::New();
  writer->SetFileName(strOutput.c_str());
  writer->SetInput(resultPolydata);
  writer->Write();
  
  /*
  //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;
  */
  
  return EXIT_SUCCESS;
}

Please try the new VTKExamples website.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

PROJECT(ICPRealData)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

add_executable(ICPRealData MACOSX_BUNDLE ICPRealData.cxx)

if(VTK_LIBRARIES)
  target_link_libraries(ICPRealData ${VTK_LIBRARIES})
else()
  target_link_libraries(ICPRealData vtkHybrid vtkWidgets)
endif()

Download and Build ICPRealData

Click here to download ICPRealData. and its CMakeLists.txt file.

Once the tarball ICPRealData.tar has been downloaded and extracted,

cd ICPRealData/build 
  • If VTK is installed:
cmake ..
  • If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..

Build the project:

make

and run it:

./ICPRealData

WINDOWS USERS PLEASE NOTE: Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.