VTK/Examples/Cxx/PolyData/ProcrustesAlignmentFilter

From KitwarePublic
< VTK‎ | Examples‎ | Cxx
Jump to navigationJump to search
VTK Examples Baseline PolyData TestProcrustesAlignmentFilter.png

This example aligns three objects (deformed spheres) using the Procrustes algorithm. The original shapes are shown on the left. The alignment using a rigid transform is shown in the middle, and the alignment using a similarity transform is shown on the right.

ProcrustesAlignmentFilter.cxx

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkPointSet.h>
#include <vtkPolyData.h>
#include <vtkLandmarkTransform.h>
#include <vtkCamera.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkProcrustesAlignmentFilter.h>
#if VTK_MAJOR_VERSION > 5
#include <vtkMultiBlockDataSet.h>
#include <vtkMultiBlockDataGroupFilter.h>
#endif 
int main(int, char *[])
{
  //create a sphere
  vtkSmartPointer<vtkSphereSource> sphereSource = 
      vtkSmartPointer<vtkSphereSource>::New();
 
  // make two copies of the shape and distort them a little
  vtkSmartPointer<vtkTransform> transform1 = 
    vtkSmartPointer<vtkTransform>::New();
  transform1->Translate(0.2, 0.1, 0.3);
  transform1->Scale(1.3, 1.1, 0.8);
 
  vtkSmartPointer<vtkTransform> transform2 = 
    vtkSmartPointer<vtkTransform> ::New();
  transform2->Translate(0.3, 0.7, 0.1);
  transform2->Scale(1.0, 0.1, 1.8);
 
  vtkSmartPointer<vtkTransformPolyDataFilter> transformer1 = 
          vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformer1->SetInputConnection(sphereSource->GetOutputPort());
  transformer1->SetTransform(transform1);
 
  vtkSmartPointer<vtkTransformPolyDataFilter> transformer2 = 
          vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformer2->SetInputConnection(sphereSource->GetOutputPort());
  transformer2->SetTransform(transform2);
 
  // map these three shapes into the first renderer
  vtkSmartPointer<vtkPolyDataMapper> map1a = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  map1a->SetInputConnection(sphereSource->GetOutputPort());
 
  vtkSmartPointer<vtkActor> Actor1a = 
    vtkSmartPointer<vtkActor> ::New();
  Actor1a->SetMapper(map1a);
  Actor1a->GetProperty()->SetDiffuseColor(1.0000, 0.3882, 0.2784);
 
  vtkSmartPointer<vtkPolyDataMapper> map1b = 
    vtkSmartPointer<vtkPolyDataMapper> ::New();
  map1b->SetInputConnection(transformer1->GetOutputPort());
 
  vtkSmartPointer<vtkActor> Actor1b = 
    vtkSmartPointer<vtkActor> ::New();
  Actor1b->SetMapper(map1b);
  Actor1b->GetProperty()->SetDiffuseColor(0.3882, 1.0000, 0.2784);
 
  vtkSmartPointer<vtkPolyDataMapper> map1c = 
      vtkSmartPointer<vtkPolyDataMapper>::New();
  map1c->SetInputConnection(transformer2->GetOutputPort());
  vtkSmartPointer<vtkActor> Actor1c = 
      vtkSmartPointer<vtkActor>::New();
  Actor1c->SetMapper(map1c);
  Actor1c->GetProperty()->SetDiffuseColor(0.3882, 0.2784, 1.0000);
 
  // align the shapes using Procrustes (using SetModeToRigidBody) 
  vtkSmartPointer<vtkProcrustesAlignmentFilter> procrustes1 = 
          vtkSmartPointer<vtkProcrustesAlignmentFilter>::New();
#if VTK_MAJOR_VERSION <=5 
  procrustes1->SetNumberOfInputs(3);
  procrustes1->SetInputConnection(sphereSource->GetOutputPort());
  procrustes1->AddInputConnection(transformer1->GetOutputPort());
  procrustes1->AddInputConnection(transformer2->GetOutputPort());
#else
  vtkSmartPointer<vtkMultiBlockDataGroupFilter> group =
    vtkSmartPointer<vtkMultiBlockDataGroupFilter>::New();
  group->AddInputConnection(sphereSource->GetOutputPort());
  group->AddInputConnection(transformer1->GetOutputPort());
  group->AddInputConnection(transformer2->GetOutputPort());
  procrustes1->SetInputConnection(group->GetOutputPort());
#endif
  procrustes1->GetLandmarkTransform()->SetModeToRigidBody();
 
  // map the aligned shapes into the second renderer
  vtkSmartPointer<vtkDataSetMapper> map2a = 
      vtkSmartPointer<vtkDataSetMapper>::New();
 
#if VTK_MAJOR_VERSION <= 5
  map2a->SetInputConnection(procrustes1->GetOutputPort(0));
#else
  procrustes1->Update();
  map2a->SetInputData(vtkDataSet::SafeDownCast(procrustes1->GetOutput()->GetBlock(0)));
#endif
  vtkSmartPointer<vtkActor> Actor2a = 
      vtkSmartPointer<vtkActor>::New();
  Actor2a->SetMapper(map2a);
  Actor2a->GetProperty()->SetDiffuseColor(1.0000, 0.3882, 0.2784);
 
  vtkSmartPointer<vtkDataSetMapper> map2b =
      vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  map2b->SetInputConnection(procrustes1->GetOutputPort(1));
#else
  procrustes1->Update();
  map2b->SetInputData(vtkDataSet::SafeDownCast(procrustes1->GetOutput()->GetBlock(1)));
#endif
  vtkSmartPointer<vtkActor> Actor2b =
    vtkSmartPointer<vtkActor>::New();
  Actor2b->SetMapper(map2b);
  Actor2b->GetProperty()->SetDiffuseColor(0.3882, 1.0000, 0.2784);
 
  vtkSmartPointer<vtkDataSetMapper> map2c =
      vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  map2c->SetInputConnection(procrustes1->GetOutputPort(2));
#else
  procrustes1->Update();
  map2c->SetInputData(vtkDataSet::SafeDownCast(procrustes1->GetOutput()->GetBlock(2)));
#endif
  vtkSmartPointer<vtkActor> Actor2c = 
      vtkSmartPointer<vtkActor>::New();
  Actor2c->SetMapper(map2c);
  Actor2c->GetProperty()->SetDiffuseColor(0.3882, 0.2784, 1.0000);
 
  //align the shapes using Procrustes (using SetModeToSimilarity (default))
  vtkSmartPointer<vtkProcrustesAlignmentFilter> procrustes2 =
      vtkSmartPointer<vtkProcrustesAlignmentFilter>::New();
#if VTK_MAJOR_VERSION <=5 
  procrustes2->SetNumberOfInputs(3);
  procrustes2->SetInputConnection(sphereSource->GetOutputPort());
  procrustes2->AddInputConnection(transformer1->GetOutputPort());
  procrustes2->AddInputConnection(transformer2->GetOutputPort());
#else
  procrustes2->SetInputConnection(group->GetOutputPort());
#endif
 
  // map the aligned shapes into the third renderer
  vtkSmartPointer<vtkDataSetMapper> map3a =
      vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  map3a->SetInputConnection(procrustes2->GetOutputPort(0));
#else
  procrustes2->Update();
  map3a->SetInputData(vtkDataSet::SafeDownCast(procrustes2->GetOutput()->GetBlock(0)));
#endif
  vtkSmartPointer<vtkActor> Actor3a =
      vtkSmartPointer<vtkActor>::New();
  Actor3a->SetMapper(map3a);
  Actor3a->GetProperty()->SetDiffuseColor(1.0000, 0.3882, 0.2784);
 
  vtkSmartPointer<vtkDataSetMapper> map3b =
      vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  map3b->SetInputConnection(procrustes2->GetOutputPort(1));
#else
  procrustes2->Update();
  map3b->SetInputData(vtkDataSet::SafeDownCast(procrustes2->GetOutput()->GetBlock(1)));
#endif
  vtkSmartPointer<vtkActor> Actor3b =
      vtkSmartPointer<vtkActor>::New();
  Actor3b->SetMapper(map3b);
  Actor3b->GetProperty()->SetDiffuseColor(0.3882, 1.0000, 0.2784);
 
  vtkSmartPointer<vtkDataSetMapper> map3c =
      vtkSmartPointer<vtkDataSetMapper>::New();
#if VTK_MAJOR_VERSION <= 5
  map3c->SetInputConnection(procrustes2->GetOutputPort(2));
#else
  procrustes2->Update();
  map3c->SetInputData(vtkDataSet::SafeDownCast(procrustes2->GetOutput()->GetBlock(2)));
#endif
  vtkSmartPointer<vtkActor> Actor3c =
      vtkSmartPointer<vtkActor>::New();
  Actor3c->SetMapper(map3c);
  Actor3c->GetProperty()->SetDiffuseColor(0.3882, 0.2784, 1.0000);
 
  // Create the RenderWindow and its three Renderers
  vtkSmartPointer<vtkRenderer> ren1 =
      vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderer> ren2 =
      vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderer> ren3 =
      vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renWin =
      vtkSmartPointer<vtkRenderWindow>::New();
  renWin->AddRenderer(ren1);
  renWin->AddRenderer(ren2);
  renWin->AddRenderer(ren3);
  renWin->SetSize(300, 100);
  vtkSmartPointer<vtkRenderWindowInteractor> interactor =
      vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renWin);
 
  // Add the actors to the renderer
  ren1->AddActor(Actor1a);
  ren1->AddActor(Actor1b);
  ren1->AddActor(Actor1c);
 
  ren2->AddActor(Actor2a);
  ren2->AddActor(Actor2b);
  ren2->AddActor(Actor2c);
 
  ren3->AddActor(Actor3a);
  ren3->AddActor(Actor3b);
  ren3->AddActor(Actor3c);
 
  // set the properties of the renderers
 
  ren1->SetBackground(1, 1, 1);
  ren1->SetViewport(0.0, 0.0, 0.33, 1.0);
  ren1->ResetCamera();
  ren1->GetActiveCamera()->SetPosition(1, -1, 0);
  ren1->ResetCamera();
 
  ren2->SetBackground(1, 1, 1);
  ren2->SetViewport(0.33, 0.0, 0.66, 1.0);
  ren2->ResetCamera();
  ren2->GetActiveCamera()->SetPosition(1, -1, 0);
  ren2->ResetCamera();
 
  ren3->SetBackground(1, 1, 1);
  ren3->SetViewport(0.66, 0.0, 1.0, 1.0);
  ren3->ResetCamera();
  ren3->GetActiveCamera()->SetPosition(1, -1, 0);
  ren3->ResetCamera();
 
  renWin->Render();
  interactor->Start();
 
  return EXIT_SUCCESS;
}

Please try the new VTKExamples website.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

PROJECT(ProcrustesAlignmentFilter)

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

add_executable(ProcrustesAlignmentFilter MACOSX_BUNDLE ProcrustesAlignmentFilter.cxx)

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

Download and Build ProcrustesAlignmentFilter

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

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

cd ProcrustesAlignmentFilter/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:

./ProcrustesAlignmentFilter

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.