[Insight-users] Bspline artefact multi resolution - origin offset -	Bug?
    Emma Saunders 
    emmasaunders123 at gmail.com
       
    Wed Dec 11 17:26:16 EST 2013
    
    
  
Hi everyone
I appear to be getting a step artefact at the boundaries of my registered
image, using a multi-resolution Bspline approach.  The distance of the
artefact co-indices with the origin of the original image.  I can't seem to
find why this occurs.  I set the Bspline grid wrt the original fixed image
so unsure why this is happening.
I would really appreciate any advice:
Below is the code if anyone is interested:
 Many Thanks
Emma
#include "itkMedianImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkImageRegistrationMethod.h"
#include "itkTimeProbesCollectorBase.h"
#include "itkSpatialObjectToImageFilter.h"
#include "itkEllipseSpatialObject.h"
#include "itkRegularStepGradientDescentOptimizer.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRegularStepGradientDescentOptimizer.h"
#include "itkAffineTransform.h"
#include "itkBSplineDeformableTransform.h" //version 3
#include "itkMattesMutualInformationImageToImageMetric.h"
#include "itkTimeProbesCollectorBase.h"
#include "itkMemoryProbesCollectorBase.h"
#include <itkHistogramMatchingImageFilter.h>
#include "itkBSplineResampleImageFunction.h"
#include "itkLBFGSBOptimizer.h"
#include "itkMattesMutualInformationImageToImageMetric.h"
#include "itkLBFGSOptimizer.h"
#include "itkImageFileWriter.h"
#include "itkResampleImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkSquaredDifferenceImageFilter.h"
#include "itkBSplineResampleImageFunction.h"
#include "itkIdentityTransform.h"
#include "itkBSplineDecompositionImageFilter.h"
#include "itkCommand.h"
#include <fstream>
#include "itkCommand.h"
unsigned int Counter = 0;
unsigned int Countold = 0;
//This is for the affine registration
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->GetValue() << "   " <<std::endl;
    }
};
//This is for B spline
   class BCommandIterationUpdate : public itk::Command
  {
  public:
    typedef  BCommandIterationUpdate                     Self;
    typedef  itk::Command                               Superclass;
    typedef  itk::SmartPointer<BCommandIterationUpdate>  Pointer;
    itkNewMacro( BCommandIterationUpdate );
  protected:
    BCommandIterationUpdate() {};
  public:
  typedef itk::LBFGSBOptimizer    OptimizerType;
  typedef   const OptimizerType *                  OptimizerPointer;
  public:
    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)
      {
const OptimizerPointer  optimizer =
                      dynamic_cast< OptimizerPointer >( object );
        if( !(itk::IterationEvent().CheckEvent( &event )) )
          {
          return;
          }
        Countold=Counter;
        Counter = optimizer->GetCurrentIteration();
        if (Counter!=Countold)
        {
        std::cout  <<  optimizer->GetValue() << " " <<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::endl;
    std::cerr << "   outputImagefile" << std::endl;
     std::cerr << "   outputDeformationField " << std::endl;
    return EXIT_FAILURE;
    }
 // READ AND CREATE THE IMAGES AND DISPLACEMENT FIELD
  const    unsigned int    Dimension = 3;
  typedef float        PixelType;
  typedef itk::Vector< double, 3 >           VectorPixelType;
  typedef itk::Image< PixelType, Dimension >  FixedImageType;
  typedef itk::Image< PixelType, Dimension >  MovingImageType;
  typedef itk::Image< PixelType, Dimension >  OutputImageType;
  typedef itk::Image<  VectorPixelType, 3 > DisplacementFieldType;
  typedef itk::ImageFileReader< FixedImageType  > FixedImageReaderType;
  typedef itk::ImageFileReader< MovingImageType > MovingImageReaderType;
  typedef itk::ImageFileWriter< OutputImageType >  ImageWriterType;
  typedef itk::ImageFileWriter< DisplacementFieldType >  FieldWriterType;
  typedef itk::ImageFileWriter< DisplacementFieldType >  FieldWriterType;
  FieldWriterType::Pointer FieldWriter = FieldWriterType::New();
  FixedImageReaderType::Pointer  FixedImageReader  =
FixedImageReaderType::New();
  MovingImageReaderType::Pointer MovingImageReader =
MovingImageReaderType::New();
  ImageWriterType::Pointer ImageWriter = ImageWriterType::New();
  FixedImageReader->SetFileName(  argv[1] );
  MovingImageReader->SetFileName( argv[2] );
  ImageWriter->SetFileName( argv[3] );
  FieldWriter->SetFileName( argv[4] );
  FixedImageType::Pointer FixedImage = FixedImageReader->GetOutput();
  MovingImageType::Pointer MovedImage = MovingImageReader->GetOutput();
  OutputImageType::Pointer OutImage = OutputImageType::New();
  DisplacementFieldType::Pointer DeformField = DisplacementFieldType::New();
  std::cout << "First Fixed Image origin is " << FixedImage->GetOrigin() <<
std::endl ;
  FixedImage->Update();
  MovedImage->Update();
  //Median and Gaussian Filter
 typedef itk::MedianImageFilter<FixedImageType, FixedImageType > FilterType;
  // Create and setup a median filter
  FilterType::Pointer medianFilterFixed = FilterType::New();
  FilterType::InputSizeType radius;
  radius.Fill(1);
  medianFilterFixed->SetRadius(radius);
  medianFilterFixed->SetInput( FixedImage );
  medianFilterFixed->Update();
   FilterType::Pointer medianFilterMoved = FilterType::New();
  medianFilterMoved->SetRadius(radius);
  medianFilterMoved->SetInput( MovedImage );
  medianFilterMoved->Update();
  typedef itk::DiscreteGaussianImageFilter<
                                      FixedImageType,
                                      FixedImageType
                                                    > GaussianFilterType;
  GaussianFilterType::Pointer fixedSmoother  = GaussianFilterType::New();
  GaussianFilterType::Pointer movingSmoother = GaussianFilterType::New();
  fixedSmoother->SetVariance(1.0 );
  movingSmoother->SetVariance(1.0 );
  fixedSmoother->SetInput(  medianFilterFixed->GetOutput() );
  movingSmoother->SetInput ( medianFilterMoved->GetOutput() );
  fixedSmoother->Update();
  movingSmoother->Update();
   std::cout<< "The fixed origin is " <<
fixedSmoother->GetOutput()->GetOrigin() <<std::endl;
   std::cout << "Fixed Image origin is " << FixedImage->GetOrigin() <<
std::endl ;
//Define the transformations to be used
//PERFROM AN INITIAL AFFINE
  typedef itk::AffineTransform<
                                  double,
                                  Dimension  >     AffineTransformType;
//This will be followed by Bspline
  const unsigned int SpaceDimension = Dimension;
  const unsigned int SplineOrder = 3;
  typedef double CoordinateRepType;
  typedef itk::BSplineDeformableTransform<
                            CoordinateRepType,
                            SpaceDimension,
                            SplineOrder >     DeformableTransformType;
//version 3
 //Now for the Optimizer, Metric and Interpolatror  and Registration
 //which are connected to the registration
 //typedef itk::LBFGSOptimizer       bOptimizerType;
  typedef itk::LBFGSBOptimizer       bOptimizerType;
   bOptimizerType::Pointer      boptimizer     = bOptimizerType::New();
 typedef itk::RegularStepGradientDescentOptimizer       OptimizerType;
  typedef itk::MattesMutualInformationImageToImageMetric<
                                    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();
  // Setup the metric parameters
  metric->ReinitializeSeed( 76926294 );
  metric->SetUseCachingOfBSplineWeights(1);
    const unsigned long numberOfImagePixels =
    FixedImage->GetLargestPossibleRegion().GetNumberOfPixels();
      const unsigned long numberOfSpatialSamplesAffine =
    static_cast<unsigned long>( numberOfImagePixels * 1 );
  metric->SetNumberOfSpatialSamples( numberOfSpatialSamplesAffine );
  metric->SetNumberOfHistogramBins( 40 ); // Reduce the number of bins if a
deformable registration fails. If the number of bins is too large, the
estimated PDFs will be a field of impulses and will inhibit reliable
registration estimation.
  registration->SetMetric(        metric        );
  registration->SetOptimizer(     optimizer     );
  registration->SetInterpolator(  interpolator  );
//create the Affine transform
  AffineTransformType::Pointer  Affinetransform =
AffineTransformType::New();
  registration->SetTransform( Affinetransform );
//input the images
  registration->SetFixedImage(fixedSmoother->GetOutput());
  registration->SetMovingImage(movingSmoother->GetOutput());
//input the region
  registration->SetFixedImageRegion(FixedImage->GetBufferedRegion() );
//set the initial parameters
  typedef RegistrationType::ParametersType AffineParametersType;
  AffineParametersType initialParameters(
Affinetransform->GetNumberOfParameters() );
  Affinetransform->SetIdentity();
  registration->SetInitialTransformParameters(
                             Affinetransform->GetParameters() );
//set scale values for optimizer to search sensibly and set up optimizer
  typedef OptimizerType::ScalesType       OptimizerScalesType;
  OptimizerScalesType optimizerScales(
Affinetransform->GetNumberOfParameters() );
  FixedImageType:: SpacingType fixedspacing = FixedImage->GetSpacing();
  FixedImageType::RegionType region=FixedImage->GetLargestPossibleRegion();
  const unsigned int numberOfPixels = region.GetNumberOfPixels();
  FixedImageType:: SizeType fixedsize =region.GetSize();
  double translationScalea = 1.0 /( 10.0 * fixedspacing[0]  *  fixedsize[0]
 );
  double translationScaleb = 1.0 /( 10.0 * fixedspacing[1]  *  fixedsize[1]
 );
  double translationScalec = 1.0 /( 10.0 * fixedspacing[2]  *  fixedsize[2]
 );
//for 3D use below
  optimizerScales[0] =  1.0;
  optimizerScales[1] =  1.0;
  optimizerScales[2] =  1.0;
  optimizerScales[3] =  1.0;
  optimizerScales[4] =  1.0;
  optimizerScales[5] =  1.0;
  optimizerScales[6] =  1.0;
  optimizerScales[7] =  1.0;
  optimizerScales[8] =  1.0;
  optimizerScales[9]  =  translationScalea;
  optimizerScales[10] =  translationScaleb;
  optimizerScales[11] =  translationScalec;
  //step length was 0.1 larger step length quicker converge but may get
erreaic values in the metric as it decreases
  unsigned int maxNumberOfIterations = 60;
  optimizer->SetMaximumStepLength( 0.05 );
  optimizer->SetMinimumStepLength( 0.001 ); //was 0.00001
  optimizer->SetNumberOfIterations( maxNumberOfIterations );
  optimizer->MaximizeOff();
//Perform Affine Registration put observer on the Affine optimizer
  CommandIterationUpdate::Pointer observera = CommandIterationUpdate::New();
  optimizer->AddObserver( itk::IterationEvent(), observera );
  try
    {
    registration->Update();
    std::cout << " " <<std::endl;
    std::cout << "Optimizer stop condition: "
           << registration->GetOptimizer()->GetStopConditionDescription()
           << std::endl;
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  std::cout << "Affine Registration completed" << std::endl;
  std::cout << std::endl;
  optimizer->RemoveAllObservers();
  optimizer->RemoveAllObservers();
//Obtain the last Affine transform which will be used as a bulk transform
in the Bspline
  Affinetransform->SetParameters(registration->GetLastTransformParameters()
);
//////////////////////////////////////////////////////////////////////////////////////////////
///NOW FOR THE Bspline Registration
//  We construct two transform objects, each one will be configured for a
resolution level.
//  Notice than in this multi-resolution scheme we are not modifying the
//  resolution of the image, but rather the flexibility of the deformable
//  transform itself.
//SO must define a transform and a grid for each level
  DeformableTransformType::Pointer  BtransformLow =
DeformableTransformType::New();
  typedef DeformableTransformType::RegionType RegionType;
  RegionType bsplineRegionlow;
  RegionType::SizeType   gridBorderSize;
  RegionType::SizeType   gridSizeOnImagelow;
  RegionType::SizeType   totalGridSizelow;
//.//////////////////////////////////////////////////////////////////////
///GRID SIZE FOR LOW RESOLUTION
/////////////////////////////////////////////////////////////////////////
  gridSizeOnImagelow[0]=12;  //lat coronal, sup-inf //want 5 2 7 10 4 15
  gridSizeOnImagelow[1]=4;    // want
  gridSizeOnImagelow[2]=12;
  gridBorderSize.Fill( 3 );    // Border for spline order = 3 ( 1 lower, 2
upper )
  totalGridSizelow = gridSizeOnImagelow + gridBorderSize;
  bsplineRegionlow.SetSize( totalGridSizelow );
  typedef DeformableTransformType::SpacingType SpacingTypelow;
  SpacingTypelow spacinglow = FixedImage->GetSpacing();
  typedef DeformableTransformType::OriginType OriginTypelow;
  OriginTypelow originlow = FixedImage->GetOrigin();
  FixedImageType::RegionType FixedRegionlow =
FixedImage->GetBufferedRegion();
  FixedImageType::SpacingType   fixedSpacinglow    =
FixedImage->GetSpacing();
  FixedImageType::SizeType FixedImageSizelow = FixedRegionlow.GetSize();
  for(unsigned int r=0; r<Dimension; r++)
    {
    spacinglow[r] = floor( fixedSpacinglow[r] * (FixedImageSizelow[r] - 1)
/ (gridSizeOnImagelow[r] - 1) ); //new way
    }
  FixedImageType::DirectionType gridDirection = FixedImage->GetDirection();
  SpacingTypelow gridOriginOffsetlow = gridDirection * spacinglow;
  OriginTypelow gridOriginlow = originlow - gridOriginOffsetlow;
  BtransformLow->SetGridSpacing( spacinglow );
  BtransformLow->SetGridOrigin( gridOriginlow );
  BtransformLow->SetGridRegion( bsplineRegionlow ); //i.e region of gridsize
  BtransformLow->SetGridDirection( gridDirection );
  std::cout << "grid region for low Bspline is " <<
BtransformLow->GetGridRegion() <<std::endl;
//////////////////////////////////////////////////////////////////////////////
///GRID FOR MEDIUM
////////////////////////////////////////////////////////////////////////////////
  DeformableTransformType::Pointer  BtransformMed=
DeformableTransformType::New();
  RegionType bsplineRegionMed;
  RegionType::SizeType   gridSizeOnImageMed;
  RegionType::SizeType   totalGridSizeMed;
//.//////////////////////////////////////////////////////////////////////
///GRID SIZE FOR MEDIUM RESOLUTION
/////////////////////////////////////////////////////////////////////////
  gridSizeOnImageMed[0]=24;  //lat coronal, sup-inf
  gridSizeOnImageMed[1]=8;    // want
  gridSizeOnImageMed[2]=24;
  totalGridSizeMed = gridSizeOnImageMed + gridBorderSize;
  bsplineRegionMed.SetSize( totalGridSizeMed );
 typedef DeformableTransformType::SpacingType SpacingTypeMed;
  SpacingTypeMed spacingMed = FixedImage->GetSpacing();
  typedef DeformableTransformType::OriginType OriginTypeMed;
  OriginTypeMed originMed = FixedImage->GetOrigin();
  FixedImageType::RegionType FixedRegionMed =
FixedImage->GetBufferedRegion();
  FixedImageType::SpacingType   fixedSpacingMed    =
FixedImage->GetSpacing();
  FixedImageType::SizeType FixedImageSizeMed = FixedRegionMed.GetSize();
      for(unsigned int r=0; r<Dimension; r++)
    {
    spacingMed[r] = floor( fixedSpacingMed[r] * (FixedImageSizeMed[r] - 1)
/ (gridSizeOnImageMed[r] - 1) ); //new way
    }
   SpacingTypeMed gridOriginOffsetMed = gridDirection * spacingMed;
   OriginTypeMed gridOriginMed = originMed - gridOriginOffsetMed;
  BtransformMed->SetGridSpacing( spacingMed );
  BtransformMed->SetGridOrigin( gridOriginMed );
  BtransformMed->SetGridRegion( bsplineRegionMed ); //i.e region of gridsize
  BtransformMed->SetGridDirection( gridDirection );
  std::cout << "grid region for Med Bspline is " <<
BtransformMed->GetGridRegion() <<std::endl;
//////////////////////////////////////////////////////////////////////////////
///GRID FOR HIGH
////////////////////////////////////////////////////////////////////////////////
//Now the Higher Transform
  DeformableTransformType::Pointer  BtransformHigh =
DeformableTransformType::New();
  RegionType bsplineRegionhigh;
  RegionType::SizeType   gridSizeOnImagehigh;
  RegionType::SizeType   totalGridSizehigh;
//.//////////////////////////////////////////////////////////////////////
///GRID SIZE FOR HIGH RESOLUTION
/////////////////////////////////////////////////////////////////////////
  gridSizeOnImagehigh[0]=50;  //lat coronal, sup-inf
  gridSizeOnImagehigh[1]=16;    // want
  gridSizeOnImagehigh[2]=50;
  totalGridSizehigh = gridSizeOnImagehigh + gridBorderSize;
  bsplineRegionhigh.SetSize( totalGridSizehigh );
 typedef DeformableTransformType::SpacingType SpacingTypehigh;
  SpacingTypehigh spacinghigh = FixedImage->GetSpacing();
  typedef DeformableTransformType::OriginType OriginTypehigh;
  OriginTypehigh originhigh = FixedImage->GetOrigin();
  FixedImageType::RegionType FixedRegionhigh =
FixedImage->GetBufferedRegion();
  FixedImageType::SpacingType   fixedSpacinghigh    =
FixedImage->GetSpacing();
  FixedImageType::SizeType FixedImageSizehigh = FixedRegionhigh.GetSize();
      for(unsigned int r=0; r<Dimension; r++)
    {
    spacinghigh[r] = floor( fixedSpacinghigh[r] * (FixedImageSizehigh[r] -
1) / (gridSizeOnImagehigh[r] - 1) ); //new way
    }
   SpacingTypehigh gridOriginOffsethigh = gridDirection * spacinghigh;
   OriginTypehigh gridOriginhigh = originhigh - gridOriginOffsethigh;
  BtransformHigh->SetGridSpacing( spacinghigh );
  BtransformHigh->SetGridOrigin( gridOriginhigh );
  BtransformHigh->SetGridRegion( bsplineRegionhigh ); //i.e region of
gridsize
  BtransformHigh->SetGridDirection( gridDirection );
  std::cout << "grid region for high Bspline is " <<
BtransformHigh->GetGridRegion() <<std::endl;
///////////////////////////////////////////////////////////////////////
///METRIC NUMBER OF SAMPLES
//////////////////////////////////////////////////////////////////////
//Low
  const unsigned int numberOfBSplineParametersLow =
               BtransformLow->GetNumberOfParameters();
  typedef DeformableTransformType::ParametersType     ParametersTypeLow;
  ParametersTypeLow parametersLow( numberOfBSplineParametersLow );
//Medium
  const unsigned int numberOfBSplineParametersMed =
               BtransformMed->GetNumberOfParameters();
  typedef DeformableTransformType::ParametersType     ParametersTypeMed;
  ParametersTypeMed parametersMed( numberOfBSplineParametersMed );
  const unsigned int numberOfBSplineParametersHigh =
               BtransformHigh->GetNumberOfParameters();
  typedef DeformableTransformType::ParametersType     ParametersTypeHigh;
  ParametersTypeHigh parametersHigh( numberOfBSplineParametersHigh );
     const unsigned long numberOfSamplesBsplineHigh =
       static_cast<unsigned long>(
        vcl_sqrt( static_cast<double>( numberOfBSplineParametersHigh ) *
                static_cast<double>( numberOfPixels ) ) );
///////////////////////////////////////////////////////////////////////
///LOW PARAMETERS
//////////////////////////////////////////////////////////////////////
  typedef DeformableTransformType::ParametersType     ParametersTypelow;
  const unsigned int numberOfBSplineParameterslow =
               BtransformLow->GetNumberOfParameters();
  ParametersTypelow parameterslow( numberOfBSplineParameterslow );
  parameterslow.Fill( 0.0 );
  BtransformLow->SetBulkTransform( Affinetransform );
 //////////////////////////////////////////////////////////////////////////////
///OPTIMIZER FOR LOW RESOLUTION
////////////////////////////////////////////////////////////////////////////////
 // if get IFLAG= -1. LINE SEARCH FAILED
 // increase step lentgth but keep other parameters the same
/////////////////////////////////////////////////////////////////////
// SEE HERE FOR OPTIMIZER ADVICE
//http://www.itk.org/pipermail/insight-users/2011-March/040286.html
///FOR the LBFGSBOptimizer got LOW
  bOptimizerType::BoundSelectionType boundSelectlow(
BtransformLow->GetNumberOfParameters() );
  bOptimizerType::BoundValueType upperBoundlow(
BtransformLow->GetNumberOfParameters() );
  bOptimizerType::BoundValueType lowerBoundlow(
BtransformLow->GetNumberOfParameters() );
  boundSelectlow.Fill( 0 );
  upperBoundlow.Fill( 0.0 );
  lowerBoundlow.Fill( 0.0 );
  boptimizer->SetBoundSelection( boundSelectlow );
  boptimizer->SetUpperBound( upperBoundlow );
  boptimizer->SetLowerBound( lowerBoundlow );
  boptimizer->SetCostFunctionConvergenceFactor( 1.e1 );
  boptimizer->SetProjectedGradientTolerance( 1e-6 );
  boptimizer->SetMaximumNumberOfIterations( 200 ); //was 200
  boptimizer->SetMaximumNumberOfEvaluations( 300 ); //
  boptimizer->SetMaximumNumberOfCorrections( 5 );
///////////////////////////////////////////////////////////////
  metric->SetNumberOfSpatialSamples( numberOfPixels*1 ); //
  RegistrationType::Pointer   bregistration  = RegistrationType::New();
  bregistration->SetNumberOfThreads(1);
  bregistration->SetInitialTransformParameters(
BtransformLow->GetParameters() );
  bregistration->SetTransform(BtransformLow);
  bregistration->SetFixedImageRegion(FixedImage->GetBufferedRegion() );
  bregistration->SetMetric(        metric        );
  bregistration->SetOptimizer(     boptimizer     );
  bregistration->SetInterpolator(  interpolator  );
  bregistration->SetFixedImage(fixedSmoother->GetOutput());
  bregistration->SetMovingImage(movingSmoother->GetOutput());
  bregistration->SetNumberOfThreads(1);
//////////////////////////////////////////////////////////////////////
///REGISTRATION FOR LOW
///////////////////////////////////////////////////////////////////////
  BCommandIterationUpdate::Pointer observerl =
BCommandIterationUpdate::New();
  boptimizer->AddObserver( itk::IterationEvent(), observerl );
  try
    {
    bregistration->Update();
    std::cout << " " <<std::endl;
    std::cout << "Optimizer stop condition: "
           << bregistration->GetOptimizer()->GetStopConditionDescription()
           << std::endl;
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
 boptimizer->RemoveAllObservers();
/////////////////////////////////////////////////////////////////////
 ///MEDIUM PARAMETERS
////////////////////////////////////////////////////////////////////
  typedef DeformableTransformType::ParametersType     ParametersTypeMed;
  parametersMed.Fill( 0.0 );
//  Now we need to initialize the BSpline coefficients of the higher
resolution
//  transform. This is done by first computing the actual deformation field
//  at the higher resolution from the lower resolution BSpline
coefficients.
//  Then a BSpline decomposition is done to obtain the BSpline coefficient
of
//  the higher resolution transform.
  unsigned int counterMed = 0;
  for ( unsigned int k = 0; k < SpaceDimension; k++ )
    {
    typedef DeformableTransformType::ImageType ParametersImageTypeMed;
    typedef
itk::ResampleImageFilter<ParametersImageTypeMed,ParametersImageTypeMed>
ResamplerTypeMed;
    ResamplerTypeMed::Pointer upsamplerMed = ResamplerTypeMed::New();
    typedef
itk::BSplineResampleImageFunction<ParametersImageTypeMed,double>
FunctionTypeMed;
    FunctionTypeMed::Pointer functionMed = FunctionTypeMed::New();
    typedef itk::IdentityTransform<double,SpaceDimension>
IdentityTransformTypeMed;
    IdentityTransformTypeMed::Pointer identityMed =
IdentityTransformTypeMed::New();
    upsamplerMed->SetInput( BtransformLow->GetCoefficientImages()[k] );
    upsamplerMed->SetInterpolator( functionMed );
    upsamplerMed->SetTransform( identityMed );
    upsamplerMed->SetSize( BtransformMed->GetGridRegion().GetSize() );
    upsamplerMed->SetOutputSpacing( BtransformMed->GetGridSpacing() );
    upsamplerMed->SetOutputOrigin( BtransformMed->GetGridOrigin() );
    upsamplerMed->SetOutputDirection( FixedImage->GetDirection() );
    upsamplerMed->Update();
    typedef
itk::BSplineDecompositionImageFilter<ParametersImageTypeMed,ParametersImageTypeMed>
      DecompositionTypeMed;
    DecompositionTypeMed::Pointer decompositionMed =
DecompositionTypeMed::New();
    decompositionMed->SetSplineOrder( SplineOrder );
    decompositionMed->SetInput( upsamplerMed->GetOutput() );
    decompositionMed->Update();
    ParametersImageTypeMed::Pointer newCoefficientsMed =
decompositionMed->GetOutput();
    // copy the coefficients into the parameter array
    typedef itk::ImageRegionIterator<ParametersImageTypeMed> IteratorMed;
    IteratorMed it( newCoefficientsMed, BtransformMed->GetGridRegion() );
    while ( !it.IsAtEnd() )
      {
      parametersMed[ counterMed++ ] = it.Get();
      ++it;
      }
    }
  BtransformMed->SetParameters( parametersMed );
////////////////////////////////////////////////////////////////
///FOR the LBFGSBOptimizer MEDIUM
  bOptimizerType::BoundSelectionType boundSelectMed(
BtransformMed->GetNumberOfParameters() );
  bOptimizerType::BoundValueType upperBoundMed(
BtransformMed->GetNumberOfParameters() );
  bOptimizerType::BoundValueType lowerBoundMed(
BtransformMed->GetNumberOfParameters() );
  boundSelectMed.Fill( 0 );
  upperBoundMed.Fill( 0.0 );
  lowerBoundMed.Fill( 0.0 );
  boptimizer->SetBoundSelection( boundSelectMed );
  boptimizer->SetUpperBound( upperBoundMed );
  boptimizer->SetLowerBound( lowerBoundMed );
  boptimizer->SetCostFunctionConvergenceFactor( 1.e12 ); //was 1.e7
 //set/Get the CostFunctionConvergenceFactor. Algorithm terminates
 //  when the reduction in cost function is less than factor * epsmcj
 // where epsmch is the machine precision.
 // Typical values for factor: 1e+12 for low accuracy;
 // 1e+7 for moderate accuracy and 1e+1 for extremely high accuracy.
  boptimizer->SetProjectedGradientTolerance( 1e-6 );
  //Gradient tolerance determines a lower threshold which cuases the
optimization to stop if its
//value reached, recommended values for gradient tolerance are 1e-6 to
1e-10, higher values might result in premature elimination of the
optimization process
  boptimizer->SetMaximumNumberOfIterations( 200); //was 200
  boptimizer->SetMaximumNumberOfEvaluations( 300 );
  boptimizer->SetMaximumNumberOfCorrections( 5 );
  //M Number of correction- number of function/gradient pairs used to build
 model
  //This parameter is passed to the function which is used to create
optimizer object.
  // Increase of number of corrections decreases number of function
evaluations
  //and iterations needed to converge, but increases computational overhead
associated with iteration.
  // On well-conditioned problems can be as small as 3-10.
  //If function changes rapidly in some directions and slowly in other
ones,
  //then you can try increasing M in order to increase convergenc
///////////////////////////////////////////////////////////////////////
///REGISTRATION FOR MEDIUM
/////////////////////////////////////////////////////////////////////
  //For time probe
   metric->SetNumberOfSpatialSamples( numberOfPixels*1 ); //
  bregistration->SetInitialTransformParameters(
BtransformMed->GetParameters() );
  bregistration->SetTransform( BtransformMed );
  itk::TimeProbesCollectorBase chronometerm;
  itk::MemoryProbesCollectorBase memorymeterm;
  BCommandIterationUpdate::Pointer observerm =
BCommandIterationUpdate::New();
  boptimizer->AddObserver( itk::IterationEvent(), observerm );
  try
    {
    bregistration->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  boptimizer->RemoveAllObservers();
 BtransformMed->SetParameters( bregistration->GetLastTransformParameters()
);
//NOW HIGH RESOLUTION
/////////////////////////////////////////////////////////////////////
 ///HIGH PARAMETERS
////////////////////////////////////////////////////////////////////
  parametersHigh.Fill( 0.0 );
  unsigned int counter = 0;
  for ( unsigned int k = 0; k < SpaceDimension; k++ )
    {
    typedef DeformableTransformType::ImageType ParametersImageType;
    typedef
itk::ResampleImageFilter<ParametersImageType,ParametersImageType>
ResamplerType;
    ResamplerType::Pointer upsampler = ResamplerType::New();
    typedef itk::BSplineResampleImageFunction<ParametersImageType,double>
FunctionType;
    FunctionType::Pointer function = FunctionType::New();
    typedef itk::IdentityTransform<double,SpaceDimension>
IdentityTransformType;
    IdentityTransformType::Pointer identity = IdentityTransformType::New();
    upsampler->SetInput( BtransformMed->GetCoefficientImages()[k] );
    upsampler->SetInterpolator( function );
    upsampler->SetTransform( identity );
    upsampler->SetSize( BtransformHigh->GetGridRegion().GetSize() );
    upsampler->SetOutputSpacing( BtransformHigh->GetGridSpacing() );
    upsampler->SetOutputOrigin( BtransformHigh->GetGridOrigin() );
    upsampler->SetOutputDirection( FixedImage->GetDirection() );
    upsampler->Update();
    typedef
itk::BSplineDecompositionImageFilter<ParametersImageType,ParametersImageType>
      DecompositionType;
    DecompositionType::Pointer decomposition = DecompositionType::New();
    decomposition->SetSplineOrder( SplineOrder );
    decomposition->SetInput( upsampler->GetOutput() );
    decomposition->Update();
    ParametersImageType::Pointer newCoefficients =
decomposition->GetOutput();
    // copy the coefficients into the parameter array
    typedef itk::ImageRegionIterator<ParametersImageType> Iterator;
    Iterator it( newCoefficients, BtransformHigh->GetGridRegion() );
    while ( !it.IsAtEnd() )
      {
      parametersHigh[ counter++ ] = it.Get();
      ++it;
      }
    }
  BtransformHigh->SetParameters( parametersHigh );
/////////////////////////////////////////////////////////////////////////////////////////
///FOR the LBFGSBOptimizer HIGH
  bOptimizerType::BoundSelectionType boundSelecthigh(
BtransformHigh->GetNumberOfParameters() );
  bOptimizerType::BoundValueType upperBoundhigh(
BtransformHigh->GetNumberOfParameters() );
  bOptimizerType::BoundValueType lowerBoundhigh(
BtransformHigh->GetNumberOfParameters() );
  boundSelecthigh.Fill( 0 );
  upperBoundhigh.Fill( 0.0 );
  lowerBoundhigh.Fill( 0.0 );
  boptimizer->SetBoundSelection( boundSelecthigh );
  boptimizer->SetUpperBound( upperBoundhigh );
  boptimizer->SetLowerBound( lowerBoundhigh );
  boptimizer->SetCostFunctionConvergenceFactor( 1.e12 );
  boptimizer->SetProjectedGradientTolerance( 1e-6 );//was 1e-6
  boptimizer->SetMaximumNumberOfIterations( 1000 ); //was 200
  boptimizer->SetMaximumNumberOfEvaluations( 300 );
  boptimizer->SetMaximumNumberOfCorrections( 5 );
///////////////////////////////////////////////////////////////////////
///REGISTRATION FOR HIGH
/////////////////////////////////////////////////////////////////////
  //For time probe
   metric->SetNumberOfSpatialSamples( numberOfPixels*1 ); //
  bregistration->SetInitialTransformParameters(
BtransformHigh->GetParameters() );
  bregistration->SetTransform( BtransformHigh );
  itk::TimeProbesCollectorBase chronometerh;
  itk::MemoryProbesCollectorBase memorymeterh;
  BCommandIterationUpdate::Pointer observerh =
BCommandIterationUpdate::New();
  boptimizer->AddObserver( itk::IterationEvent(), observerh );
 try
    {
    bregistration->Update();
   std::cout << " " <<std::endl;
    std::cout << "Optimizer stop condition: "
           << bregistration->GetOptimizer()->GetStopConditionDescription()
           << std::endl;
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  // Finally we use the last transform parameters in order to resample the
image.
  //
  boptimizer->RemoveAllObservers();
 BtransformHigh->SetParameters( bregistration->GetLastTransformParameters()
);
  typedef itk::ResampleImageFilter<
                            MovingImageType,
                            FixedImageType >    ResampleFilterType;
  ResampleFilterType::Pointer resample = ResampleFilterType::New();
  resample->SetTransform( BtransformHigh );
  resample->SetInput( MovedImage );
  resample->SetSize(    FixedImage->GetLargestPossibleRegion().GetSize() );
  resample->SetOutputOrigin(  FixedImage->GetOrigin() );
  resample->SetOutputSpacing( FixedImage->GetSpacing() );
  resample->SetOutputDirection( FixedImage->GetDirection() );
  resample->SetDefaultPixelValue( 0 );
  resample->Update();
  ImageWriter->SetInput(resample->GetOutput());
    try
      {
      ImageWriter->Update();
      }
    catch( itk::ExceptionObject & excp )
      {
      std::cerr << "Exception thrown " << std::endl;
      std::cerr << excp << std::endl;
      return EXIT_FAILURE;
      }
  FixedImageType::RegionType FixedRegion = FixedImage->GetBufferedRegion();
  DeformField->SetRegions( FixedRegion );
  DeformField->SetOrigin( FixedImage->GetOrigin() );
  DeformField->SetSpacing( FixedImage->GetSpacing() );
  FixedImageType:: DirectionType Fixeddirection =FixedImage->GetDirection();
  DeformField->SetDirection(Fixeddirection);
  DeformField->Allocate();
  DeformField->Update();
//WRITE THE DEFORMATION FIELD
    typedef itk::ImageRegionIterator< DisplacementFieldType > FieldIterator;
    FieldIterator fi( DeformField, FixedRegion );
    fi.GoToBegin();
    DeformableTransformType::InputPointType  fixedPointa;
    DeformableTransformType::OutputPointType movingPointa;
    DisplacementFieldType::IndexType indexa;
    VectorPixelType displacement;
    while( ! fi.IsAtEnd() )
      {
      indexa = fi.GetIndex();
      DeformField->TransformIndexToPhysicalPoint( indexa, fixedPointa );
      movingPointa = BtransformHigh->TransformPoint( fixedPointa );
      displacement = movingPointa - fixedPointa;
      fi.Set( displacement );
      ++fi;
      }
    FieldWriter->SetInput( DeformField );
    //std::cout << "Writing deformation field ...";
    try
      {
      FieldWriter->Update();
      }
    catch( itk::ExceptionObject & excp )
      {
      std::cerr << "Exception thrown " << std::endl;
      std::cerr << excp << std::endl;
      return EXIT_FAILURE;
      }
  return EXIT_SUCCESS;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20131211/d0d69676/attachment-0001.htm>
    
    
More information about the Insight-users
mailing list