[ITK-users] 2D rigid transformation

Bill Lorensen bill.lorensen at gmail.com
Tue May 19 11:20:06 EDT 2015


It would be useful if you included a compilable, minimal example.

I include your code snippet in a small program that reads two files
and performs the optimization. I ran it with the fixed and moving set
to the same image. Here are my results:

  InitialPosition = [-6.283185307179586, 0, 0]
  CurrentValue = 3528.15
  NumberOfSteps = [6, 0, 0]
  Stop = 1
  StepLength = 1
  CurrentIndex = [0, 0, 0]
  MaximumMetricValue = 3528.15
  MinimumMetricValue = 4.50585e-27
  MinimumMetricValuePosition = [-6.283185307179586, 0, 0]
  MaximumMetricValuePosition = [-3.141592653589793, 0, 0]

I suspect that your images are filled with zeroes. You do not show how
you populate the images.

Here is my code:
#include "itkImageFileReader.h"
#include "itkEuler2DTransform.h"
#include "itkExhaustiveOptimizerv4.h"
#include "itkMeanSquaresImageToImageMetricv4.h"
#include "itkCenteredTransformInitializer.h"
#include "itkImageRegistrationMethodv4.h"
#include "itkImage.h"

int main (int argc, char *argv[])
{
  if (argc < 3)
    {
    std::cout << "Usage: " << argv[0] << " fixedImage movingImage" << std::endl;
    return EXIT_FAILURE;
    }
  typedef itk::Image<double, 2>                 FixedImageType;
  typedef itk::Image<double, 2>                 MovingImageType;
  typedef itk::ImageFileReader<FixedImageType>  FixedImageReaderType;
  typedef itk::ImageFileReader<MovingImageType> MovingImageReaderType;
  typedef itk::Euler2DTransform< double >       TransformType;
  typedef itk::ExhaustiveOptimizerv4< double >  OptimizerType;
  typedef itk::MeanSquaresImageToImageMetricv4< FixedImageType,
MovingImageType >
                                                MetricType;
  typedef itk::CenteredTransformInitializer< TransformType,
FixedImageType,  MovingImageType >
                                                TransformInitializerType;
  typedef itk::ImageRegistrationMethodv4< FixedImageType,
MovingImageType, TransformType >
                                                RegistrationType;

  FixedImageReaderType::Pointer     fixedImageReader    =
FixedImageReaderType::New();
  MovingImageReaderType::Pointer    movingImageReader    =
MovingImageReaderType::New();
  FixedImageType::Pointer           fixedImage    = FixedImageType::New();
  MovingImageType::Pointer          movingImage    = MovingImageType::New();
  TransformType::Pointer            transform    = TransformType::New();
  MetricType::Pointer               metric       = MetricType::New();
  OptimizerType::Pointer            optimizer    = OptimizerType::New();
  RegistrationType::Pointer         registration = RegistrationType::New();
  TransformInitializerType::Pointer initializer  =
TransformInitializerType::New();

  fixedImageReader->SetFileName (argv[1]);
  fixedImageReader->Update();
  fixedImage = fixedImageReader->GetOutput();

  movingImageReader->SetFileName (argv[2]);
  movingImageReader->Update();
  movingImage = movingImageReader->GetOutput();

  unsigned int angles = 12;
  OptimizerType::StepsType steps( transform->GetNumberOfParameters() );
  steps[0] = int(angles/2);
  steps[1] = 0;
  steps[2] = 0;
  optimizer->SetNumberOfSteps( steps );

  OptimizerType::ScalesType scales( transform->GetNumberOfParameters() );
  scales[0] = 2.0 * vnl_math::pi / angles;
  scales[1] = 1.0;
  scales[2] = 1.0;

  optimizer->SetScales( scales );

  initializer->SetTransform(   transform );
  initializer->SetFixedImage(  fixedImage );
  initializer->SetMovingImage( movingImage );
  initializer->InitializeTransform();

// Initialize registration
  registration->SetMetric(           metric );
  registration->SetOptimizer(        optimizer );
  registration->SetFixedImage(       fixedImage );
  registration->SetMovingImage(      movingImage );
  registration->SetInitialTransform( transform );

  try
    {
    registration->Update();
    optimizer->Print(std::cout);
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}


On Tue, May 19, 2015 at 5:41 AM, Pietro Nardelli
<p.nardelli at umail.ucc.ie> wrote:
> Hi guys,
>
> thank you very much for your help. I was trying to follow the examples you
> sent me (converting it in native C++ ITK code), but it seems that the
> optimizer does not work properly. In particular, no matter the number of
> angles and the step length I choose, it always gives me the same result. It
> seems to me that the optimizer is never updating the angles, therefore it is
> not following the grid I create. Also the metric is always 0. There is
> definitely something wrong! Here is part of the script I am using and the
> result I always get. Am I overlooking anything?
>
>   typedef itk::Euler2DTransform< double >
> TransformType;
>   typedef itk::ExhaustiveOptimizerv4< double >
> OptimizerType;
>   typedef itk::MeanSquaresImageToImageMetricv4< FixedInputImageType,
> MovingInputImageType >               MetricType;
>   typedef itk::CenteredTransformInitializer< TransformType,
> FixedInputImageType,  MovingInputImageType > TransformInitializerType;
>   typedef itk::ImageRegistrationMethodv4< FixedInputImageType,
> MovingInputImageType, TransformType > RegistrationType;
>
>   typename TransformType::Pointer               transform    =
> TransformType::New();
>   typename MetricType::Pointer                      metric       =
> MetricType::New();
>   typename OptimizerType::Pointer                optimizer    =
> OptimizerType::New();
>   typename RegistrationType::Pointer            registration =
> RegistrationType::New();
>   typename TransformInitializerType::Pointer initializer  =
> TransformInitializerType::New();
>
>   unsigned int angles = 12;
>   OptimizerType::StepsType steps( transform->GetNumberOfParameters() );
>   steps[0] = int(angles/2);
>   steps[1] = 0;
>   steps[2] = 0;
>   optimizer->SetNumberOfSteps( steps );
>
>   OptimizerType::ScalesType scales( transform->GetNumberOfParameters() );
>   scales[0] = 2.0 * vnl_math::pi / angles;
>   scales[1] = 1.0;
>   scales[2] = 1.0;
>
>   optimizer->SetScales( scales );
>
>   initializer->SetTransform(   transform );
>   initializer->SetFixedImage(  fixImage );
>   initializer->SetMovingImage( movImage );
>   //initializer->GeometryOn();
>   initializer->InitializeTransform();
>
>   // Initialize registration
>   registration->SetMetric(                  metric    );
>   registration->SetOptimizer(            optimizer );
>   registration->SetFixedImage(         fixedImage  );
>   registration->SetMovingImage(      movingImage  );
>   registration->SetInitialTransform(   transform );
>
>   try
>   {
>     registration->Update();
>   }
>   catch( itk::ExceptionObject & err )
>   {
>     std::cerr << "ExceptionObject caught !" << std::endl;
>     std::cerr << err << std::endl;
>     return EXIT_FAILURE;
>   }
>
> Result:
>
> Final parameters: [-1.8849555921538759, -40, 40]
> Result =
> Metric value  = 0
> Angle (rad) =  -1.88496
> Angle (degrees) =  -108
> Iterations    = 13
> Rotation Center = [225.5, 185.5]
> ExhaustiveOptimizerv4: Completed sampling of parametric space of size 3
>
>
> Thank you very much,
> Pietro
>
> Pietro Nardelli, MEngSc, BE
>
> Ph.D Candidate
>
> School of Engineering
>
> Electrical & Electronic Engineering
>
> University College Cork
>
> College Road
>
> Cork, Ireland
>
>
> On Fri, May 15, 2015 at 7:21 PM, Yaniv, Ziv Rafael (NIH/NLM/LHC) [C]
> <zivrafael.yaniv at nih.gov> wrote:
>>
>> Hello Pietro,
>>
>> You should use the ExhaustiveOptimizerv4
>> (http://www.itk.org/Doxygen/html/classitk_1_1ExhaustiveOptimizerv4.html)
>> which allows you to set a grid on which the similarity metric is evaluated.
>>
>> If you are familiar with python, then the following SimpleITK notebook may
>> be of use to you (see last section):
>> https://github.com/zivy/SimpleITK-Notebook-Staging/blob/master/registration3.ipynb
>>
>>      regards
>>               Ziv
>>
>> From: Pietro Nardelli
>> <p.nardelli at umail.ucc.ie<mailto:p.nardelli at umail.ucc.ie>>
>> Date: Friday, May 15, 2015 at 2:13 PM
>> To: "insight-users at itk.org<mailto:insight-users at itk.org>"
>> <insight-users at itk.org<mailto:insight-users at itk.org>>
>> Subject: [ITK-users] 2D rigid transformation
>>
>> Hello guys,
>>
>> is there a way to have a 2D rigid registration that uses a specific number
>> of rotations and chooses the best one? I have two images that are simply
>> rotated with respect to each other, and I would like to register them using
>> for example 36 rotations (therefore computing the mean squared error every
>> 10 degrees). At the moment I am using the 2DRigidTransform with a specified
>> center, with a regular step descent optimizer and the
>> ImageRegistrationMethodv4. I saw that the transform has the function
>> SetFixedParameters() but I am not really sure whether I understand correctly
>> that that would tell the optimizer the angles (and translations) to use at
>> every iteration. Could anyone please clarify this?
>>
>> Thank you very much,
>> Pietro
>>
>>
>
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.php
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/insight-users
>



-- 
Unpaid intern in BillsBasement at noware dot com


More information about the Insight-users mailing list