[Insight-users] Question regarding centered versor transform
Dan Mueller
dan.muel at gmail.com
Fri Oct 31 02:40:02 EDT 2008
Hi Simon, thanks for your reply.
No, I did not called SetFixedParameters(.). Doing so makes everything
behave as I expect. A bug with the user :P
Thanks again.
Regards, Dan
2008/10/30 Simon Warfield <simon.warfield at childrens.harvard.edu>:
>
> The different types of transforms have inconsistent APIs and it is tricky to
> know exactly what should be set.
>
> There is an interaction between the 'fixed parameters' and the 'offset'.
>
> Did you set the 'Fixed Parameters' before you set the 'Parameters' ?
> http://www.itk.org/Doxygen/html/classitk_1_1MatrixOffsetTransformBase.html#bab57111fda06e69309c80fdf6fbee38
>
>
>> In itkVersorTransform.txx in SetRotation(.) the versor is set and then
>> > both ComputeMatrix(.) and ComputeOffset(.) are called.
>> >
>> > In itkVersorTransform.txx in SetParameters(.) the verser is set and
>> > then only ComputeMatrix(.) is called. If I add ComputeOffset(.) here,
>> > then my code works as expected.
>
>
> --
> Simon
>
> Message: 6
> Date: Thu, 30 Oct 2008 10:44:45 +0100
> From: "Dan Mueller" <dan.muel at gmail.com>
> Subject: Re: [Insight-users] Question regarding centered versor
> transform
> To: "Insight Users" <insight-users at itk.org>
> Message-ID:
> <2b8d077d0810300244t5dc7ffc4w7972969dfc613fbc at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> Is someone able to confirm if this is a bug with the code or with the user?
>
> 2008/10/28 Dan Mueller <dan.muel at gmail.com>:
>> I've had a dig into the code and seem to have found an inconsistency...
>>
>> In itkVersorTransform.txx in SetRotation(.) the versor is set and then
>> both ComputeMatrix(.) and ComputeOffset(.) are called.
>>
>> In itkVersorTransform.txx in SetParameters(.) the verser is set and
>> then only ComputeMatrix(.) is called. If I add ComputeOffset(.) here,
>> then my code works as expected.
>>
>> Should I file a bug, or have I misunderstood something?
>>
>> Regards, Dan
>>
>> 2008/10/28 Dan Mueller <dan.muel at gmail.com>:
>>> Hi Insight Users,
>>>
>>> I am experiencing a problem with setting parameters for centered
>>> versor transforms.
>>>
>>> Some background: I ultimately want to perform registration considering
>>> only (centered) rotation. From my understanding the VersorTransform
>>> compactly represents a centered rotation in 3D space (three rotation
>>> parameters, no translation parameters optimized). However, when the
>>> VersorTransformOptimizer optimizes the metric I seem to be noticing
>>> "translation". I think this "translation" is occurring because the
>>> center of rotation/translation/offset ? is not being set correctly
>>> when setting the versor parameters.
>>>
>>> To further investigate the issue I have simplified the problem,
>>> totally removing the registration component, only considering image
>>> resampling with a VersorTransform. The source code attached below does
>>> the following:
>>> 1. Read the fixed image
>>> 2. Read the moving image
>>> 3. Create and setup the transform
>>> 4. Create interpolator
>>> 5. Resample moving image using the transform
>>> 6. Write resampled image
>>>
>>> What I am observing is the following:
>>> a. If I set the rotation via Versor.SetRotation(.) everything behaves
>>> as I expect (i.e. the image is rotated around the center).
>>> b. If I set the rotation via Transform.SetParameters(.) (which is what
>>> the optimizer does) the rotation is NOT around the (desired) center.
>>>
>>> I have made screen shots showing the results of (a) and (b) above,
>>> only changing the #define SETBYPARAMETERS.
>>> https://fileshare.qut.edu.au/public/muellerd/resampled_direct.png
>>> https://fileshare.qut.edu.au/public/muellerd/resampled_param.png
>>>
>>> The problem described in (b) seems to be what I am noticing with my
>>> registration (i.e. a rotation around the wrong center, introducing
>>> "translation").
>>>
>>> What am I doing wrong? Have I misunderstood something? Is this a bug
>>> with VersorTransform?
>>>
>>> Thanks for any advice!
>>>
>>> Regards, Dan
>>>
>>> === CMake ===
>>> PROJECT(VersorTest)
>>> CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
>>>
>>> FIND_PACKAGE(ITK REQUIRED)
>>> INCLUDE(${ITK_USE_FILE})
>>>
>>> ADD_EXECUTABLE(VersorTest main.cxx)
>>> TARGET_LINK_LIBRARIES(VersorTest ITKCommon ITKIO)
>>>
>>> === Source Code (main.cxx) ===
>>> #include "itkImage.h"
>>> #include "itkImageFileReader.h"
>>> #include "itkImageFileWriter.h"
>>> #include "itkVersorTransform.h"
>>> #include "itkLinearInterpolateImageFunction.h"
>>> #include "itkResampleImageFilter.h"
>>>
>>> #define SETBYPARAMETERS 0
>>>
>>> int main(int argc, char* argv[]) {
>>>
>>> try {
>>> // Typedefs
>>> const unsigned int Dimension = 3;
>>> typedef float PixelType;
>>> typedef double CoordRepType;
>>> typedef itk::Image< PixelType, Dimension > ImageType;
>>> typedef ImageType::PointType PointType;
>>> typedef itk::Vector< CoordRepType, Dimension > VectorType;
>>>
>>> // 1. Read fixed image
>>> std::cout << "Reading fixed image..." << std::endl;
>>> typedef itk::ImageFileReader< ImageType > ReaderType;
>>> ReaderType::Pointer readerFixed = ReaderType::New( );
>>> readerFixed->SetFileName( "D:/Temp/fixed.mhd" );
>>> readerFixed->Update( );
>>> ImageType::Pointer imageFixed = readerFixed->GetOutput();
>>> imageFixed->DisconnectPipeline( );
>>>
>>> // 2. Read moving image
>>> std::cout << "Reading moving image..." << std::endl;
>>> ReaderType::Pointer readerMoving = ReaderType::New( );
>>> readerMoving->SetFileName( "D:/Temp/moving.mhd" );
>>> readerMoving->Update( );
>>> ImageType::Pointer imageMoving = readerMoving->GetOutput();
>>> imageMoving->DisconnectPipeline( );
>>>
>>> // 3. Create and setup transform
>>> // NOTE: This basically does the same as
>>> CenteredTransformInitializer
>>> // with geometry on
>>> std::cout << "Creating transform..." << std::endl;
>>> typedef itk::VersorTransform< CoordRepType > TransformType;
>>> TransformType::Pointer transform = TransformType::New();
>>> PointType centerFixed;
>>> for (int i=0; i<Dimension; i++) {
>>> centerFixed[i] =
>>> imageFixed->GetOrigin()[i] +
>>> imageFixed->GetLargestPossibleRegion().GetSize()[0] *
>>> imageFixed->GetSpacing()[0] / 2.0;
>>> }
>>> PointType centerMoving;
>>> for (int i=0; i<Dimension; i++) {
>>> centerMoving[i] =
>>> imageMoving->GetOrigin()[i] +
>>> imageMoving->GetLargestPossibleRegion().GetSize()[0] *
>>> imageMoving->GetSpacing()[0] / 2.0;
>>> }
>>> VectorType translation = centerFixed - centerMoving;
>>> TransformType::VersorType versor;
>>> versor.Set( 0.0, 0.0, 0.9, 0.43589 );
>>> transform->SetCenter( centerFixed );
>>> transform->SetTranslation( translation );
>>> TransformType::ParametersType param( Dimension );
>>> for (int i=0; i<Dimension; i++) {
>>> param[i] = versor.GetRight()[i];
>>> }
>>> #if SETBYPARAMETERS
>>> std::cout << "Setting rotation using parameters..." << param
>>> << std::endl;
>>> transform->SetParameters( param );
>>> #else
>>> std::cout << "Setting rotation directly..." << versor <<
>>> std::endl;
>>> transform->SetRotation( versor );
>>> #endif
>>>
>>> // 4. Create interpolator
>>> typedef itk::LinearInterpolateImageFunction< ImageType,
>>> CoordRepType > InterpolatorType;
>>> InterpolatorType::Pointer interpolator = InterpolatorType::New();
>>>
>>> // 5. Resample
>>> std::cout << "Resampling moving image..." << std::endl;
>>> typedef itk::ResampleImageFilter< ImageType, ImageType>
>>> ResampleType;
>>> ResampleType::Pointer resample = ResampleType::New();
>>> resample->SetInput( imageMoving );
>>> resample->SetOutputParametersFromImage( imageFixed );
>>> resample->SetInterpolator( interpolator );
>>> resample->SetTransform( transform );
>>> resample->Update( );
>>>
>>> // 6. Write resample image
>>> std::cout << "Writing resampled image..." << std::endl;
>>> typedef itk::ImageFileWriter< ImageType > WriterType;
>>> WriterType::Pointer writer = WriterType::New( );
>>> writer->SetFileName( "D:/Temp/resampled.mhd" );
>>> writer->SetInput( resample->GetOutput() );
>>> writer->Update( );
>>>
>>> return EXIT_SUCCESS;
>>> }
>>> catch( itk::ExceptionObject& err ) {
>>> std::cout << err << std::endl;
>>> return EXIT_FAILURE;
>>> }
>>> }
>>>
>>> === Information ===
>>> ITK 3.8
>>> CMake 2.6.0
>>> Windows XP 64-bit SP2
>>> Visual Studio 8.0.50727.762
More information about the Insight-users
mailing list