[Insight-users] rigid2D registration fails to rotate images

Darren Weber darren.weber.lists at gmail.com
Tue Mar 9 19:01:40 EST 2010


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
>>> >
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100309/5a674834/attachment-0001.htm>


More information about the Insight-users mailing list