Menu

Applying transformations to point data sets

Tristan
2012-05-11
2012-12-31
  • Tristan

    Tristan - 2012-05-11

    Hi,

    I've had trouble with applying transformations to point data sets in the past, and I just wrote my own code to do simple 2D affine transforms, but I need to use the 3D and warping transforms of ANTS which requires I use the ANTS programs.

    I believe I need WarpLabeledPointSetFileMultiTransform or WarpVTKPolyDataMultiTransform to apply ANTS transforms to point sets. I followed the instructions to build ANTS from:

    http://brianavants.wordpress.com/2012/04/13/updated-ants-compile-instructions-april-12-2012/

    and everthing built ok, but neither WarpLabeledPointSetFileMultiTransform or WarpVTKPolyDataMultiTransform are present.  Does anyone know why they didn't build?  Is there a new way to apply ANTS transformations to point datasets?

    Any help would be greatly appreciated, I really need to be able to apply the transformations to point data sets.

    Thanks,
    Tristan

     
  • Tristan

    Tristan - 2012-05-13

    Apologies I meant to post this in the help forum.

     
  • Nick Tustison

    Nick Tustison - 2012-05-14

    Hi Tristan,

    We might have stopped compiling it with the regular package since we have been undergoing quite a few changes with the ITKv4 work.  You might want to try to compile those programs separately and see if they work for your data.

    Nick

     
  • Tristan

    Tristan - 2012-05-16

    Hi Nick,

    Apologies for my ignorance, but I'm not a C/C++ guy so I'm not sure how to build these executables.  I looked through the build-ish looking files and I can't seem to find where other executables (like WarpImageMultiTransform) are built, or where these point executable files are excluded. ANTS.cmake has a bunch of add_test entries but I assume that's for post build testing.

    If someone could tell me how to do it or point me in the right direction it would be appreciated.  I'm using OSX 10.6 if that helps.

    Thanks,
    Tristan

     
  • Nick Tustison

    Nick Tustison - 2012-05-16

    Hi Tristan,

    Unfortunately I don't have the time right now to get it working but you should be able to go into the ANTS/Examples/CMakeLists.txt file and uncomment (i.e. remove the '#' character) in front of the
    two lines (789-790).  If you reconfigure and rebuild ANTS, those programs should compile.

      #  WarpVTKPolyDataMultiTransform
      #  l_WarpVTKPolyDataMultiTransform

    Nick

     
  • Anonymous

    Anonymous - 2012-05-17

    added a simple point transformation facility: 

    antsApplyTransformsToPoints

    example call:

    antsApplyTransformsToPoints -i points.csv -o points_out.csv  -t xtest1Warp.nii.gz -t xtest0Affine.mat -d 3

    points.csv  is formed like this:

    x,y,z
    100,100,0
    200,200,0
    140,150,0

    … hope it helps.

    b

     
  • Tristan

    Tristan - 2012-05-29

    Thanks for the effort in making the antsApplyTransformsToPoints program, but it seems it may have broken the build process in the trunk, at least when I run it as described in http://brianavants.wordpress.com/2012/04/13/updated-ants-compile-instructions-april-12-2012/

    I tried "git pull origin master" but it didn't help.  See the error bellow:

    Building CXX object Examples/CMakeFiles/l_antsApplyTransformsToPoints.dir/antsApplyTransformsToPoints.cxx.o
    In file included from /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.h:570,
                     from /Users/tchaplin/ANTS/ANTS/trunk/Examples/antsApplyTransforms.cxx:3:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx: In member function ‘void ants::antsRegistrationCommandIterationUpdate<TFilter>::Execute(const itk::Object*, const itk::EventObject&)’:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:50: error: ‘ConjugateGradientLineSearchOptimizerv4’ in namespace ‘itk’ does not name a type
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: ‘GradientDescentOptimizerType’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: ‘optimizer’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected type-specifier before ‘GradientDescentOptimizerType’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected `>' before ‘GradientDescentOptimizerType’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected `(' before ‘GradientDescentOptimizerType’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected primary-expression before ‘>’ token
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:52: error: expected `)' before ‘;’ token
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx: In member function ‘int ants::RegistrationHelper<VImageDimension>::DoRegistration()’:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1041: error: ‘ConjugateGradientLineSearchOptimizerv4’ in namespace ‘itk’ does not name a type
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1042: error: ‘GradientDescentOptimizerType’ has not been declared
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1042: error: expected initializer before ‘optimizer’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1043: error: ‘optimizer’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1054: error: ‘GradientDescentOptimizerType’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1054: error: template argument 1 is invalid
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1054: error: invalid type in declaration before ‘;’ token
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1055: error: ‘OptimizerCommandType’ is not a class or namespace
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1055: error: expected initializer before ‘optimizerObserver’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1056: error: ‘optimizerObserver’ was not declared in this scope
    In file included from /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.h:570,
                     from /Users/tchaplin/ANTS/ANTS/trunk/Examples/antsApplyTransformsToPoints.cxx:4:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:5:55: error: itkConjugateGradientLineSearchOptimizerv4.h: No such file or directory
    make: ***  Error 1
    make: ***  Error 2
    make: *** Waiting for unfinished jobs….
    Building CXX object Examples/CMakeFiles/l_antsApplyTransformsToPoints.dir/__/Utilities/antsCommandLineParser.cxx.o
    In file included from /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.h:570,
                     from /Users/tchaplin/ANTS/ANTS/trunk/Examples/antsApplyTransformsToPoints.cxx:4:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx: In member function ‘void ants::antsRegistrationCommandIterationUpdate<TFilter>::Execute(const itk::Object*, const itk::EventObject&)’:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:50: error: ‘ConjugateGradientLineSearchOptimizerv4’ in namespace ‘itk’ does not name a type
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: ‘GradientDescentOptimizerType’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: ‘optimizer’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected type-specifier before ‘GradientDescentOptimizerType’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected `>' before ‘GradientDescentOptimizerType’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected `(' before ‘GradientDescentOptimizerType’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:51: error: expected primary-expression before ‘>’ token
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:52: error: expected `)' before ‘;’ token
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx: In member function ‘int ants::RegistrationHelper<VImageDimension>::DoRegistration()’:
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1041: error: ‘ConjugateGradientLineSearchOptimizerv4’ in namespace ‘itk’ does not name a type
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1042: error: ‘GradientDescentOptimizerType’ has not been declared
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1042: error: expected initializer before ‘optimizer’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1043: error: ‘optimizer’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1054: error: ‘GradientDescentOptimizerType’ was not declared in this scope
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1054: error: template argument 1 is invalid
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1054: error: invalid type in declaration before ‘;’ token
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1055: error: ‘OptimizerCommandType’ is not a class or namespace
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1055: error: expected initializer before ‘optimizerObserver’
    /Users/tchaplin/ANTS/ANTS/trunk/Examples/itkantsRegistrationHelper.hxx:1056: error: ‘optimizerObserver’ was not declared in this scope
    make: ***  Error 1
    make: *** Waiting for unfinished jobs….
    Building CXX object Examples/CMakeFiles/l_WarpImageMultiTransform.dir/__/Utilities/antsCommandLineOption.cxx.o
    make: ***  Error 2
    Linking CXX static library /Users/tchaplin/ANTS/bin/lib/libl_WarpImageMultiTransform.a
    Built target l_WarpImageMultiTransform
    Linking CXX static library /Users/tchaplin/ANTS/bin/lib/libl_ImageMath.a
    Built target l_ImageMath
    make: ***  Error 2
    make: ***  Error 2
    make: ***  Error 2
    make: ***  Error 2

     
  • Nick Tustison

    Nick Tustison - 2012-05-29

    Hi,

    It looks like your ITK version is not up to date.  If you're using your own repository, please update.  If you're using ANTS Superbuild capabilities to retrieve the requisite ITK, it was out of date so I just updated it.

    Nick

     
  • Tristan

    Tristan - 2012-05-29

    Wow thanks for the quick reply. I did a fresh svn download and the problem persists.  The revision is 1384, is that correct? I'm building from the trunk, is that right?

     
  • Nick Tustison

    Nick Tustison - 2012-05-29

    There were some recent ITK changes which weren't propagated to the current ANTS repository.  I just fixed that so try again and let me know if you are still unable to compile.

     
  • Tristan

    Tristan - 2012-05-30

    Thanks, the build is fine now, I'll spend some time with the antsApplyTransformsToPoints program and let you know if I have any problems.

    Thanks for your help guys, I couldn't have worked this stuff out myself, very much appreciated.

     
  • Tristan

    Tristan - 2012-06-14

    I noticed in the help message for antsApplyTransformsToPoints it mentions you can supply a reference image.  However, after trying to pass one and then looking at the source code, it seems there is no such feature. May I ask to have this feature added in the future?

    Thanks,
    Tristan

     
  • Tristan

    Tristan - 2012-06-14

    If not, perhaps some could explain how to do it manually.

    For example if the point are in RSA and it needs to be changed to RAI and the origins are both (0,0,0), I think I need to swap the y and z coords, and multiple the new z by -1?

    Or if the points are RAI and origin = (0,0,0) and I need to change them to LPI origin = (a,b,c), do I multiply the x and y by -1 then subtract the new origin (a,b,c)?

     
  • DanE

    DanE - 2012-09-07

    tristan, I am having the same problem with transforming points, where the image registration is spot on, but the points are not moved correctly. Like you, I suspect that it has to do with the convention for the origin, but I am not sure. Did you ever resolve this?

     
  • Tristan

    Tristan - 2012-09-07

    For me, it turned out the the origin was not important, the transformation takes care of that for you.  What is important is that you get your points in LPS first.  The confusion for me was that in ITK LPS the L means left is positive etc, but in Caret LPS the L means left is negative etc.  You need to get your points in ITK LPS.

    Also you have to apply the inverse transformation for points.

    Hope that helps.

     
  • Anonymous

    Anonymous - 2012-09-07

    tristan

    thanks much for your explanation to danieleinst -- there are very few ants developers so it's not always easy for us to field the more complex questions.

    b

     
  • DanE

    DanE - 2012-09-10

    The LPS to RAS conversion was what I needed. Worked like a charm. Thanks

     
  • Tiziano D'Albis

    Tiziano D'Albis - 2012-10-23

    Hi,

    I am struggling with the same problem. Using the program WarpVTKPolyDataMultiTransform  I get as output the same mesh thet I provided as input, while using antsApplyTransformsToPoints I just get 'nan' values:

    tdalbis@matisse:~/ANTSbin/bin$ antsApplyTransformsToPoints  -i ~/points.csv -o ~/pointsWarped.csv -t '/acoustic/data/studies/planning/patients/63/park/63_patient_roi_2_template_roi_Affine.txt' -d 3
    Input csv file: /home/tdalbis/points.csv
    =============================================================================
    The composite transform is comprised of the following transforms (in order):
      1. /acoustic/data/studies/planning/patients/63/park/63_patient_roi_2_template_roi_Affine.txt (type = MatrixOffsetTransformBase)
    =============================================================================
    point-in =  point-out =
    point-in =  point-out =
    point-in =  point-out =
    Output warped points to csv file: /home/tdalbis/pointsWarped.csv

    And points.csv is like in the example posted on this forum:

    x,y,z
    100,100,0
    200,200,0
    140,150,0

    I'd like to make work WarpVTKPolyDataMultiTransform since it does directly what I need but, if I get it done with antsApplyTransformsToPoints is OK as well.

    Thanks for your help
    Tiziano

     
  • Nick Tustison

    Nick Tustison - 2012-10-24

    Can you send me the points and affine files directly? 

    ntustison@gmail.com

     
  • Tiziano D'Albis

    Tiziano D'Albis - 2012-10-30

    I think I solved the problem. For some very weired reason on my installation (Linux Ubuntu 12.04 64 bits) there should be a space AFTER the numbers and before the comma. Indeed if I write the CSV file like this:

    csv.write('%.6f ,%.6f ,%.6f \n' % (point,point,point))

    It works, while if I write it like this

    csv.write('%.6f, %.6f, %.6f\n' % (point,point,point))

    It doesn't!

    Tiziano

     
  • Tiziano D'Albis

    Tiziano D'Albis - 2012-10-30

    I want to stress that this program works if the points are in LPS and if the inverse tranformation is applied.
    Especially the second point is quite counter-intuitive and I do not really understand the rationale about it. Maybe the developers can englight us about this?

     
  • Anonymous

    Anonymous - 2012-10-30

    the inverse transform is a relative idea -- it is the inverse of the mapping used to transform the moving image to the fixed image.  

    because you need to know the value of the transform at the location of the point, you need a transform that is defined in that same domain.    the "inverse transform"  maps points from moving to fixed (and images from fixed to moving).   since that is the domain of the points , it is the natural transform to use. 

    what confuses people is the fact that warping images requires a "pull back" from the range of the transform to its domain.   point mappings can "push forward"   …  this is an ancient source of confusion but makes sense when you think about the nature of images and how our transforms are discretized.  

    an alternative approach is to resolve these issues through an optimization algorithm where one searches for a domain-range pairing that "hits" the point you want to transform.   but we don't provide that choice to the user.