[Insight-users] Segfault after StartRegistration

Luis Ibanez luis.ibanez at kitware.com
Mon Aug 22 19:12:33 EDT 2005


Hi Kevin,

Are you sure that the program Segfaulted ?

and not "Aborted" ( abort is what happens when an exception is
trhown and not catched)


Did you run the program in a debugger ?

Did you got any output from some initial iterations before
the problem appeared ? or did this happen during the computation
of the first iteration.


More information will be useful....



   Thanks


      Luis



----------------------
Kevin H. Hobbs wrote:
> I tried to swap out the optimizer in ImageRegistration5.cxx with the
> AmoebaOptimizer  as in ImageRegistration5.cxx. Some time after
> StartRegistration, the program segfaults.  I'm not sure what I might
> have missed, any ideas?  I'll try ddd but...
> 
> 
> ------------------------------------------------------------------------
> 
> /*=========================================================================
> 
>   Program:   Insight Segmentation & Registration Toolkit
>   Module:    $RCSfile: ImageRegistration5.cxx,v $
>   Language:  C++
>   Date:      $Date: 2005/06/18 21:51:51 $
>   Version:   $Revision: 1.41 $
> 
>   Copyright (c) Insight Software Consortium. All rights reserved.
>   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
> 
>      This software is distributed WITHOUT ANY WARRANTY; without even 
>      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
>      PURPOSE.  See the above copyright notices for more information.
> 
> =========================================================================*/
> #if defined(_MSC_VER)
> #pragma warning ( disable : 4786 )
> #endif
> 
> //  Software Guide : BeginCommandLineArgs
> //    INPUTS: {BrainProtonDensitySliceBorder20.png}
> //    INPUTS: {BrainProtonDensitySliceRotated10.png}
> //    OUTPUTS: {ImageRegistration5Output.png}
> //    OUTPUTS: {ImageRegistration5DifferenceAfter.png}
> //    OUTPUTS: {ImageRegistration5DifferenceBefore.png}
> //    0.1
> //  Software Guide : EndCommandLineArgs
> 
> //  Software Guide : BeginCommandLineArgs
> //    INPUTS: {BrainProtonDensitySliceBorder20.png}
> //    INPUTS: {BrainProtonDensitySliceR10X13Y17.png}
> //    OUTPUTS: {ImageRegistration5Output2.png}
> //    OUTPUTS: {ImageRegistration5DifferenceAfter2.png}
> //    OUTPUTS: {ImageRegistration5DifferenceBefore2.png}
> //    1.0
> //  Software Guide : EndCommandLineArgs
> 
> 
> // Software Guide : BeginLatex
> //
> // This example illustrates the use of the \doxygen{CenteredRigid2DTransform}
> // for performing rigid registration in $2D$. The example code is for the
> // most part identical to that presented in Section
> // \ref{sec:IntroductionImageRegistration}.  The main difference is the use
> // of the CenteredRigid2DTransform here instead of the
> // \doxygen{TranslationTransform}.
> //
> // \index{itk::CenteredRigid2DTransform}
> //
> // Software Guide : EndLatex 
> 
> #include "itkImageRegistrationMethod.h"
> #include "itkMeanSquaresImageToImageMetric.h"
> #include "itkLinearInterpolateImageFunction.h"
> #include "itkRegularStepGradientDescentOptimizer.h"
> #include "itkAmoebaOptimizer.h"
> #include "itkImage.h"
> 
> 
> //  Software Guide : BeginLatex
> //  
> //  In addition to the headers included in previous examples, the
> //  following header must also be included.
> //
> //  \index{itk::CenteredRigid2DTransform!header}
> // 
> //  Software Guide : EndLatex 
> 
> // Software Guide : BeginCodeSnippet
> #include "itkCenteredRigid2DTransform.h"
> // Software Guide : EndCodeSnippet
> 
> 
> #include "itkImageFileReader.h"
> #include "itkImageFileWriter.h"
> 
> #include "itkResampleImageFilter.h"
> #include "itkSubtractImageFilter.h"
> #include "itkRescaleIntensityImageFilter.h"
> 
> 
> //  The following section of code implements a Command observer
> //  that will monitor the evolution of the registration process.
> //
> #include "itkCommand.h"
> class CommandIterationUpdate : public itk::Command 
> {
> public:
>   typedef  CommandIterationUpdate   Self;
>   typedef  itk::Command             Superclass;
>   typedef itk::SmartPointer<Self>  Pointer;
>   itkNewMacro( Self );
> protected:
>   CommandIterationUpdate() {};
> public:
>   typedef itk::RegularStepGradientDescentOptimizer     OptimizerType;
>   typedef   const OptimizerType   *    OptimizerPointer;
> 
>   void Execute(itk::Object *caller, const itk::EventObject & event)
>     {
>       Execute( (const itk::Object *)caller, event);
>     }
> 
>   void Execute(const itk::Object * object, const itk::EventObject & event)
>     {
>       OptimizerPointer optimizer = 
>         dynamic_cast< OptimizerPointer >( object );
>       if( ! itk::IterationEvent().CheckEvent( &event ) )
>         {
>         return;
>         }
>       //std::cout << optimizer->GetCurrentIteration() << "   ";
>       std::cout << optimizer->GetValue() << "   ";
>       std::cout << optimizer->GetCurrentStepLength() << "   ";
>       std::cout << optimizer->GetCurrentPosition() << std::endl;
>     }
> };
> 
> 
> int main( int argc, char *argv[] )
> {
>   if( argc < 4 )
>     {
>     std::cerr << "Missing Parameters " << std::endl;
>     std::cerr << "Usage: " << argv[0];
>     std::cerr << " fixedImageFile  movingImageFile ";
>     std::cerr << " outputImagefile  [differenceAfterRegistration] ";
>     std::cerr << " [differenceBeforeRegistration] ";
>     std::cerr << " [initialStepLength] "<< std::endl;
>     return EXIT_FAILURE;
>     }
>   
>   const    unsigned int    Dimension = 2;
>   typedef  unsigned char   PixelType;
> 
>   typedef itk::Image< PixelType, Dimension >  FixedImageType;
>   typedef itk::Image< PixelType, Dimension >  MovingImageType;
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  The transform type is instantiated using the code below. The only
>   //  template parameter for this class is the representation type of the
>   //  space coordinates.
>   //
>   //  \index{itk::CenteredRigid2DTransform!Instantiation}
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   typedef itk::CenteredRigid2DTransform< double > TransformType;
>   
>   // Software Guide : EndCodeSnippet
> 
> 
>   //typedef itk::RegularStepGradientDescentOptimizer       OptimizerType;
>   typedef itk::AmoebaOptimizer       OptimizerType;
>   
>   typedef itk::MeanSquaresImageToImageMetric< 
>                                     FixedImageType, 
>                                     MovingImageType >    MetricType;
>   typedef itk:: LinearInterpolateImageFunction< 
>                                     MovingImageType,
>                                     double          >    InterpolatorType;
>   typedef itk::ImageRegistrationMethod< 
>                                     FixedImageType, 
>                                     MovingImageType >    RegistrationType;
> 
>   MetricType::Pointer         metric        = MetricType::New();
>   OptimizerType::Pointer      optimizer     = OptimizerType::New();
>   InterpolatorType::Pointer   interpolator  = InterpolatorType::New();
>   RegistrationType::Pointer   registration  = RegistrationType::New();
>   
>   registration->SetMetric(        metric        );
>   registration->SetOptimizer(     optimizer     );
>   registration->SetInterpolator(  interpolator  );
> 
> 
>   //  Software Guide : BeginLatex
>   //
>   //  The transform object is constructed below and passed to the registration
>   //  method.
>   //
>   //  \index{itk::CenteredRigid2DTransform!New()}
>   //  \index{itk::CenteredRigid2DTransform!Pointer}
>   //  \index{itk::RegistrationMethod!SetTransform()}
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   TransformType::Pointer  transform = TransformType::New();
>   registration->SetTransform( transform );
>   // Software Guide : EndCodeSnippet
> 
> 
>   typedef itk::ImageFileReader< FixedImageType  > FixedImageReaderType;
>   typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType;
> 
>   FixedImageReaderType::Pointer  fixedImageReader  = FixedImageReaderType::New();
>   MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New();
> 
>   fixedImageReader->SetFileName(  argv[1] );
>   movingImageReader->SetFileName( argv[2] );
> 
> 
>   registration->SetFixedImage(    fixedImageReader->GetOutput()    );
>   registration->SetMovingImage(   movingImageReader->GetOutput()   );
>   fixedImageReader->Update();
> 
>   registration->SetFixedImageRegion( 
>      fixedImageReader->GetOutput()->GetBufferedRegion() );
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  In this example, the input images are taken from readers. The code
>   //  below updates the readers in order to ensure that the image parameters
>   //  (size, origin and spacing) are valid when used to initialize the
>   //  transform.  We intend to use the center of the fixed image as the
>   //  rotation center and then use the vector between the fixed image center
>   //  and the moving image center as the initial translation to be applied
>   //  after the rotation.
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   fixedImageReader->Update();
>   movingImageReader->Update();
>   // Software Guide : EndCodeSnippet
> 
>   typedef FixedImageType::SpacingType    SpacingType;
>   typedef FixedImageType::PointType      OriginType;
>   typedef FixedImageType::RegionType     RegionType;
>   typedef FixedImageType::SizeType       SizeType;
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  The center of rotation is computed using the origin, size and spacing of
>   //  the fixed image.
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput();
> 
>   const SpacingType fixedSpacing = fixedImage->GetSpacing();
>   const OriginType  fixedOrigin  = fixedImage->GetOrigin();
>   const RegionType  fixedRegion  = fixedImage->GetLargestPossibleRegion(); 
>   const SizeType    fixedSize    = fixedRegion.GetSize();
>   
>   TransformType::InputPointType centerFixed;
>   
>   centerFixed[0] = fixedOrigin[0] + fixedSpacing[0] * fixedSize[0] / 2.0;
>   centerFixed[1] = fixedOrigin[1] + fixedSpacing[1] * fixedSize[1] / 2.0;
>   // Software Guide : EndCodeSnippet
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  The center of the moving image is computed in a similar way.
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   MovingImageType::Pointer movingImage = movingImageReader->GetOutput();
> 
>   const SpacingType movingSpacing = movingImage->GetSpacing();
>   const OriginType  movingOrigin  = movingImage->GetOrigin();
>   const RegionType  movingRegion  = movingImage->GetLargestPossibleRegion();
>   const SizeType    movingSize    = movingRegion.GetSize();
>   
>   TransformType::InputPointType centerMoving;
>   
>   centerMoving[0] = movingOrigin[0] + movingSpacing[0] * movingSize[0] / 2.0;
>   centerMoving[1] = movingOrigin[1] + movingSpacing[1] * movingSize[1] / 2.0;
>   // Software Guide : EndCodeSnippet
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //   The most straightforward method of initializing the transform parameters
>   //   is to configure the transform and then get its parameters with the
>   //   method \code{GetParameters()}. Here we initialize the transform by
>   //   passing the center of the fixed image as the rotation center with the
>   //   \code{SetCenter()} method. Then the translation is set as the vector
>   //   relating the center of the moving image to the center of the fixed
>   //   image.  This last vector is passed with the method
>   //   \code{SetTranslation()}.
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   transform->SetCenter( centerFixed );
>   transform->SetTranslation( centerMoving - centerFixed );
>   // Software Guide : EndCodeSnippet
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  Let's finally initialize the rotation with a zero angle.
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   transform->SetAngle( 0.0 );
>   // Software Guide : EndCodeSnippet
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  Now we pass the current transform's parameters as the initial
>   //  parameters to be used when the registration process starts.
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   registration->SetInitialTransformParameters( transform->GetParameters() );
>   // Software Guide : EndCodeSnippet
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  Keeping in mind that the scale of units in rotation and translation is
>   //  quite different, we take advantage of the scaling functionality provided
>   //  by the optimizers. We know that the first element of the parameters array
>   //  corresponds to the angle that is measured in radians, while the other
>   //  parameters correspond to translations that are measured in millimeters.
>   //  For this reason we use small factors in the scales associated with
>   //  translations and the coordinates of the rotation center .
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   /*
>   typedef OptimizerType::ScalesType       OptimizerScalesType;
>   OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() );
>   const double translationScale = 1.0 / 1000.0;
> 
>   optimizerScales[0] = 1.0;
>   optimizerScales[1] = translationScale;
>   optimizerScales[2] = translationScale;
>   optimizerScales[3] = translationScale;
>   optimizerScales[4] = translationScale;
> 
>   optimizer->SetScales( optimizerScales );
>   */
>   // Software Guide : EndCodeSnippet
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  Next we set the normal parameters of the optimization method. In this
>   //  case we are using an \doxygen{RegularStepGradientDescentOptimizer}.
>   //  Below, we define the optimization parameters like the relaxation factor,
>   //  initial step length, minimal step length and number of iterations. These
>   //  last two act as stopping criteria for the optimization.
>   //
>   //  \index{Regular\-Step\-Gradient\-Descent\-Optimizer!SetRelaxationFactor()}
>   //  \index{Regular\-Step\-Gradient\-Descent\-Optimizer!SetMaximumStepLength()}
>   //  \index{Regular\-Step\-Gradient\-Descent\-Optimizer!SetMinimumStepLength()}
>   //  \index{Regular\-Step\-Gradient\-Descent\-Optimizer!SetNumberOfIterations()}
>   //
>   //  Software Guide : EndLatex 
> 
>   // Software Guide : BeginCodeSnippet
>   /*
>   double initialStepLength = 0.001;
>   // Software Guide : EndCodeSnippet
> 
>   if( argc > 6 )
>     {
>     initialStepLength = atof( argv[6] );
>     }
> 
>   // Software Guide : BeginCodeSnippet
>   optimizer->SetRelaxationFactor( 0.6 );
>   optimizer->SetMaximumStepLength( initialStepLength * 100.0); 
>   optimizer->SetMinimumStepLength( 0.001 );
>   optimizer->SetNumberOfIterations( 2000 );
>   */
>   // Software Guide : EndCodeSnippet
>   
>   OptimizerType::ParametersType
>     simplexDelta( transform->GetNumberOfParameters() );
>   simplexDelta.Fill( 5.0 );
>   //simplexDelta[0] = 0.001;
> 
>   optimizer->AutomaticInitialSimplexOff();
>   optimizer->SetInitialSimplexDelta( simplexDelta );
> 
>   optimizer->SetParametersConvergenceTolerance( 0.25 ); // quarter pixel
>   optimizer->SetFunctionConvergenceTolerance(0.001); // 0.1%
> 
>   optimizer->SetMaximumNumberOfIterations( 2000 );
>   
>   // Create the Command observer and register it with the optimizer.
>   //
>   CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
>   optimizer->AddObserver( itk::IterationEvent(), observer );
> 
>   std::cerr << "Got Here" << std::endl;
>   
>   try 
>     { 
>     registration->StartRegistration(); 
>     } 
>   catch( itk::ExceptionObject & err ) 
>     { 
>     std::cerr << "ExceptionObject caught !" << std::endl; 
>     std::cerr << err << std::endl; 
>     return EXIT_FAILURE;
>     } 
>   
>   OptimizerType::ParametersType finalParameters = 
>                     registration->GetLastTransformParameters();
> 
>   const double finalAngle           = finalParameters[0];
>   const double finalRotationCenterX = finalParameters[1];
>   const double finalRotationCenterY = finalParameters[2];
>   const double finalTranslationX    = finalParameters[3];
>   const double finalTranslationY    = finalParameters[4];
> 
>   //const unsigned int numberOfIterations = optimizer->GetCurrentIteration();
> 
>   const double bestValue = optimizer->GetValue();
> 
> 
>   // Print out results
>   //
>   const double finalAngleInDegrees = finalAngle * 45.0 / atan(1.0);
> 
>   std::cout << "Result = " << std::endl;
>   std::cout << " Angle (radians)   = " << finalAngle  << std::endl;
>   std::cout << " Angle (degrees)   = " << finalAngleInDegrees  << std::endl;
>   std::cout << " Center X      = " << finalRotationCenterX  << std::endl;
>   std::cout << " Center Y      = " << finalRotationCenterY  << std::endl;
>   std::cout << " Translation X = " << finalTranslationX  << std::endl;
>   std::cout << " Translation Y = " << finalTranslationY  << std::endl;
>   //std::cout << " Iterations    = " << numberOfIterations << std::endl;
>   std::cout << " Metric value  = " << bestValue          << std::endl;
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  Let's execute this example over two of the images provided in
>   //  \code{Examples/Data}:
>   //  
>   //  \begin{itemize}
>   //  \item \code{BrainProtonDensitySliceBorder20.png} 
>   //  \item \code{BrainProtonDensitySliceRotated10.png}
>   //  \end{itemize}
>   //
>   //  The second image is the result of intentionally rotating the first image
>   //  by $10$ degrees around the geometrical center of the image. Both images
>   //  have unit-spacing and are shown in Figure
>   //  \ref{fig:FixedMovingImageRegistration5}. The registration takes $20$
>   //  iterations and produces the results:
>   //
>   //  \begin{center}
>   //  \begin{verbatim}
>   //  [0.177458, 110.489, 128.488, 0.0106296, 0.00194103]
>   //  \end{verbatim}
>   //  \end{center}
>   //
>   //  These results are interpreted as
>   //
>   //  \begin{itemize}
>   //  \item Angle         =                  $0.177458$     radians
>   //  \item Center        = $( 110.489    , 128.488      )$ millimeters
>   //  \item Translation   = $(   0.0106296,   0.00194103 )$ millimeters
>   //  \end{itemize}
>   // 
>   //  As expected, these values match the misalignment intentionally introduced
>   //  into the moving image quite well, since $10$ degrees is about $0.174532$
>   //  radians.
>   //
>   // \begin{figure}
>   // \center
>   // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceBorder20.eps}
>   // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceRotated10.eps}
>   // \itkcaption[Rigid2D Registration input images]{Fixed and moving images
>   // are provided as input to the registration method using the CenteredRigid2D
>   // transform.}
>   // \label{fig:FixedMovingImageRegistration5}
>   // \end{figure}
>   //
>   //
>   // \begin{figure}
>   // \center
>   // \includegraphics[width=0.32\textwidth]{ImageRegistration5Output.eps}
>   // \includegraphics[width=0.32\textwidth]{ImageRegistration5DifferenceBefore.eps}
>   // \includegraphics[width=0.32\textwidth]{ImageRegistration5DifferenceAfter.eps} 
>   // \itkcaption[Rigid2D Registration output images]{Resampled moving image
>   // (left). Differences between the fixed and moving images, before (center) 
>   // and after (right) registration using the CenteredRigid2D transform.}
>   // \label{fig:ImageRegistration5Outputs}
>   // \end{figure}
>   //
>   // Figure \ref{fig:ImageRegistration5Outputs} shows from left to right the
>   // resampled moving image after registration, the difference between fixed
>   // and moving images before registration, and the difference between fixed
>   // and resampled moving image after registration. It can be seen from the
>   // last difference image that the rotational component has been solved but
>   // that a small centering misalignment persists.
>   //
>   // \begin{figure}
>   // \center
>   // \includegraphics[height=0.32\textwidth]{ImageRegistration5TraceMetric1.eps}
>   // \includegraphics[height=0.32\textwidth]{ImageRegistration5TraceAngle1.eps}
>   // \includegraphics[height=0.32\textwidth]{ImageRegistration5TraceTranslations1.eps} 
>   // \itkcaption[Rigid2D Registration output plots]{Metric values, rotation
>   // angle and translations during registration with the CenteredRigid2D
>   // transform.}
>   // \label{fig:ImageRegistration5Plots}
>   // \end{figure}
>   //
>   //  Figure \ref{fig:ImageRegistration5Plots} shows plots of the main output
>   //  parameters produced from the registration process. This includes, the
>   //  metric values at every iteration, the angle values at every iteration,
>   //  and the translation components of the transform as the registration
>   //  progress.
>   //
>   //  Software Guide : EndLatex 
> 
> 
>   typedef itk::ResampleImageFilter< 
>                             MovingImageType, 
>                             FixedImageType >    ResampleFilterType;
> 
>   TransformType::Pointer finalTransform = TransformType::New();
> 
>   finalTransform->SetParameters( finalParameters );
> 
>   ResampleFilterType::Pointer resample = ResampleFilterType::New();
> 
>   resample->SetTransform( finalTransform );
>   resample->SetInput( movingImageReader->GetOutput() );
> 
>   resample->SetSize(    fixedImage->GetLargestPossibleRegion().GetSize() );
>   resample->SetOutputOrigin(  fixedImage->GetOrigin() );
>   resample->SetOutputSpacing( fixedImage->GetSpacing() );
>   resample->SetDefaultPixelValue( 0 );
>   
>   typedef itk::ImageFileWriter< FixedImageType >  WriterFixedType;
> 
>   WriterFixedType::Pointer      writer =  WriterFixedType::New();
> 
>   writer->SetFileName( argv[3] );
> 
>   writer->SetInput( resample->GetOutput()   );
> 
>   try
>     {
>     writer->Update();
>     }
>   catch( itk::ExceptionObject & excp )
>     { 
>     std::cerr << "ExceptionObject while writing the resampled image !" << std::endl; 
>     std::cerr << excp << std::endl; 
>     return EXIT_FAILURE;
>     } 
> 
> 
> 
>   typedef itk::Image< float, Dimension > DifferenceImageType;
> 
>   typedef itk::SubtractImageFilter< 
>                            FixedImageType, 
>                            FixedImageType, 
>                            DifferenceImageType > DifferenceFilterType;
> 
>   DifferenceFilterType::Pointer difference = DifferenceFilterType::New();
> 
>   typedef  unsigned char  OutputPixelType;
> 
>   typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
>   
>   typedef itk::RescaleIntensityImageFilter< 
>                                   DifferenceImageType, 
>                                   OutputImageType >   RescalerType;
> 
>   RescalerType::Pointer intensityRescaler = RescalerType::New();
> 
>   intensityRescaler->SetOutputMinimum(   0 );
>   intensityRescaler->SetOutputMaximum( 255 );
> 
>   difference->SetInput1( fixedImageReader->GetOutput() );
>   difference->SetInput2( resample->GetOutput() );
> 
>   resample->SetDefaultPixelValue( 0 );
> 
>   intensityRescaler->SetInput( difference->GetOutput() );  
> 
>   typedef itk::ImageFileWriter< OutputImageType >  WriterType;
> 
>   WriterType::Pointer      writer2 =  WriterType::New();
> 
>   writer2->SetInput( intensityRescaler->GetOutput() );
> 
> 
>   try
>     {
>     // Compute the difference image between the 
>     // fixed and moving image after registration.
>     if( argc > 4 )
>       {
>       writer2->SetFileName( argv[4] );
>       writer2->Update();
>       }
> 
>     // Compute the difference image between the 
>     // fixed and resampled moving image after registration.
>     TransformType::Pointer identityTransform = TransformType::New();
>     identityTransform->SetIdentity();
>     resample->SetTransform( identityTransform );
>     if( argc > 5 )
>       {
>       writer2->SetFileName( argv[5] );
>       writer2->Update();
>       }
>     }
>   catch( itk::ExceptionObject & excp )
>     {
>     std::cerr << "Error while writing difference images" << std::endl;
>     std::cerr << excp << std::endl;
>     return EXIT_FAILURE;
>     }
> 
> 
> 
> 
> 
>   //  Software Guide : BeginLatex
>   //  
>   //  Let's now consider the case in which rotations and translations are
>   //  present in the initial registration, as in the following pair
>   //  of images:
>   //  
>   //  \begin{itemize}
>   //  \item \code{BrainProtonDensitySliceBorder20.png} 
>   //  \item \code{BrainProtonDensitySliceR10X13Y17.png}
>   //  \end{itemize}
>   //
>   //  The second image is the result of intentionally rotating the first image
>   //  by $10$ degrees and then translating it $13mm$ in $X$ and $17mm$ in $Y$.
>   //  Both images have unit-spacing and are shown in Figure
>   //  \ref{fig:FixedMovingImageRegistration5b}. In order to accelerate
>   //  convergence it is convenient to use a larger step length as shown here.
>   //
>   //  \code{optimizer->SetMaximumStepLength( 1.0 );}
>   //
>   //  The registration now takes $46$ iterations and produces the following
>   //  results:
>   //
>   //  \begin{center}
>   //  \begin{verbatim}
>   //  [0.174454, 110.361, 128.647, 12.977, 15.9761]
>   //  \end{verbatim}
>   //  \end{center}
>   //
>   //  These parameters are interpreted as
>   //
>   //  \begin{itemize}
>   //  \item Angle         =                     $0.174454$   radians
>   //  \item Center        = $( 110.361     , 128.647      )$ millimeters
>   //  \item Translation   = $(  12.977     ,  15.9761     )$ millimeters
>   //  \end{itemize}
>   //  
>   //  These values approximately match the initial misalignment intentionally
>   //  introduced into the moving image, since $10$ degrees is about $0.174532$
>   //  radians. The horizontal translation is well resolved while the vertical
>   //  translation ends up being off by about one millimeter.
>   //
>   // \begin{figure}
>   // \center
>   // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceBorder20.eps}
>   // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceR10X13Y17.eps}
>   // \itkcaption[Rigid2D Registration input images]{Fixed and moving images
>   // provided as input to the registration method using the CenteredRigid2D
>   // transform.}
>   // \label{fig:FixedMovingImageRegistration5b}
>   // \end{figure}
>   //
>   //
>   // \begin{figure}
>   // \center
>   // \includegraphics[width=0.32\textwidth]{ImageRegistration5Output2.eps}
>   // \includegraphics[width=0.32\textwidth]{ImageRegistration5DifferenceBefore2.eps}
>   // \includegraphics[width=0.32\textwidth]{ImageRegistration5DifferenceAfter2.eps} 
>   // \itkcaption[Rigid2D Registration output images]{Resampled moving image
>   // (left). Differences between the fixed and moving images, before (center) 
>   // and after (right) registration with the CenteredRigid2D transform.}
>   // \label{fig:ImageRegistration5Outputs2}
>   // \end{figure}
>   //
>   // Figure \ref{fig:ImageRegistration5Outputs2} shows the output of the
>   // registration. The rightmost image of this figure shows the difference
>   // between the fixed image and the resampled moving image after registration. 
>   //
>   // \begin{figure}
>   // \center
>   // \includegraphics[height=0.32\textwidth]{ImageRegistration5TraceMetric2.eps}
>   // \includegraphics[height=0.32\textwidth]{ImageRegistration5TraceAngle2.eps}
>   // \includegraphics[height=0.32\textwidth]{ImageRegistration5TraceTranslations2.eps} 
>   // \itkcaption[Rigid2D Registration output plots]{Metric values, rotation
>   // angle and translations during the registration using the CenteredRigid2D
>   // transform on an image with rotation and translation mis-registration.}
>   // \label{fig:ImageRegistration5Plots2}
>   // \end{figure}
>   //
>   //  Figure \ref{fig:ImageRegistration5Plots2} shows plots of the main output
>   //  registration parameters when the rotation and translations are combined.
>   //  These results include, the metric values at every iteration, the angle
>   //  values at every iteration, and the translation components of the
>   //  registration as the registration converges. It can be seen from the
>   //  smoothness of these plots that a larger step length could have been
>   //  supported easily by the optimizer. You may want to modify this value in
>   //  order to get a better idea of how to tune the parameters.
>   //
>   //  Software Guide : EndLatex 
> 
> 
>   return EXIT_SUCCESS;
> }
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users



More information about the Insight-users mailing list