[Insight-users] On Interpolation and transform parameters

Luis Ibanez luis.ibanez@kitware.com
Thu, 26 Sep 2002 11:00:59 -0400


Hi cspl,


1) About initializing the parameters for registration:

Probably the easiest way to get a reasonable set of initial parameters
is to instantiate an AffineTransform, configure it manually and then
invoke its GetParameters() method.

Using the AffineTransform API
http://www.itk.org/Insight/Doxygen/html/classitk_1_1AffineTransform.html

You could do something like:


   typedef itk::AffineTransform< double, 3 > TransformType;
   TransformType::Pointer transform = TransformType::New();
   transform->SetIdentity();
   TransformType::OutputVectorType axis;
   axis[0] = 0.0;
   axis[1] = 0.0;
   axis[2] = 1.0;  // axis= vector parallel to the Z axis
   const double angle = 10;
   transform->Rotate( axis, angle );

   TransformType::OutputVectorType shift;
   shift[0] = 10;
   shift[1] = 15;
   shift[2] = 20;  // translation of (10,15,20)
   transform->Translate( shift );

   registration->SetInitialParameters(   transform->GetParameters() );




2) About the size problem between MRI and SPECT
    I still suspect that the problem is related with the spacing
    specified on the images.

    Let's consider the following case:

     A) MRI image of size {512,512,100}
        with pixel spacing in mm { 0.4, 0.4, 2.0 }
        The physical extent of this image in space is
        { 204.8 x 204.8 x 200 } millimeters.

     B) SPECT image of size { 64 64 64 }
        with pixel spacing in mm { 3.0, 3.0, 3.0 }
        The physical extent of this image in space is
        { 192.0 x 192.0 x 192.0 } millimeters.

     Even though the number of pixels in the SPECT
     image is much lower, the physical coverage is
     about the same as the MRI image.

     If you register this two images, the final transform
     will have a reduced scale component since the
     transformation is done in millimeters and not in
     pixel units.


     When the ResampleImage filter is applied to the SPECT
     image, points are sampled from the positions of a image
     with the spacing and size of the MRI image.  The physical
     coordinates of these points are transformed into the
     using the transform resulting from the registration process.

     The mapped points are in the space of the SPECT image (in
     millimeters).

     The interpolator hierarchy is as follows:

        itk::ImageFunction
                 |
        itk::InterpolateImageFunction
                 |
        itk::NearestNeighborInterpolateImageFunction

     When the Evaluate( PointType ) method is called, the interpolator
     takes the coordinates of the point, use the origin and spacing of
     the image being interpolated (in this case the SPECT) and compute
     the corresponding position in pixel indices.


      If the image spacing is not taken into account in one of the
      two processes the scale of the image will be missinterpreted.


  Could you please post the size (number of pixels along each dimension)
and spacing (value in millimeters between centers of neigbor pixels
along each dimension) for both your MRI and SPECT images ?

----

There is still the possibility that the registration is getting
stopped in a local minima early in the optimization process.
It is in fact suspicious that the final parameters are too close
to the initial parameters...

Do you have a way of posting screenshots of the MRI and  SPECT images ?
could you post a screenshot of the resampled SPECT ?
(probably not to the list since there is a 40K limit in emails
posted to the list... but if you could put it in a web site somewhere
it could be helpful to see what you are getting after the resampliing).


Thanks


    Luis


=============================================================

