[Insight-users] Initializing a BSplineTransform in ITK 4.4

Nick Tustison ntustison at gmail.com
Sat Aug 3 11:22:57 EDT 2013


Hi Frank,

You can look at the test I recently added to gerrit

http://review.source.kitware.com/#/c/12186/

which demonstrates how to use the B-spline transform with
ITKv4.  It includes being initialized with an affine transform,
multi-level, and use of the scales estimator.

Nick


On Aug 1, 2013, at 10:09 AM, Nick Tustison <ntustison at gmail.com> wrote:

> Hi Frank,
> 
> I don't see anything immediately.  I can't work on it now but will most likely get to
> it this weekend.  I'll also take your code and, after we figure out what's going on,
> add it as a test in using the b-spline transform with the new framework since
> we currently don't have one (outside of our ANTs tool).
> 
> Nick
> 
> 
> On Jul 31, 2013, at 11:10 AM, Frank Preiswerk <frank.preiswerk at unibas.ch> wrote:
> 
>> Hi Nick,
>> 
>> I have noticed that the error is not thrown if I do not set the initial transform for the moving image via registrationMethod->SetMovingInitialTransform (although the optimizer then produces a constant error value and the registration simply iterates without altering the deformation field - I don't know if this is an unrelated problem).
>> 
>> My setup is simple, i.e. no multi-resolution involved. I'm doing essentially this:
>> 
>> typedef itk::BSplineTransform< PixelType, ImageDimension > TransformType;
>> typedef itk::MeanSquaresImageToImageMetricv4< ImageType, ImageType >     MetricType;
>> typedef itk::GradientDescentOptimizerv4 OptimizerType;
>> typedef itk::ImageRegistrationMethodv4< ImageType, ImageType, TransformType > RegistrationMethodType;
>> typedef itk::RegistrationParameterScalesFromPhysicalShift< MetricType > ScalesEstimatorType;
>> 
>> MetricType::Pointer metric = MetricType::New();
>> 
>> OptimizerType::Pointer optimizer = OptimizerType::New();
>> optimizer->SetNumberOfIterations( 200 );
>> optimizer->SetDoEstimateLearningRateOnce( true );
>> optimizer->SetMinimumConvergenceValue( 1e-16 );
>> optimizer->SetConvergenceWindowSize( 20 );
>> optimizer->SetMaximumStepSizeInPhysicalUnits( 2 );
>> 
>> ScalesEstimatorType::Pointer scalesEstimator = ScalesEstimatorType::New();
>> scalesEstimator->SetMetric( metric );
>> scalesEstimator->SetTransformForward( true );
>> optimizer->SetScalesEstimator( scalesEstimator );
>> optimizer->SetDoEstimateScales( true );
>> 
>> RegistrationMethodType::Pointer registrationMethod = RegistrationMethodType::New();
>> registrationMethod->SetOptimizer( optimizer );
>> registrationMethod->SetFixedImage( fixedImage );
>> registrationMethod->SetMovingImage( movingImage );
>> registrationMethod->SetFixedInitialTransform( initialFixedTransform );
>> registrationMethod->SetMovingInitialTransform( initialMovingTransform );
>> registrationMethod->SetNumberOfLevels( 1 );
>> registrationMethod->SetMetric( metric );
>> registrationMethod->SetMetricSamplingStrategy( RegistrationMethodType::NONE );
>> 
>> 
>> 
>> 
>> The initial transforms are initialized like this:
>> 
>> TransformType::PhysicalDimensionsType fixedPhysicalDimensions;
>> TransformType::MeshSizeType meshSize;
>> for( unsigned int i=0; i < ImageDimension; i++ )
>> {
>>   fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] *
>>   static_cast<double>(
>>     movingImage->GetLargestPossibleRegion().GetSize()[i] - 1 );
>> }
>> unsigned int SplineOrder = 3;
>> unsigned int numberOfGridNodesInOneDimension = 5;
>> meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder );
>> initialMovingTransform->SetTransformDomainOrigin( movingImage->GetOrigin() );
>> initialMovingTransform->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
>> initialMovingTransform->SetTransformDomainMeshSize( meshSize );
>> initialMovingTransform->SetTransformDomainDirection( movingImage->GetDirection() );
>> TransformType::ParametersType initialMovingParameters( initialMovingTransform->GetNumberOfParameters() );
>> initialMovingParameters.Fill(0.0);
>> initialMovingTransform->SetParameters(initialMovingParameters);
>> 
>> 
>> Thanks for the link to the relevant ANTs class. I took a look at the relevant lines but it didn't help me either.
>> 
>> Many thanks,
>> Frank
>> 
>> 
>> 
>> 
>> 
>> On 07/31/2013 01:21 PM, Nick Tustison wrote:
>>> Hi Frank,
>>> 
>>> I'm cc'ing the insight users list as others might be interested.  
>>> 
>>> How are you setting up the registration? In case you were interested, we have 
>>> a pretty comprehensive application which ties in all the new registration stuff 
>>> in a single application. In it, we set up the B-spline transform which you can 
>>> view at
>>> 
>>> https://github.com/stnava/ANTs/blob/master/Examples/itkantsRegistrationHelper.hxx
>>> 
>>> starting at line 1896.
>>> 
>>> Nick
>>> 
>>> On Jul 31, 2013, at 4:45 AM, Frank Preiswerk <frank.preiswerk at unibas.ch> wrote:
>>> 
>>>> Hi Nick,
>>>> 
>>>> I have adapted my code to work with the new ITKv4 classes. For the affine registration this worked well. But for the BSplineTransform, I get the following error during optimization:
>>>> 
>>>> /usr/local/include/ITK-4.4/itkImageToImageMetricv4GetValueAndDerivativeThreaderBase.hxx:258:
>>>> Exception in GetValueAndDerivativeProcessPoint:
>>>> /usr/local/include/ITK-4.4/itkBSplineBaseTransform.h:282:
>>>> itk::ERROR: BSplineTransform(0x384cb00): ComputeJacobianWithRespectToPosition not yet implemented for BSplineTransform
>>>> 
>>>> I use GradientDescentOptimizerv4 and MeanSquaresImageToImageMetricv4 and also tried substituting them with QuasiNewtonOptimizerv4 and MattesMutualInformationImageToImageMetricv4 but to no avail.
>>>> 
>>>> Sorry to bother you but I could not find any examples on the web that shows how the BSplineTransform can be used in the new framework.
>>>> 
>>>> Many thanks!
>>>> Frank
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On 07/30/2013 04:09 PM, Nick Tustison wrote:
>>>>> Hi Frank,
>>>>> 
>>>>> I don't think that anybody on the registration team has tried to use the composite
>>>>> transform with the old registration framework.  I'm not even sure that it would work 
>>>>> as both the optimization and metrics are completely separate between ITKv3 and
>>>>> ITKv4.  In suggesting the use of the CompositeTransform class, I didn't catch that
>>>>> you were sticking with ITKv3.  Sorry about that.  
>>>>> 
>>>>> There was some earlier work by Torsten and Marius & Stefan who gave us some
>>>>> ideas for the current composite transform.  Perhaps one of those contributions would
>>>>> fit your needs.
>>>>> 
>>>>> http://www.insight-journal.org/browse/publication/143
>>>>> http://www.insight-journal.org/browse/publication/91
>>>>> 
>>>>> Also, I would be remiss if I didn't at least proselyte concerning the utility of the new 
>>>>> registration framework.  There's quite a few advantages in addition to the composite
>>>>> transform:
>>>>> 
>>>>> http://www.itk.org/Wiki/ITK/Release_4/Why_Switch_to_ITKv4#New_Registration_Framework
>>>>> 
>>>>> Nick
>>>>> 
>>>>> 
>>>>> On Jul 30, 2013, at 7:35 AM, Frank Preiswerk <frank.preiswerk at unibas.ch> wrote:
>>>>> 
>>>>>> Hi Nick,
>>>>>> 
>>>>>> I have a few additional questions and I would be very glad if you could help me getting on the right track.
>>>>>> 
>>>>>> Your suggestion to use the CompositeTransform guided me to the new registration framework. I have played around a bit and now I'm unsure which version to use.
>>>>>> 
>>>>>> First of all, in ImageRegistrationMethodv4 there is a method SetMovingInitialTransform that probably does exactly what I need. As far as I understand it, one can achieve the same with the old framework by using CompositeTransform like this:
>>>>>> 
>>>>>> compositeTransform->AddTransform(affineTransform); // the output from the prior affine step
>>>>>> compositeTransform->AddTransform(bsplineTransform);
>>>>>> compositeTransform->SetOnlyMostRecentTransformToOptimizeOn(); // activate the bspline transform for the next optimization
>>>>>> registration->SetTransform( compositeTransform );
>>>>>> 
>>>>>> Is this the way how to properly use CompositeTransform in the old registration framework? And is my assumption correct that SetMovingInitialTransform would be sufficient when using the new framework?
>>>>>> 
>>>>>> Thanks a lot for your efforts,
>>>>>> Frank
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> On 07/29/2013 12:16 PM, Nick Tustison wrote:
>>>>>>> You should try using the composite transform
>>>>>>> 
>>>>>>> http://www.itk.org/Doxygen/html/classitk_1_1CompositeTransform.html
>>>>>>> 
>>>>>>> Nick
>>>>>>> 
>>>>>>> On Jul 29, 2013, at 4:49 AM, Frank Preiswerk <frank.preiswerk at unibas.ch> wrote:
>>>>>>> 
>>>>>>>> Hi all,
>>>>>>>> 
>>>>>>>> I'm writing a program that performs image registration by first computing an
>>>>>>>> affine transformation followed by a bspline deformation. The bspline
>>>>>>>> registration should be initialized with the output of the affine
>>>>>>>> registration.
>>>>>>>> 
>>>>>>>> I'm using ITK 4.4. The example DeformableRegistration15.cxx intends to do
>>>>>>>> the above but it seems that the BSplineTransform is actually not initialized
>>>>>>>> with the output of the affine step, as already reported earlier:
>>>>>>>> http://www.itk.org/pipermail/insight-users/2012-May/044623.html
>>>>>>>> 
>>>>>>>> ITK 3's BSplineDeformableTransform had a method SetBulkTransform to concat
>>>>>>>> the bspline transform with another transform, but in ITK 4's
>>>>>>>> BSplineTransform this method was removed. So the question remains how to
>>>>>>>> properly initialize a BSplineTransform with an affine (or any other)
>>>>>>>> registration output.
>>>>>>>> 
>>>>>>>> Computing the parameters of the bspline transform by applying the affine
>>>>>>>> transform to the grid nodes is an option. But something like
>>>>>>>> SetBulkTransform would be much more convenient.
>>>>>>>> 
>>>>>>>> I'm thankful for any hints.
>>>>>>>> 
>>>>>>>> Regards,
>>>>>>>> Frank
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> --
>>>>>>>> View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Initializing-a-BSplineTransform-in-ITK-4-4-tp7583607.html
>>>>>>>> Sent from the ITK Insight Users mailing list archive at Nabble.com.
>>>>>>>> _____________________________________
>>>>>>>> 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://www.itk.org/mailman/listinfo/insight-users
>>>>>> -- 
>>>>>> Frank Preiswerk, Senior Researcher
>>>>>> Medical Image Analysis Center (MIAC)
>>>>>> University of Basel c/o University Hospital Basel
>>>>>> Spitalstrasse 21
>>>>>> CH-4031 Basel
>>>>>> Switzerland
>>>>>> 
>>>>>> Tel: +41 61 265 96 58
>>>>>> Fax: +41 61 265 96 68
>>>>>> Office:Schanzenstrasse 46, Room 321
>>>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Frank Preiswerk, Senior Researcher
>>>> Medical Image Analysis Center (MIAC)
>>>> University of Basel c/o University Hospital Basel
>>>> Spitalstrasse 21
>>>> CH-4031 Basel
>>>> Switzerland
>>>> 
>>>> Tel: +41 61 265 96 58
>>>> Fax: +41 61 265 96 68
>>>> Office:Schanzenstrasse 46, Room 321
>>> 
>> 
>> 
>> -- 
>> Frank Preiswerk, Senior Researcher
>> Medical Image Analysis Center (MIAC)
>> University of Basel c/o University Hospital Basel
>> Spitalstrasse 21
>> CH-4031 Basel
>> Switzerland
>> 
>> Tel: +41 61 265 96 58
>> Fax: +41 61 265 96 68
>> Office:Schanzenstrasse 46, Room 321
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20130803/0dcac47d/attachment.htm>


More information about the Insight-users mailing list