ITK圖像配準介紹

完整WORD文檔請查看http://download.csdn.net/source/2285738

 

 

1.什麼叫配準

 


Image registration is the process of determining the spatial transform that maps points from one image to homologous points on a object in the second image.

 

2.配準的框架

 

3Transform


In the Insight Toolkit, itk::Transform objects encapsulate the mapping of points and vectors from an input space to an output space.

 

ITK provides a variety of transforms from simple translation, rotation and scaling to general affine and kernel transforms.

 

下面詳細介紹一些主要的變換方法:

 

3.1 Translation Transform

 

3.2 Scale Transform

 

3.3 Euler2DTransform

 

3.4 CenteredRigid2DTransform

 

 

3.5 Similarity2DTransform

       can be seen as a rigid transform combined with an isotropic scaling factor.

 

3.6 AffineTransform

 

3.7 變換的分類

 

4. Interpolators

 

4.1 爲什麼要插值?

 

 

4.2 最常用的兩種插值方法

 

4.2.1 Nearest Neighbor Interpolation

 

 

4.2.2 Linear Interpolation

 

 

5. Metrics

 

In ITK, itk::ImageToImageMetric objects quantitatively measure how well the transformed moving image fits the fixed image by comparing the gray-scale intensity of the images. These metrics are very flexible and can work with any transform or interpolation method and do not require reduction of the gray-scale images to sparse extracted information such as edges.

 

下面介紹一些常用的Metrics

 

5.1 Mean Squares Metric

 

The itk::MeanSquaresImageToImageMetric computes the mean squared pixel-wise difference in intensity between image A and B over a user defined region

5.2 Normalized Correlation Metric

 

6. Optimizers

 

The basic input to an optimizer is a cost function object

 

常用的兩種方法

 

6.1 Gradient Descent

 

 Advances parameters in the direction of the gradient where the step size is governed by a learning rate ( itk::GradientDescentOptimizer).

 

6.2 Regular Step Gradient Descent

Advances parameters in the direction of the gradient where a bipartition scheme is used to compute the step size (itk::RegularStepGradientDescentOptimizer).

 

7.一個簡單的例子

 

 

實現平移配準

#include "itkImageRegistrationMethod.h"

#include "itkTranslationTransform.h"

#include "itkLinearInterpolateImageFunction.h"

#include "itkMeanSquaresImageToImageMetric.h"

#include "itkRegularStepGradientDescentOptimizer.h"

#include "itkImage.h"

 

#include "itkImageFileReader.h"

#include "itkImageFileWriter.h"

 

#include "itkResampleImageFilter.h"

 

#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::endl;

              std::cout <<  optimizer->GetValue() << " " << std::endl;

              std::cout <<  optimizer->GetCurrentPosition() << " " << std::endl;

 

       }

};

 

int main()