cspl wrote:
> Dear Mr.Luis,
>  I am working on registration.I have used Affinetranformation class for 
> transformation.My registration code is working fine and i could be able 
> to resample the image after registration.But,I have some doubts 
> regarding initial transform parameters and interpolation.I have observed 
> that registration output is dependent on Initial transform parameters.I 
> have some other tool to test the registration output.I could not get the 
> output matching with that tool.I think by setting Initial transform 
> parameters to some values we coud get the output.Because,the final 
> registration matrix is close to initial parmeters.I have no idea about 
> what these parameters hold.Please, tell me whether my opinion is correct 
> or not and tell me how to set these parameters.I am enclosing the 
> parameters i have tried.
> 
>  
> 
> case1:
>  
>    for(int i=1;i<12;i++)
>     initialParameters[i]=0.1;
>    initialParameters[3]=0.5;
>          initialParameters[5]=0.3;
>    initialParameters[0] = 1.0;
>    initialParameters[4] = 1.0;
>    initialParameters[8] = 1.0;   
> case2:
>  
>    for(int i=1;i<12;i++)
>     initialParameters[i]=0.0;
>    initialParameters[0] = 1.0;
>    initialParameters[4] = 1.0;
>    initialParameters[8] = 1.0;
> case 3:
>  
>    for(int i=1;i<12;i++)
>     initialParameters[i]=0.1;
>    initialParameters[3]=0.5;
>           initialParameters[5]=0.1;
>    initialParameters[0] = 1.0;
>    initialParameters[4] = 1.0;
>    initialParameters[8] = 1.0;
>    initialParameters[10]=0.3; 
>     
> 
>  
> 
>  I am having one more doubt regarding the role of interpolator in 
>   registration and resampling.when i registered MRI and SPECT(Mri as 
>   Fixed and SPECT as mooving) I could get the registered voilume equal 
>  to the fixed volume.But, the Images size is  decreasing.I am getting 
> small images.Please,tell me how i could solve  this problem and why it 
> is getting.I am enclosing resample code and  registration code also.
> 
>  
> 
> Registration code:
>   typedef OptimizerType::ScalesType ScalesType;
>      ScalesType parametersScales( transform->GetNumberOfParameters() );
>    
>     parametersScales.Fill( 1.0 );
>    
>     double scale = 1.0 / vnl_math_sqr( 500);
>       
>     for (int  j = 9; j < 12; j++ )
>     {
> 
>  
> 
>      parametersScales[j] = scale;
>     }
>    
>     optimizer->SetScales( parametersScales );
>    
>     // need to maximize for mutual information
>     optimizer->MaximizeOn();
> 
>  
> 
>     ////////////////////////////////////////////////////////////////////
>     //Set up the metric.
>        
> ////////////////////////////////////////////////////////////////////   
>     metric->SetMovingImageStandardDeviation(      
> movingImageStatisticsFilter->GetSigma() * 0.4 );
>     metric->SetFixedImageStandardDeviation(     
> fixedImageStatisticsFilter->GetSigma() * 0.4 );
>     metric->SetNumberOfSpatialSamples( 50);
>     metric->SetFixedImageRegion( fixedImage->GetBufferedRegion() );   
> 
>  
> 
> 
>       ////////////////////////////////////////////////////////////////////
>       // Set up the registrator.
>       ////////////////////////////////////////////////////////////////////
> 
>  
> 
>   // connect up the components
>    registration->SetMetric( metric );
>    registration->SetOptimizer( optimizer );
>    registration->SetTransform( transform );
>    registration->SetFixedImage(fixedImage );
>    registration->SetMovingImage( movingImage  );
>    registration->SetInterpolator( interpolator );
>  
>    // set initial parameters to identity
>    RegistrationType::ParametersType initialParameters(
>      transform->GetNumberOfParameters() );
> 
>  
> 
>    initialParameters.Fill( 0.0 );
>    for(int i=1;i<12;i++)
>     initialParameters[i]=0.1;
>    initialParameters[3]=0.5;
>          initialParameters[5]=0.3;
>    initialParameters[0] = 1.0;
>    initialParameters[4] = 1.0;
>    initialParameters[8] = 1.0;    
>  
>       registration->SetInitialTransformParameters( initialParameters );
>       optimizer->SetNumberOfIterations(4);
> 
>  
> 
>    try
>    {
>     registration->StartRegistration();    
> 
>  
> 
>    }catch(itk::ExceptionObject& Eo)
>    {   
>       AfxMessageBox(Eo.GetDescription());
>    return NULL;
>    } 
> 
>  
> 
>  
> 
>  
> 
>  
> 
>  
> 
> resample code:
> 
>  
> 
>     resampleFilter ->SetTransform(transform);
>     resampleFilter->SetInput(movingImage);   
> 
>  
> 
>     resampleFilter->SetSize( 
> mriImage->GetLargestPossibleRegion().GetSize());
>     resampleFilter->SetOutputOrigin( mriImage->GetOrigin() );
>     resampleFilter->SetOutputSpacing( mriImage->GetSpacing() );
>     resampleFilter->Update();
> 
>  
> 
> Regards,
> CSPL
>