3D Transformation using VTK and Paraview

Using Paraview’s python shell and VTK, I’m trying to perform a complex transformation on a series of specific 3D facial landmark points (about 10-15 points). These points have been separately collected and are stored in an excel sheet. Essentially, they can represented as matrices (x-y-z coordinates). I’ve been trying to use VTK’s special classes like AbstractTransform() or HomogenousTransform(), but I’m not sure how to write out the syntax and make sure they apply to the particular points. To provide some more context, I’m taking a 3D face (represented as polydata in Paraview) and trying to make that face look slightly different. Thus, this transformation has to be applied to the specific set of points.

3 questions:

  1. Is there a way to multiple these 3D points by a transformation matrix?
  2. What’s the right way to go about using these VTK classes and have the transformation apply to only a specific set of points, but not all of them?
  3. Is there a smarter way to go about what i’m trying to accomplish?

This is very simple to do in 3D Slicer - free, open-source application, similarly to ParaView, but specifically developed for biomedical applications. You can load the landmark points from csv files and use “Fiducial registration wizard” module to generate a full dense deformation field. You can compute rigid, similarity or warping transform. If you have any question then you can post it on the Slicer forum.

1 Like

Hi Andras,

I appreciate your response and help. I have 2 questions:

  1. Can you clarify how to load to the landmark points from the CSV file? I.e. which steps to take?
  2. How can I translate a specific point on my 3D mesh without moving the entire image? I assume this is through Fiducial Registration Wizard, but I need help on selecting the right tools in Slicer.

Thank you very much.

You can save your landmark positions as a csv file (for convenient loading into Slicer, use .fcsv file extension). Definition of header and columns is available here. If you don’t like the header format of fcsv then you can read points as a numpy array using standard numpy or pandas fcsv readers and set the point positions into a markups fiducial node using slicer.util.updateMarkupsControlPointsFromArray().

However, I would recommend to use the new markups json file format instead.

Yes, to warp an image by specifying a set of corresponding points, you can use Fiducial Registration Wizard (inernally it uses vtkThinPlateSplineTransform). In regions that you don’t want to have any displacements, place pair of fixed and moving points at the same positions.