template <typename TRegistration>
{
public:
using Self = RegistrationInterfaceCommand;
protected:
RegistrationInterfaceCommand() = default;
public:
using RegistrationType = TRegistration;
void
{
}
void
{
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);
if (registration == nullptr)
{
itkExceptionMacro(<< "Dynamic cast failed, object of type "
}
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;
protected:
CommandIterationUpdate() = default;
public:
using OptimizerPointer = const OptimizerType *;
void
{
}
void
{
auto optimizer = static_cast<OptimizerPointer>(object);
if (optimizer == nullptr)
{
return;
}
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;
using MetricType =
MovingImageType>;
using TRegistrationType =
transRegistration->SetOptimizer(transOptimizer);
transRegistration->SetMetric(transMetric);
transRegistration->SetInitialTransform(translationTx);
transRegistration->InPlaceOn();
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);
transOptimizer->AddObserver(itk::IterationEvent(), observer1);
using TranslationCommandType =
RegistrationInterfaceCommand<TRegistrationType>;
transRegistration->AddObserver(itk::MultiResolutionIterationEvent(),
command1);
using AOptimizerType =
using ARegistrationType =
affineRegistration->SetOptimizer(affineOptimizer);
affineRegistration->SetMetric(affineMetric);
affineMetric->SetNumberOfHistogramBins(24);
if (argc > 7)
{
affineMetric->SetNumberOfHistogramBins(std::stoi(argv[7]));
}
fixedImageReader->Update();
using FixedImageCalculatorType =
fixedCalculator->SetImage(fixedImage);
fixedCalculator->Compute();
fixedCalculator->GetCenterOfGravity();
const unsigned int numberOfFixedParameters =
affineTx->GetFixedParameters().Size();
ATransformType::ParametersType fixedParameters(numberOfFixedParameters);
for (unsigned int i = 0; i < numberOfFixedParameters; ++i)
{
fixedParameters[i] = fixedCenter[i];
}
affineTx->SetFixedParameters(fixedParameters);
affineRegistration->SetInitialTransform(affineTx);
affineRegistration->InPlaceOn();
affineRegistration->SetFixedImage(fixedImageReader->GetOutput());
affineRegistration->SetMovingImage(movingImageReader->GetOutput());
affineRegistration->SetObjectName("AffineRegistration");
affineRegistration->SetMovingInitialTransformInput(
transRegistration->GetTransformOutput());
using ScalesEstimatorType =
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(10);
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>;
affineRegistration->AddObserver(itk::MultiResolutionIterationEvent(),
command2);
try
{
affineRegistration->Update();
std::cout
<< "Optimizer stop condition: "
<< affineRegistration->GetOptimizer()->GetStopConditionDescription()
<< std::endl;
}
catch (const itk::ExceptionObject & err)
{
std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl;
return EXIT_FAILURE;
}
compositeTransform->AddTransform(translationTx);
compositeTransform->AddTransform(affineTx);
std::cout << " Translation transform parameters after registration: "
<< std::endl
<< transOptimizer->GetCurrentPosition() << std::endl
<< " Last LearningRate: "
<< transOptimizer->GetCurrentStepLength() << std::endl;
std::cout << " Affine transform parameters after registration: "
<< std::endl
<< affineOptimizer->GetCurrentPosition() << std::endl
<< " Last LearningRate: " << affineOptimizer->GetLearningRate()
<< std::endl;
using ResampleFilterType =
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;
using CastFilterType =
writer->SetFileName(argv[3]);
caster->SetInput(resample->GetOutput());
writer->SetInput(caster->GetOutput());
writer->Update();
checker->SetInput1(fixedImage);
checker->SetInput2(resample->GetOutput());
caster->SetInput(checker->GetOutput());
writer->SetInput(caster->GetOutput());
resample->SetDefaultPixelValue(0);
try
{
}
catch (const itk::ExceptionObject & err)
{
err.Print(std::cerr);
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;
}