📄 itkmultiresolutionimageregistrationmethodtest_1.cxx
字号:
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkMultiResolutionImageRegistrationMethodTest_1.cxx,v $
Language: C++
Date: $Date: 2008-03-27 20:12:33 $
Version: $Revision: 1.13 $
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
#include "itkMultiResolutionImageRegistrationMethod.h"
#include "itkAffineTransform.h"
#include "itkMutualInformationImageToImageMetric.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkGradientDescentOptimizer.h"
#include "itkRecursiveMultiResolutionPyramidImageFilter.h"
#include "itkTextOutput.h"
#include "itkImageRegionIterator.h"
#include "itkCommandIterationUpdate.h"
#include "itkSimpleMultiResolutionImageRegistrationUI.h"
namespace
{
double F( itk::Vector<double,3> & v );
}
/**
* This program test the
* itk::MultiResolutionImageRegistrationMethod class
*
* This file tests the combination of:
* - MutualInformation
* - AffineTransform
* - GradientDescentOptimizer
* - LinearInterpolateImageFunction
* - RecursiveMultiResolutionPyramidImageFilter
*
* The test image pattern consists of a 3D gaussian in the middle
* with some directional pattern on the outside.
* One image is scaled and shifted relative to the other.
*
* This program runs two registration tests. The first test
* uses SetNumberOfLevels() method to specify the number of computation levels
* in the pyramid. The second test uses a user defined multi-resolution schedule.
* The final transform of the registration runs are compared with the
* true parameters.
*
*
* Notes:
* =====
* This example performs an affine
* registration between a moving image and a fixed image using
* mutual information and a multi-resolution strategy.
*
* See notes for itkImageRegistrationMethodTest_13.cxx for more
* detailed information on the algorithm.
*
* A simple user-interface, allows the user to define the number
* of iteration and learning rate at each resolution level.
*
* In addition, several exceptions are exercised for testing and code
* coverage purpose.
*
*
*/
int itkMultiResolutionImageRegistrationMethodTest_1(int, char* [] )
{
itk::OutputWindow::SetInstance(itk::TextOutput::New().GetPointer());
bool pass = true;
const unsigned int dimension = 3;
unsigned int j;
typedef float PixelType;
// Fixed Image Type
typedef itk::Image<PixelType,dimension> FixedImageType;
// Moving Image Type
typedef itk::Image<PixelType,dimension> MovingImageType;
// Transform Type
typedef itk::AffineTransform< double,dimension > TransformType;
// Optimizer Type
typedef itk::GradientDescentOptimizer OptimizerType;
// Metric Type
typedef itk::MutualInformationImageToImageMetric<
FixedImageType,
MovingImageType > MetricType;
// Interpolation technique
typedef itk:: LinearInterpolateImageFunction<
MovingImageType,
double > InterpolatorType;
// Fixed Image Pyramid Type
typedef itk::RecursiveMultiResolutionPyramidImageFilter<
FixedImageType,
FixedImageType > FixedImagePyramidType;
// Moving Image Pyramid Type
typedef itk::RecursiveMultiResolutionPyramidImageFilter<
MovingImageType,
MovingImageType > MovingImagePyramidType;
// Registration Method
typedef itk::MultiResolutionImageRegistrationMethod<
FixedImageType,
MovingImageType > RegistrationType;
/*********************************************************
* Set up the two input images.
* One image scaled and shifted with respect to the other.
**********************************************************/
FixedImageType::Pointer fixedImage = FixedImageType::New();
MovingImageType::Pointer movingImage = MovingImageType::New();
double displacement[dimension] = {7,3,2};
double scale[dimension] = { 0.80, 1.0, 1.0 };
FixedImageType::SizeType size = {{100,100,40}};
FixedImageType::IndexType index = {{0,0,0}};
FixedImageType::RegionType region;
region.SetSize( size );
region.SetIndex( index );
fixedImage->SetLargestPossibleRegion( region );
fixedImage->SetBufferedRegion( region );
fixedImage->SetRequestedRegion( region );
fixedImage->Allocate();
movingImage->SetLargestPossibleRegion( region );
movingImage->SetBufferedRegion( region );
movingImage->SetRequestedRegion( region );
movingImage->Allocate();
typedef itk::ImageRegionIterator<MovingImageType> MovingImageIterator;
typedef itk::ImageRegionIterator<FixedImageType> FixedImageIterator;
itk::Point<double,dimension> center;
for ( j = 0; j < dimension; j++ )
{
center[j] = 0.5 * (double)region.GetSize()[j];
}
itk::Point<double,dimension> p;
itk::Vector<double,dimension> d;
MovingImageIterator mIter( movingImage, region );
FixedImageIterator fIter( fixedImage, region );
while( !mIter.IsAtEnd() )
{
for ( j = 0; j < dimension; j++ )
{
p[j] = mIter.GetIndex()[j];
}
d = p - center;
fIter.Set( (PixelType) F(d) );
for ( j = 0; j < dimension; j++ )
{
d[j] = d[j] * scale[j] + displacement[j];
}
mIter.Set( (PixelType) F(d) );
++fIter;
++mIter;
}
// set the image origin to be center of the image
double transCenter[dimension];
for ( j = 0; j < dimension; j++ )
{
transCenter[j] = -0.5 * double(size[j]);
}
movingImage->SetOrigin( transCenter );
fixedImage->SetOrigin( transCenter );
RegistrationType::ScheduleType fixedImageSchedule;
RegistrationType::ScheduleType movingImageSchedule;
/* The first registration run invokes SetNumberOfLevels to specify
* the number of computation levels */
{
MetricType::Pointer metric = MetricType::New();
TransformType::Pointer transform = TransformType::New();
OptimizerType::Pointer optimizer = OptimizerType::New();
InterpolatorType::Pointer interpolator = InterpolatorType::New();
FixedImagePyramidType::Pointer fixedImagePyramid =
FixedImagePyramidType::New();
MovingImagePyramidType::Pointer movingImagePyramid =
MovingImagePyramidType::New();
RegistrationType::Pointer registration = RegistrationType::New();
/******************************************************************
* Set up the optimizer.
******************************************************************/
// set the translation scale
typedef OptimizerType::ScalesType ScalesType;
ScalesType parametersScales( transform->GetNumberOfParameters() );
parametersScales.Fill( 1.0 );
for ( j = 9; j < 12; j++ )
{
parametersScales[j] = 0.0001;
}
optimizer->SetScales( parametersScales );
// need to maximize for mutual information
optimizer->MaximizeOn();
/******************************************************************
* Set up the metric.
******************************************************************/
metric->SetMovingImageStandardDeviation( 5.0 );
metric->SetFixedImageStandardDeviation( 5.0 );
metric->SetNumberOfSpatialSamples( 50 );
/******************************************************************
* 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 );
registration->SetFixedImagePyramid( fixedImagePyramid );
registration->SetMovingImagePyramid( movingImagePyramid );
registration->SetFixedImageRegion( fixedImage->GetBufferedRegion() );
// set initial parameters to identity
RegistrationType::ParametersType initialParameters(
transform->GetNumberOfParameters() );
initialParameters.Fill( 0.0 );
initialParameters[0] = 1.0;
initialParameters[4] = 1.0;
initialParameters[8] = 1.0;
/******************************************************************
* Attach registration to a simple UI and run registration
******************************************************************/
SimpleMultiResolutionImageRegistrationUI2<RegistrationType>
simpleUI( registration );
unsigned short numberOfLevels = 3;
itk::Array<unsigned int> niter( numberOfLevels );
itk::Array<double> rates( numberOfLevels );
niter[0] = 100;
niter[1] = 300;
niter[2] = 550;
rates[0] = 1e-3;
rates[1] = 5e-4;
rates[2] = 1e-4;
simpleUI.SetNumberOfIterations( niter );
simpleUI.SetLearningRates( rates );
try
{
metric->ReinitializeSeed( 121212 );
registration->SetNumberOfLevels( numberOfLevels );
registration->SetInitialTransformParameters( initialParameters );
registration->StartRegistration();
}
catch( itk::ExceptionObject & e )
{
std::cout << "Registration failed" << std::endl;
std::cout << "Reason " << e.GetDescription() << std::endl;
return EXIT_FAILURE;
}
/***********************************************************
* Check the results
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -