template <typename TRegistration>
{
public:
using Self = RegistrationInterfaceCommand;
itkNewMacro( Self );
protected:
RegistrationInterfaceCommand() = default;
public:
using RegistrationType = TRegistration;
{
}
{
if( !(itk::MultiResolutionIterationEvent().CheckEvent( &event ) ) )
{
return;
}
std::cout << "\nObserving from class " << object->GetNameOfClass();
{
std::cout << " \"" << object->GetObjectName() << "\"" << std::endl;
}
const auto * registration = static_cast<const RegistrationType *>( object );
unsigned int currentLevel = registration->GetCurrentLevel();
typename RegistrationType::ShrinkFactorsPerDimensionContainerType shrinkFactors =
registration->GetShrinkFactorsPerDimension( currentLevel );
typename RegistrationType::SmoothingSigmasArrayType smoothingSigmas =
registration->GetSmoothingSigmasPerLevel();
std::cout << "-------------------------------------" << std::endl;
std::cout << " Current multi-resolution level = " << currentLevel << std::endl;
std::cout << " shrink factor = " << shrinkFactors << std::endl;
std::cout << " smoothing sigma = " << smoothingSigmas[currentLevel] << std::endl;
std::cout << std::endl;
}
};
{
public:
using Self = CommandIterationUpdate;
itkNewMacro( Self );
protected:
CommandIterationUpdate() {};
public:
using OptimizerPointer = const OptimizerType *;
{
}
{
auto optimizer = static_cast< OptimizerPointer >( object );
if( !(itk::IterationEvent().CheckEvent( &event )) )
{
return;
}
std::cout << optimizer->GetCurrentIteration() << " ";
std::cout << optimizer->GetValue() << " ";
std::cout << optimizer->GetCurrentPosition() << " " <<
m_CumulativeIterationIndex++ << std::endl;
}
private:
unsigned int m_CumulativeIterationIndex{0};
};
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 [backgroundGrayLevel]";
std::cerr << " [checkerboardbefore] [CheckerBoardAfter]";
std::cerr << " [numberOfBins] " << std::endl;
return EXIT_FAILURE;
}
using PixelType = float;
FixedImageType,
MovingImageType >;
FixedImageType,
MovingImageType,
TTransformType >;
TOptimizerType::Pointer transOptimizer = TOptimizerType::New();
MetricType::Pointer transMetric = MetricType::New();
TRegistrationType::Pointer transRegistration = TRegistrationType::New();
transRegistration->SetOptimizer( transOptimizer );
transRegistration->SetMetric( transMetric );
TTransformType::Pointer movingInitTx = TTransformType::New();
using ParametersType = TOptimizerType::ParametersType;
ParametersType initialParameters( movingInitTx->GetNumberOfParameters() );
initialParameters[0] = 3.0;
initialParameters[1] = 5.0;
movingInitTx->SetParameters( initialParameters );
transRegistration->SetMovingInitialTransform( movingInitTx );
Dimension >;
CompositeTransformType::Pointer compositeTransform =
CompositeTransformType::New();
compositeTransform->AddTransform( movingInitTx );
FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New();
MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New();
fixedImageReader->SetFileName( argv[1] );
movingImageReader->SetFileName( argv[2] );
transRegistration->SetFixedImage( fixedImageReader->GetOutput() );
transRegistration->SetMovingImage( movingImageReader->GetOutput() );
transRegistration->SetObjectName("TranslationRegistration");
constexpr unsigned int numberOfLevels1 = 1;
TRegistrationType::ShrinkFactorsArrayType shrinkFactorsPerLevel1;
shrinkFactorsPerLevel1.SetSize( numberOfLevels1 );
shrinkFactorsPerLevel1[0] = 3;
TRegistrationType::SmoothingSigmasArrayType smoothingSigmasPerLevel1;
smoothingSigmasPerLevel1.SetSize( numberOfLevels1 );
smoothingSigmasPerLevel1[0] = 2;
transRegistration->SetNumberOfLevels ( numberOfLevels1 );
transRegistration->SetShrinkFactorsPerLevel( shrinkFactorsPerLevel1 );
transRegistration->SetSmoothingSigmasPerLevel( smoothingSigmasPerLevel1 );
transMetric->SetNumberOfHistogramBins( 24 );
if( argc > 7 )
{
transMetric->SetNumberOfHistogramBins( std::stoi( argv[7] ) );
}
transOptimizer->SetNumberOfIterations( 200 );
transOptimizer->SetRelaxationFactor( 0.5 );
transOptimizer->SetLearningRate( 16 );
transOptimizer->SetMinimumStepLength( 1.5 );
CommandIterationUpdate::Pointer observer1 = CommandIterationUpdate::New();
transOptimizer->AddObserver( itk::IterationEvent(), observer1 );
using TranslationCommandType = RegistrationInterfaceCommand<TRegistrationType>;
TranslationCommandType::Pointer command1 = TranslationCommandType::New();
transRegistration->AddObserver( itk::MultiResolutionIterationEvent(), command1 );
try
{
transRegistration->Update();
std::cout << "Optimizer stop condition: "
<< transRegistration->GetOptimizer()->GetStopConditionDescription()
<< std::endl;
}
{
std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl;
return EXIT_FAILURE;
}
compositeTransform->AddTransform(
transRegistration->GetModifiableTransform() );
using AOptimizerType =
FixedImageType,
MovingImageType,
ATransformType >;
AOptimizerType::Pointer affineOptimizer = AOptimizerType::New();
MetricType::Pointer affineMetric = MetricType::New();
ARegistrationType::Pointer affineRegistration = ARegistrationType::New();
affineRegistration->SetOptimizer( affineOptimizer );
affineRegistration->SetMetric( affineMetric );
affineRegistration->SetMovingInitialTransform( compositeTransform );
affineRegistration->SetFixedImage( fixedImageReader->GetOutput() );
affineRegistration->SetMovingImage( movingImageReader->GetOutput() );
affineRegistration->SetObjectName("AffineRegistration");
affineMetric->SetNumberOfHistogramBins( 24 );
if( argc > 7 )
{
affineMetric->SetNumberOfHistogramBins( std::stoi( argv[7] ) );
}
ATransformType::Pointer affineTx = ATransformType::New();
using SpacingType = FixedImageType::SpacingType;
FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput();
const SpacingType fixedSpacing = fixedImage->GetSpacing();
const OriginType fixedOrigin = fixedImage->GetOrigin();
const RegionType fixedRegion = fixedImage->GetLargestPossibleRegion();
ATransformType::InputPointType centerFixed;
centerFixed[0] =
fixedOrigin[0] + fixedSpacing[0] * fixedSize[0] / 2.0;
centerFixed[1] =
fixedOrigin[1] + fixedSpacing[1] * fixedSize[1] / 2.0;
const unsigned int numberOfFixedParameters =
affineTx->GetFixedParameters().Size();
ATransformType::ParametersType fixedParameters( numberOfFixedParameters );
for (unsigned int i = 0; i < numberOfFixedParameters; ++i)
{
fixedParameters[i] = centerFixed[i];
}
affineTx->SetFixedParameters( fixedParameters );
affineRegistration->SetInitialTransform( affineTx );
using ScalesEstimatorType =
ScalesEstimatorType::Pointer scalesEstimator =
ScalesEstimatorType::New();
scalesEstimator->SetMetric( affineMetric );
scalesEstimator->SetTransformForward( true );
affineOptimizer->SetScalesEstimator( scalesEstimator );
affineOptimizer->SetDoEstimateLearningRateOnce( true );
affineOptimizer->SetDoEstimateLearningRateAtEachIteration( false );
affineOptimizer->SetLowerLimit( 0 );
affineOptimizer->SetUpperLimit( 2 );
affineOptimizer->SetEpsilon( 0.2 );
affineOptimizer->SetNumberOfIterations( 200 );
affineOptimizer->SetMinimumConvergenceValue( 1
e-6 );
affineOptimizer->SetConvergenceWindowSize( 5 );
CommandIterationUpdate::Pointer observer2 = CommandIterationUpdate::New();
affineOptimizer->AddObserver( itk::IterationEvent(), observer2 );
constexpr unsigned int numberOfLevels2 = 2;
ARegistrationType::ShrinkFactorsArrayType shrinkFactorsPerLevel2;
shrinkFactorsPerLevel2.SetSize( numberOfLevels2 );
shrinkFactorsPerLevel2[0] = 2;
shrinkFactorsPerLevel2[1] = 1;
ARegistrationType::SmoothingSigmasArrayType smoothingSigmasPerLevel2;
smoothingSigmasPerLevel2.SetSize( numberOfLevels2 );
smoothingSigmasPerLevel2[0] = 1;
smoothingSigmasPerLevel2[1] = 0;
affineRegistration->SetNumberOfLevels ( numberOfLevels2 );
affineRegistration->SetShrinkFactorsPerLevel( shrinkFactorsPerLevel2 );
affineRegistration->SetSmoothingSigmasPerLevel( smoothingSigmasPerLevel2 );
using AffineCommandType = RegistrationInterfaceCommand<ARegistrationType>;
AffineCommandType::Pointer command2 = AffineCommandType::New();
affineRegistration->AddObserver( itk::MultiResolutionIterationEvent(), command2 );
try
{
affineRegistration->Update();
std::cout << "Optimizer stop condition: "
<< affineRegistration->GetOptimizer()->GetStopConditionDescription()
<< std::endl;
}
{
std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl;
return EXIT_FAILURE;
}
compositeTransform->AddTransform(
affineRegistration->GetModifiableTransform() );
std::cout << "\nInitial parameters of the registration process: " << std::endl
<< movingInitTx->GetParameters() << std::endl;
std::cout << "\nTranslation parameters after registration: " << std::endl
<< transOptimizer->GetCurrentPosition() << std::endl
<< " Last LearningRate: " << transOptimizer->GetCurrentStepLength() << std::endl;
std::cout << "\nAffine parameters after registration: " << std::endl
<< affineOptimizer->GetCurrentPosition() << std::endl
<< " Last LearningRate: " << affineOptimizer->GetLearningRate() << std::endl;
MovingImageType,
FixedImageType >;
ResampleFilterType::Pointer resample = ResampleFilterType::New();
resample->SetTransform( compositeTransform );
resample->SetInput( movingImageReader->GetOutput() );
PixelType backgroundGrayLevel = 100;
if( argc > 4 )
{
backgroundGrayLevel = std::stoi( argv[4] );
}
resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
resample->SetOutputOrigin( fixedImage->GetOrigin() );
resample->SetOutputSpacing( fixedImage->GetSpacing() );
resample->SetOutputDirection( fixedImage->GetDirection() );
resample->SetDefaultPixelValue( backgroundGrayLevel );
using OutputPixelType = unsigned char;
FixedImageType,
OutputImageType >;
WriterType::Pointer writer = WriterType::New();
CastFilterType::Pointer caster = CastFilterType::New();
writer->SetFileName( argv[3] );
caster->SetInput( resample->GetOutput() );
writer->SetInput( caster->GetOutput() );
writer->Update();
CheckerBoardFilterType::Pointer checker = CheckerBoardFilterType::New();
checker->SetInput1( fixedImage );
checker->SetInput2( resample->GetOutput() );
caster->SetInput( checker->GetOutput() );
writer->SetInput( caster->GetOutput() );
resample->SetDefaultPixelValue( 0 );
TransformType::Pointer identityTransform;
try
{
identityTransform = TransformType::New();
}
{
return EXIT_FAILURE;
}
identityTransform->SetIdentity();
resample->SetTransform( identityTransform );
if( argc > 5 )
{
writer->SetFileName( argv[5] );
writer->Update();
}
resample->SetTransform( compositeTransform );
if( argc > 6 )
{
writer->SetFileName( argv[6] );
writer->Update();
}
return EXIT_SUCCESS;
}