{

       const unsigned int Dimension = 2;

       typedef unsigned char PixelType;

 

       typedef itk::Image<PixelType,Dimension> FixImageType;

       typedef itk::Image<PixelType,Dimension> MoveImageType;

 

       typedef itk::TranslationTransform<double,Dimension> TransformType;

       typedef itk::LinearInterpolateImageFunction< MoveImageType , double > InterpolateType;

       typedef itk::MeanSquaresImageToImageMetric< FixImageType , MoveImageType > MetricType;

       typedef itk::RegularStepGradientDescentOptimizer OptimizerType;

       typedef itk::ImageRegistrationMethod< FixImageType , MoveImageType > RegistrationType;

 

       TransformType::Pointer transform = TransformType::New();

InterpolateType::Pointer interpolator = InterpolateType::New();

       MetricType::Pointer metric = MetricType::New();

       OptimizerType::Pointer optimizer = OptimizerType::New();

       RegistrationType::Pointer registration = RegistrationType::New();

 

       registration->SetTransform( transform );

       registration->SetInterpolator( interpolator );

       registration->SetMetric( metric );

       registration->SetOptimizer( optimizer );

 

       typedef itk::ImageFileReader< FixImageType > FixedImageReaderType;

       typedef itk::ImageFileReader< MoveImageType > MoveImageReaderType;

 

       FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New();

       MoveImageReaderType::Pointer  moveImageReader  = MoveImageReaderType::New();

 

       const char* FixedImageRoot = "D://pic//BFixed.png";

       const char* MoveImageRoot = "D://pic//BMove2.png";

      

       fixedImageReader->SetFileName( FixedImageRoot );

       moveImageReader->SetFileName( MoveImageRoot );

 

       registration->SetFixedImage( fixedImageReader->GetOutput());

       registration->SetMovingImage( moveImageReader->GetOutput());

 

       fixedImageReader->Update();

       registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion());

 

       typedef RegistrationType::ParametersType ParametersType;

       ParametersType initialParameters( transform->GetNumberOfParameters() );

 

       initialParameters[0] = 0.0;

       initialParameters[1] = 0.0;    

 

       registration->SetInitialTransformParameters ( initialParameters );

 

       optimizer->SetMaximumStepLength ( 4.00 );

       optimizer->SetMinimumStepLength ( 0.05 );

 

       optimizer->SetNumberOfIterations( 200 );

 

       CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();

 

       optimizer->AddObserver( itk::IterationEvent(), observer );

 

       try

       {

              registration->StartRegistration();

              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;

              system("pause");

              return -1;

       }

 

       ParametersType finalParameters = registration->GetLastTransformParameters();

 

       const double TranslationAlongX = finalParameters[0];

       const double TranslationAlongY = finalParameters[1];

 

       const unsigned int numberOfIterations = optimizer->GetCurrentIteration();

       const double bestValue = optimizer->GetValue();

 

       std::cout << " TranslationAlongX = " << TranslationAlongX << std::endl;

       std::cout << " TranslationAlongY = " << TranslationAlongY << std::endl;

 

       std::cout << " numberOfIterations = " << numberOfIterations << std::endl;

 

       system("pause");

 

       typedef itk::ResampleImageFilter< MoveImageType , FixImageType > ResampleFilterType;

      

       ResampleFilterType::Pointer resampler = ResampleFilterType::New();

       resampler->SetInput( moveImageReader->GetOutput() );

      

       resampler->SetTransform( registration->GetOutput()->Get() );

      

       FixImageType::Pointer fixedImage = fixedImageReader->GetOutput();

       resampler->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );

       resampler->SetOutputOrigin(  fixedImage->GetOrigin() );

       resampler->SetOutputSpacing( fixedImage->GetSpacing() );

       resampler->SetOutputDirection( fixedImage->GetDirection() );

       resampler->SetDefaultPixelValue( 100 );

      

      

       //     typedef itk::ImageFileWriter< OutputImageType >  WriterType;

       typedef itk::Image<PixelType,Dimension> OutputImageType;

       typedef itk::ImageFileWriter< OutputImageType >  WriterType;

       WriterType::Pointer      writer =  WriterType::New();

       //CastFilterType::Pointer  caster =  CastFilterType::New();

      

       const char* writeFile = "D://pic//write.png";

       writer->SetFileName( writeFile );

      

       //caster->SetInput( resampler->GetOutput() );

       //writer->SetInput( caster->GetOutput() );

       writer->SetInput( resampler->GetOutput());

      

       try

       {

              writer->Update();

      

       }

       catch( itk::ExceptionObject &err )

       {

              std::cerr << "ExceptionObject caught ! " << std::endl;

              std::cerr << err << std::endl;

              system("pause");

              return -1;

       }

      

      

       return 0 ;

 

}

 

 

 

8. Multi-Resolution Registration

 

 

Multi-Resolution配準方法,可以增強配準的準確性,速度以及魯棒性。如圖所示,它爲多次配準。採用金字塔模型,從第一次的粗糙配準到後面越來越細緻的配準,以此來達到程序的精確匹配。

 

代碼片段

void Execute(itk::Object * object, const itk::EventObject & event)

{

     if(!(itk::IterationEvent().CheckEvent( &event )))

     {

         return;

     }

     RegistrationPointer registration =

     dynamic_cast<RegistrationPointer>( object );

     OptimizerPointer optimizer = dynamic_cast< OptimizerPointer >(

     registration->GetOptimizer() );

     std::cout << "-------------------------------------" << std::endl;

     std::cout << "MultiResolution Level : " << registration->GetCurrentLevel() << std::endl;

     std::cout << std::endl;

 

     if( registration->GetCurrentLevel() == 0 )

     {

         optimizer->SetMaximumStepLength( 16.00 );

         optimizer->SetMinimumStepLength( 0.01 );

     }

     else

     {

         optimizer->SetMaximumStepLength( optimizer->GetMaximumStepLength() / 4.0 );

         optimizer->SetMinimumStepLength( optimizer->GetMinimumStepLength() / 10.0 );

     }

 

}

 

9.Resample Image Filter

 

       適用於配準後的圖像輸出.

 

       Inputs: an image , transform , interpolator .

 

       它針對的是空間座標系,而不是像素,單位是毫米。它是把像素點換算成座標點,然後再賦值的。

 

它的座標系起點爲左下角。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章