[Insight-users] rigid2D registration fails to rotate images

Luis Ibanez luis.ibanez at kitware.com
Thu Mar 18 12:13:55 EDT 2010


Hi Darren,

Your approach sounds reasonable,
and it should provide an unsupervised mechanism for registering the images.

What seems to be missing from your code is a re-initialization of the
optimizer. That's where you may be now carrying a left-over state from
previous registrations.

If you want to be 100% sure,  would simply put the for-loop outside of the
creation of all the registration classes. That is, move the instantiation of the
Metric, Optimizer, Interpolator and Transform, all inside of the for-loop body.

In that way you guarantee that they are all fresh.


     Regards,


           Luis


----------------------------------------------------------------------------------------------------------
On Tue, Mar 9, 2010 at 8:01 PM, Darren Weber
<darren.weber.lists at gmail.com> wrote:
>
> Hi Luis et al.,
> In this loop (see below), is it necessary to "reset" the registration method
> (optimizer or anything else)?  Could there be any "hang-over" from previous
> calls in the loop?
> TIA,
> Darren
>
>
> On Tue, Mar 9, 2010 at 3:07 PM, Darren Weber <darren.weber.lists at gmail.com>
> wrote:
>>
>> FYI, here's a snip from the "rotation loop" (see ImageRegistration6.cxx
>> for the rest):
>>
>>
>>     // The registration fails when the angle of rotation is large, so we
>> need a
>>     // loop to evaluate a range of angles to find one that will work well.
>>     double angleInDegrees[] = { 0.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0,
>> 70.0, 80.0, 90.0, 100.0, 110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0,
>> 180.0 };
>>     double angleInRadians, bestAngleInRadians;
>>     unsigned int bestIterations = 0;
>>     TransformType::Pointer rigid2DFinalTransform = TransformType::New();
>>     OptimizerType::MeasureType bestMetric = 0.0;
>>     for( unsigned int i = 0; i < 19; i++ )
>>         {
>>         angleInRadians = angleInDegrees[i] * vnl_math::pi / 180.0;
>>         std::cout
>>             << std::endl
>>             << "Loop " << i << ", trying:" << std::endl
>>             << "angleInDegrees = " << angleInDegrees[i] << " degrees " <<
>> std::endl
>>             << "angleInRadians = " << angleInRadians    << std::endl
>>             << std::endl;
>>         initializer->InitializeTransform();
>>         rigid2DTransform->SetAngle( angleInRadians );
>>         registration->SetInitialTransformParameters(
>> rigid2DTransform->GetParameters() );
>>         try
>>             {
>>             registration->StartRegistration();
>>             if( VERBOSE )
>>                 {
>>                 std::cout << std::endl
>>                     << optim << std::endl
>>                     << std::endl;
>>                 }
>>             }
>>         catch( itk::ExceptionObject & err )
>>             {
>>             std::cerr << "ExceptionObject caught !" << std::endl;
>>             std::cerr << err << std::endl;
>>             return EXIT_FAILURE;
>>             }
>>         // Check the metric and store the best angle
>>         if( i == 0 )
>>             bestMetric = optim->GetValue();
>>         if( bestMetric > optim->GetValue() )
>>             {
>>             bestMetric = optim->GetValue();
>>             bestIterations = optim->GetCurrentIteration();
>>             bestAngleInRadians = angleInRadians;
>>             // ** Set the final rigid2DTransform **
>>             rigid2DFinalTransform->SetParameters(
>> registration->GetLastTransformParameters() );
>>             rigid2DFinalTransform->SetFixedParameters(
>> rigid2DTransform->GetFixedParameters() );
>>             }
>>         std::cout
>>             << std::endl
>>             << "After loop " << i << ", metrics are:" << std::endl
>>             << "angleInDegrees = " << angleInDegrees[i] << " degrees " <<
>> std::endl
>>             << "angleInRadians = " << angleInRadians    << std::endl
>>             << "bestMetric = " << bestMetric << std::endl
>>             << "currentMetric = " << optim->GetValue() << std::endl
>>             << std::endl;
>>         }
>>
>>
>> Best,
>> Darren
>>
>>
>>
>>
>>
>>
>> On Mon, Mar 8, 2010 at 11:14 AM, Darren Weber
>> <darren.weber.lists at gmail.com> wrote:
>>>
>>> Hi Luis et al.,
>>> Thanks for considering this and offering suggestions.
>>> There are thousands of images to register.  It's possible to manually
>>> note approximate initialization values for the rotation of all the images.
>>>  However, it may be easier (perhaps not quicker) to create a "rotation loop"
>>> that:
>>>  (a) sets a rotation value between 0 to pi (stepping 15 degrees),
>>>  (b) calls the registration method, then
>>>  (c) checks the metric for the lowest value (for mean sq metric) to
>>> identify and store the rotation that provides the "best" registration.
>>> The extra "rotation" loop means running the registration N times (say 13
>>> times for 0:15:180 [in Octave syntax]) and there may be a final run with the
>>> "best" rotation value.
>>> Is this reasonable?  Is there are better way to do this?
>>> As a novice with optimization, I'm surprised that some kind of quick
>>> estimate for the full range of rotations is not built into the optimization
>>> routine or the registration method.
>>> Take care,
>>> Darren
>>>
>>>
>>>
>>> On Sat, Mar 6, 2010 at 3:58 PM, Luis Ibanez <luis.ibanez at kitware.com>
>>> wrote:
>>>>
>>>> Darren,
>>>>
>>>>
>>>> Thanks for posting all the source code and images that
>>>> reproduce the problem that you are observing.
>>>>
>>>>
>>>> As Richard pointed out, the registration process must be
>>>> initialized properly.
>>>>
>>>>
>>>> It is very unlikely that an optimization process will manage
>>>> to register two images that are 140 degrees off, as the ones
>>>> that you kindly posted.
>>>>
>>>>
>>>> So you should:
>>>>
>>>> 1)  Initialize the Transform with an angle close to 140 degrees.
>>>>
>>>> 2)  Use the Rigid2DTransform instead of the
>>>>     CenteredRigid2DTransform (this later one is deprecated)
>>>>
>>>> 3)  Remove all the Change image filters that you have in your
>>>>     code. They shouldn't be necessary.
>>>>
>>>>
>>>> Please find attached a simplified variation of the example:
>>>>
>>>>    Insight/Examples/Registration/
>>>>                            ImageRegistration6.cxx
>>>>
>>>> With this attached .cxx file,
>>>> I manage to register your two images with the following output:
>>>>
>>>>  Angle (radians) 2.45657
>>>>  Angle (degrees) 140.751
>>>>  Translation X = 1.67046
>>>>  Translation Y = -0.480926
>>>>  Iterations    = 92
>>>>  Metric value  = 6.19969e+07
>>>>
>>>>
>>>> I ran it with the following set of command line arguments:
>>>>
>>>> ImageRegistration6
>>>>
>>>>     section0004_w1.tif section0005_w1.tif 150.0 output.tiff
>>>>
>>>>
>>>> Where "150.0" is the initial angle to set in the Transform.
>>>>
>>>>
>>>> Please give it a try at this attached code and let us
>>>> know if you find any problems.
>>>>
>>>>
>>>>     Thanks
>>>>
>>>>
>>>>            Luis
>>>>
>>>>
>>>>
>>>> --------------------------------------------------------------------------------------
>>>> On Fri, Mar 5, 2010 at 7:56 PM, Richard Beare <richard.beare at gmail.com>
>>>> wrote:
>>>> > Good initialization is essential for all registration, with the
>>>> > rotation component often the most critical. If the rotation is greater
>>>> > than 15 degrees then you're probably going to have trouble.
>>>> >
>>>> > If you're trying to build an automated process rather than a one off,
>>>> > then here are some options.
>>>> >
>>>> > Moments based initialization as a first step. This is good if the
>>>> > scene is reasonably simple, or you have masks defining the regions of
>>>> > interest. You can check how similar the major moments are. If they are
>>>> > sufficiently dissimilar then the initialization is likely to be
>>>> > accurate along the major axis, but potentially flipped. In this case
>>>> > you need to try both options and select the one that gives the best
>>>> > resulting cost. If the moments are similar then the initialization
>>>> > will be unreliable and sensitive to small changes, so you need to try
>>>> > a series of angles covering the entire 360 degrees and select the best
>>>> > result as defined by your cost metric.
>>>> >
>>>> > On Sat, Mar 6, 2010 at 11:45 AM, Darren Weber
>>>> > <darren.weber.lists at gmail.com> wrote:
>>>> >>
>>>> >> I've got a couple of images that clearly need nearly 180 degree
>>>> >> rotation for
>>>> >> registration, see:
>>>> >> ftp://anonymous@ftp.buckinstitute.org/dweber/section0004_w1.tif
>>>> >> ftp://anonymous@ftp.buckinstitute.org/dweber/section0005_w1.tif
>>>> >> The registration fails to rotate the images into alignment.  I'm
>>>> >> using:
>>>> >> // Registration components
>>>> >> #include "itkImageRegistrationMethod.h"
>>>> >> #include "itkMeanSquaresImageToImageMetric.h"
>>>> >> #include "itkLinearInterpolateImageFunction.h"
>>>> >> #include "itkRegularStepGradientDescentOptimizer.h"
>>>> >> // Transforms
>>>> >> #include "itkCenteredRigid2DTransform.h"
>>>> >> #include "itkCenteredTransformInitializer.h"
>>>> >>
>>>> >> What can I do about it?  Have I selected the wrong transform for
>>>> >> rotations?
>>>> >> I've prepared a package of my test program and data for download
>>>> >> here:
>>>> >>
>>>> >> ftp://anonymous@ftp.buckinstitute.org/dweber/itkRegistrationTest.tar.gz
>>>> >> The program is built against ITK 3.16 (and it uses Boost).
>>>> >> TIA,
>>>> >> Darren
>>>> >>
>>>> >> _____________________________________
>>>> >> 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.html
>>>> >>
>>>> >> 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://www.itk.org/mailman/listinfo/insight-users
>>>> >>
>>>> >>
>>>> > _____________________________________
>>>> > 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.html
>>>> >
>>>> > 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://www.itk.org/mailman/listinfo/insight-users
>>>> >
>>>
>>
>
>


More information about the Insight-users mailing list