mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 14:53:01 +02:00
New image comparison method.
This commit is contained in:
parent
346c691f0c
commit
857f2c6880
3 changed files with 20 additions and 73 deletions
|
@ -10,13 +10,8 @@
|
|||
|
||||
#include "ITKImageComparer.h"
|
||||
|
||||
#include <itkRGBPixel.h>
|
||||
#include <itkImage.h>
|
||||
#include <itkRGBToLuminanceImageFilter.h>
|
||||
#include <itkTranslationTransform.h>
|
||||
#include <itkRegularStepGradientDescentOptimizerv4.h>
|
||||
#include <itkMeanSquaresImageToImageMetricv4.h>
|
||||
#include <itkImageRegistrationMethodv4.h>
|
||||
#include <itkTestingComparisonImageFilter.h>
|
||||
|
||||
ITKImageComparer::ITKImageComparer() {
|
||||
// These are smart pointers that do not need to be deleted
|
||||
|
@ -39,72 +34,19 @@ float ITKImageComparer::compareImages(QString resultImageFilename, QString expec
|
|||
resultImageToMonochrome->SetInput(resultImageReader->GetOutput());
|
||||
expectedImageToMonochrome->SetInput(expectedImageReader->GetOutput());
|
||||
|
||||
// Setup registration components
|
||||
// The transform that will map the fixed image space into the moving image space
|
||||
using TransformType = itk::TranslationTransform<double, Dimension>;
|
||||
using DiffType = itk::Testing::ComparisonImageFilter<MonochromeImageType, MonochromeImageType>;
|
||||
DiffType::Pointer diff = DiffType::New();
|
||||
|
||||
// The optimizer explores the parameter space of the transform in search of optimal values of the metric
|
||||
using OptimizerType = itk::RegularStepGradientDescentOptimizerv4<double>;
|
||||
diff->SetTestInput(resultImageToMonochrome->GetOutput());
|
||||
diff->SetValidInput(expectedImageToMonochrome->GetOutput());
|
||||
|
||||
// The metric will compare how well the two images match each other
|
||||
using MetricType = itk::MeanSquaresImageToImageMetricv4<MonochromeImageType, MonochromeImageType>;
|
||||
const double INTENSITY_TOLERANCE = 0.01;
|
||||
diff->SetDifferenceThreshold(INTENSITY_TOLERANCE);
|
||||
|
||||
//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<MonochromeImageType, MonochromeImageType, TransformType>;
|
||||
const double RADIUS_TOLERANCE = 2.0;
|
||||
diff->SetToleranceRadius(RADIUS_TOLERANCE);
|
||||
|
||||
// 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();
|
||||
diff->UpdateLargestPossibleRegion();
|
||||
|
||||
// The comparison metric needs an interpreter.
|
||||
// The same interpolator is used for both images
|
||||
using LinearInterpolatorType = itk::LinearInterpolateImageFunction<MonochromeImageType, double>;
|
||||
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;
|
||||
}
|
||||
return (float)diff->GetNumberOfPixelsWithDifferences();
|
||||
}
|
||||
|
|
|
@ -62,7 +62,8 @@ void Test::evaluateTests() {
|
|||
messageBox.critical(0,
|
||||
"Test failed",
|
||||
"Found " + QString::number(resultImages.length()) + " images in directory" +
|
||||
"\nExpected to find " + QString::number(expectedImages.length()) + " images");
|
||||
"\nExpected to find " + QString::number(expectedImages.length()) + " images"
|
||||
);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -138,11 +139,13 @@ void Test::createRecursiveScript() {
|
|||
QFileInfo fileInfo(testPathname);
|
||||
if (fileInfo.exists()) {
|
||||
// Current folder contains a test
|
||||
textStream << "Script.include(\"" << testPathname << "/" << " ? raw = true\")" << endl;
|
||||
textStream << "Script.include(\"" << testPathname + "\")" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
allTestsFilename.close();
|
||||
|
||||
messageBox.information(0, "Success", "Script has been created");
|
||||
}
|
||||
|
||||
void Test::createTest() {
|
||||
|
@ -166,6 +169,8 @@ void Test::createTest() {
|
|||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
messageBox.information(0, "Success", "Test images have been created");
|
||||
}
|
||||
|
||||
void Test::createListOfAllJPEGimagesInDirectory() {
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
_actualImageFilename = actualImageFilename;
|
||||
}
|
||||
|
||||
float _error;
|
||||
double _error;
|
||||
QString _pathname;
|
||||
QString _expectedImageFilename;
|
||||
QString _actualImageFilename;
|
||||
|
|
Loading…
Reference in a new issue