MantisBT - ITK
View Issue Details
0009709ITKpublic2009-10-13 18:532010-10-21 12:31
Kishore Mosaliganti 
Luis Ibanez 
normalmajoralways
closedfixed 
ITK-3-16 
 
0009709: Isotropic image spacing in itkLevelsetMotionRegistrationImageFilter
Hi all,

I was using the LevelsetMotionRegistrationImageFilter to register two 3D image datasets whose voxels have anisotropic spacing:

  RegistrationFilterType::Pointer filter = RegistrationFilterType::New();
  CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
  filter->AddObserver( itk::IterationEvent(), observer );
  filter->SetFixedImage( fixedImage );
  filter->SetMovingImage( movingImage );
  filter->SetNumberOfIterations( 50 );
  filter->SetGradientSmoothingStandardDeviations( 0.1 );
  filter->UseImageSpacingOn();
  filter->Update();

The problem is I get a Segmentation fault when I turn on UseImageSpacingOn(). Otherwise, the filter executes normally.

I used the debugger and went into the code. LevelsetMotionRegistrationImageFilter is a sub-class of itkPDEDeformableRegistrationImageFilter which is a subclass of itkFiniteDifferenceImageFilter. The code failed in the itkFiniteDifferenceImageFilter::GenerateData() method in the following lines:

....

if (this->GetState() == UNINITIALIZED)
    {
    // Set the coefficients for the deriviatives
    double coeffs[TInputImage::ImageDimension];
    if (m_UseImageSpacing)
      {
      for (unsigned int i = 0; i < TInputImage::ImageDimension; i++)
        {
        coeffs[i] = 1.0 / this->GetInput()->GetSpacing()[i];
        }
      }
    else
      {
      for (unsigned int i = 0; i < TInputImage::ImageDimension; i++)
        {
        coeffs[i] = 1.0;
        }
      }

.....

When I went to see the state of the input pointer, this->m_Input has 3 image pointers. Basically, this->m_Input[1] refers to the fixed image and this->m_Input[2] refers to the moving image. this->m_Input[0] is NULL.

The code in itkPDEDeformableRegistrationImageFilter::SetFixedImage() and itkPDEDeformableRegistrationImageFilter::SetMovingImage() incorrectly call

this->ProcessObject::SetNthInput( 1, const_cast< FixedImageType * >( ptr ) ) and this->ProcessObject::SetNthInput( 2, const_cast< FixedImageType * >( ptr ) ) respectively.

Clearly, the indices need to be 0 and 1.
No tags attached.
Issue History
2009-10-13 18:53Kishore MosaligantiNew Issue
2009-10-17 17:22Luis IbanezStatusnew => assigned
2009-10-17 17:22Luis IbanezAssigned To => Luis Ibanez
2009-10-17 17:23Luis IbanezNote Added: 0018095
2009-10-17 17:44Luis IbanezNote Added: 0018096
2009-10-17 18:09Kishore MosaligantiNote Added: 0018097
2009-10-19 09:16Luis IbanezNote Added: 0018103
2009-10-19 09:28Luis IbanezNote Added: 0018104
2009-10-19 11:34Luis IbanezNote Added: 0018108
2009-10-19 11:35Luis IbanezNote Added: 0018109
2009-10-19 11:35Luis IbanezStatusassigned => resolved
2009-10-19 11:35Luis IbanezResolutionopen => fixed
2009-10-20 16:41Luis IbanezNote Added: 0018130
2010-10-21 12:31Gabe HartStatusresolved => closed

Notes
(0018095)
Luis Ibanez   
2009-10-17 17:23   
The LevelSetMotionRegistrationFilter doesn't have a test.
We will start by adding one...
(0018096)
Luis Ibanez   
2009-10-17 17:44   
A new test was added:
http://public.kitware.com/cgi-bin/viewcvs.cgi/Testing/Code/Algorithms/itkLevelSetMotionRegistrationFilterTest.cxx?root=Insight&sortby=date&view=log [^]

When running this test, the filter seems to run fine.

We have not been able to replicate the reported bug, so far.
(0018097)
Kishore Mosaliganti   
2009-10-17 18:09   
If there is no initial deformation field, even then the filter expects you to set a 0 deformation field.

In the added test, this corresponds to the statement
registrator->SetInitialDeformationField( caster->GetOutput() );

If this statement were not there for a case where we don't have an initial deformation field, then the test fails.

Furthermore, the observed outputs don't change when we turn the UseImageSpacingOn().
(0018103)
Luis Ibanez   
2009-10-19 09:16   
The problem has been replicated in the Dashboard.
(0018104)
Luis Ibanez   
2009-10-19 09:28   
Fixed the Segmentation fault in the itkFiniteDifferenceImageFilter:

http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/Common/itkFiniteDifferenceImageFilter.txx?root=Insight&r1=1.48&r2=1.49&sortby=date [^]

Due to a lack of checking for NULL in the pointer of the Input.

There is still the question of: why did the execution get to the GenerateData() method, if the inputs are supposed to be tested before calling this method ?
(0018108)
Luis Ibanez   
2009-10-19 11:34   
The problem has been fixed in two steps:

1) Computation of coefficients has been moved to a dedicated method:
http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/Common/itkFiniteDifferenceImageFilter.txx?root=Insight&r1=1.49&r2=1.50&sortby=date [^]

and

2) Replacing the use of the Input image with the Output image, as the source of spacing information:
http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/Common/itkFiniteDifferenceImageFilter.txx?root=Insight&r1=1.50&r2=1.51&sortby=date [^]

In this way, even when the filter is used without an Input, it should be able to get access to spacing data.
(0018109)
Luis Ibanez   
2009-10-19 11:35   
With the committed changes, the test passes.
(0018130)
Luis Ibanez   
2009-10-20 16:41   
Kishore pointed out a remaining problem in the LevelSetMotionFunction:
http://www.itk.org/mailman/private/insight-developers/2009-October/013498.html [^]

This has been fixed with the following CVS commits:

http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/Algorithms/itkLevelSetMotionRegistrationFilter.txx?root=Insight&r1=1.6&r2=1.7&sortby=date [^]

http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/Algorithms/itkLevelSetMotionRegistrationFunction.txx?root=Insight&r1=1.6&r2=1.7&sortby=date [^]

http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/Algorithms/itkLevelSetMotionRegistrationFunction.h?root=Insight&r1=1.4&r2=1.5&sortby=date [^]