From fef5d95e943e493bd95fef9395e1b5ac3b7e00d9 Mon Sep 17 00:00:00 2001 From: "nissim.hadar" Date: Mon, 20 Nov 2017 12:33:38 -0800 Subject: [PATCH] First fully-coded registration. --- tools/auto-tester/src/ITKImageComparer.cpp | 75 +++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/tools/auto-tester/src/ITKImageComparer.cpp b/tools/auto-tester/src/ITKImageComparer.cpp index b7e1ee2423..e0ebcb8c16 100644 --- a/tools/auto-tester/src/ITKImageComparer.cpp +++ b/tools/auto-tester/src/ITKImageComparer.cpp @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include ITKImageComparer::ITKImageComparer() { // These are smart pointers that do not need to be deleted @@ -25,7 +29,7 @@ float ITKImageComparer::compareImages(QString resultImageFilename, QString expec expectedImageReader->SetFileName(expectedImageFilename.toStdString().c_str()); // Images are converted to monochrome for comparison - using MonochromePixelType = unsigned char; + using MonochromePixelType = double; using MonochromeImageType = itk::Image; using FilterType = itk::RGBToLuminanceImageFilter; @@ -35,5 +39,72 @@ float ITKImageComparer::compareImages(QString resultImageFilename, QString expec resultImageToMonochrome->SetInput(resultImageReader->GetOutput()); expectedImageToMonochrome->SetInput(expectedImageReader->GetOutput()); - return 0.0; + // Setup registration components + // The transform that will map the fixed image space into the moving image space + using TransformType = itk::TranslationTransform; + + // The optimizer explores the parameter space of the transform in search of optimal values of the metric + using OptimizerType = itk::RegularStepGradientDescentOptimizerv4; + + // The metric will compare how well the two images match each other + using MetricType = itk::MeanSquaresImageToImageMetricv4; + + //The registration method type is instantiated using the types of the fixed and moving images as well + // as the output transform type.This class is responsible for interconnecting the components + using RegistrationType = itk::ImageRegistrationMethodv4; + + // Create registration components (smart pointers, so no need to delete) + MetricType::Pointer metric = MetricType::New(); + OptimizerType::Pointer optimizer = OptimizerType::New(); + RegistrationType::Pointer registration = RegistrationType::New(); + + // The comparison metric needs an interpreter. + // The same interpolator is used for both images + using LinearInterpolatorType = itk::LinearInterpolateImageFunction; + LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); + metric->SetFixedInterpolator(interpolator); + metric->SetMovingInterpolator(interpolator); + + // Connect components + registration->SetMetric(metric); + registration->SetOptimizer(optimizer); + registration->SetFixedImage(resultImageToMonochrome->GetOutput()); + registration->SetMovingImage(expectedImageToMonochrome->GetOutput()); + + // Initialization + TransformType::Pointer movingInitialTransform = TransformType::New(); + TransformType::ParametersType initialParameters(movingInitialTransform->GetNumberOfParameters()); + + initialParameters[0] = 0.0; // Initial offset in mm along X + initialParameters[1] = 0.0; // Initial offset in mm along Y + + movingInitialTransform->SetParameters(initialParameters); + registration->SetMovingInitialTransform(movingInitialTransform); + + // Set optimizer parameters + optimizer->SetLearningRate(4); + optimizer->SetMinimumStepLength(0.001); + optimizer->SetRelaxationFactor(0.5); + optimizer->SetNumberOfIterations(200); + + // Define registration criteria + const unsigned int numberOfLevels = 1; + RegistrationType::ShrinkFactorsArrayType shrinkFactorsPerLevel; + shrinkFactorsPerLevel.SetSize(1); + shrinkFactorsPerLevel[0] = 1; + RegistrationType::SmoothingSigmasArrayType smoothingSigmasPerLevel; + smoothingSigmasPerLevel.SetSize(1); + smoothingSigmasPerLevel[0] = 0; + registration->SetNumberOfLevels(numberOfLevels); + registration->SetSmoothingSigmasPerLevel(smoothingSigmasPerLevel); + registration->SetShrinkFactorsPerLevel(shrinkFactorsPerLevel); + + // Activate the registration project + try + { + registration->Update(); + return 0.0; + } catch (itk::ExceptionObject & err) { + return EXIT_FAILURE; + } }