Commit 5c57aee8 authored by Floris Berendsen's avatar Floris Berendsen
Browse files

ENH: handle more settings ImageRegistrationMethodv4 and check their

consistencies
parent eb408865
......@@ -60,15 +60,18 @@ public:
virtual ~ItkImageRegistrationMethodv4Component();
typedef TPixel PixelType;
using TransformInternalComputationValueType = double; //should be in class template
// Get the type definitions from the interfaces
typedef typename itkOptimizerv4Interface< TransformInternalComputationValueType >::InternalComputationValueType OptimizerInternalComputationValueType; //should be from class template
typedef typename itkImageFixedInterface< Dimensionality, TPixel >::ItkImageType FixedImageType;
typedef typename itkImageMovingInterface< Dimensionality, TPixel >::ItkImageType MovingImageType;
typedef typename itkTransformInterface< double, Dimensionality >::TransformType TransformType;
typedef typename itkTransformInterface< double, Dimensionality >::TransformPointer TransformPointer;
typedef typename itkTransformInterface< TransformInternalComputationValueType, Dimensionality >::TransformType TransformType;
typedef typename itkTransformInterface< TransformInternalComputationValueType, Dimensionality >::TransformPointer TransformPointer;
typedef typename itkOptimizerv4Interface< double >::InternalComputationValueType OptimizerInternalComputationValueType; //should be from class template
typedef typename itkTransformInterface< double, Dimensionality >::InternalComputationValueType TransformInternalComputationValueType; //should be from class template
using TransformParametersAdaptorInterfaceType = itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface< TransformInternalComputationValueType, Dimensionality>;
typedef itk::ImageRegistrationMethodv4< FixedImageType, MovingImageType > TheItkFilterType;
typedef typename TheItkFilterType::ImageMetricType ImageMetricType;
......@@ -81,7 +84,7 @@ public:
virtual int Set( itkTransformInterface< TransformInternalComputationValueType, Dimensionality > * ) override;
virtual int Set( itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface< TransformInternalComputationValueType, Dimensionality> *) override;
virtual int Set(TransformParametersAdaptorInterfaceType *) override;
virtual int Set( itkMetricv4Interface< Dimensionality, TPixel > * ) override;
......@@ -101,7 +104,11 @@ public:
private:
typename TheItkFilterType::Pointer m_theItkFilter;
// The settings SmoothingSigmas and ShrinkFactors imply NumberOfLevels, if the user
// provides inconsistent numbers we should detect that and report about it.
std::string m_NumberOfLevelsLastSetBy;
TransformParametersAdaptorInterfaceType* m_TransformAdaptorInterface;
protected:
/* The following struct returns the string name of computation type */
......
......@@ -171,10 +171,8 @@ int
ItkImageRegistrationMethodv4Component< Dimensionality, TPixel >::Set(itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface< TransformInternalComputationValueType,
Dimensionality > * component)
{
auto adaptors = component->GetItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainer();
//TODO check number of resolutions?
this->m_theItkFilter->SetTransformParametersAdaptorsPerLevel(adaptors);
// store the interface to the ParametersAdaptorsContainer since during the setup of the connections the TransformParametersAdaptorComponent might not be fully connected and thus does not have the adaptors ready.
this->m_TransformAdaptorInterface = component;
return 0;
}
......@@ -252,6 +250,9 @@ ItkImageRegistrationMethodv4Component< Dimensionality, TPixel >::RunRegistration
smoothingSigmasPerLevel[ 2 ] = 1;
this->m_theItkFilter->SetSmoothingSigmasPerLevel( smoothingSigmasPerLevel );
this->m_theItkFilter->SetTransformParametersAdaptorsPerLevel(this->m_TransformAdaptorInterface->GetItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainer());
typedef CommandIterationUpdate< TheItkFilterType > RegistrationCommandType;
typename RegistrationCommandType::Pointer registrationObserver = RegistrationCommandType::New();
this->m_theItkFilter->AddObserver( itk::IterationEvent(), registrationObserver );
......@@ -310,14 +311,62 @@ ItkImageRegistrationMethodv4Component< Dimensionality, TPixel >
}
}
}
else if (criterion.first == "NumberOfLevels") //Supports this?
{
meetsCriteria = true;
if (criterion.second.size() == 1)
{
if (this->m_NumberOfLevelsLastSetBy == "") // check if some other settings set the NumberOfLevels
{
// try catch?
this->m_theItkFilter->SetNumberOfLevels(std::stoi(criterion.second[0]));
this->m_NumberOfLevelsLastSetBy = criterion.first;
}
else
{
if (this->m_theItkFilter->GetNumberOfLevels() != std::stoi(criterion.second[0]))
{
// TODO log error?
std::cout << "A conflicting NumberOfLevels was set by " << this->m_NumberOfLevelsLastSetBy << std::endl;
meetsCriteria = false;
return meetsCriteria;
}
}
}
else
{
// TODO log error?
std::cout << "NumberOfLevels accepts one number only" << std::endl;
meetsCriteria = false;
return meetsCriteria;
}
}
else if (criterion.first == "ShrinkFactorsPerLevel") //Supports this?
{
meetsCriteria = true;
const int NumberOfResolutions = criterion.second.size(); // maybe check with criterion "NumberOfResolutions"?
const int impliedNumberOfResolutions = criterion.second.size();
if (this->m_NumberOfLevelsLastSetBy == "") // check if some other settings set the NumberOfLevels
{
// try catch?
this->m_theItkFilter->SetNumberOfLevels(impliedNumberOfResolutions);
this->m_NumberOfLevelsLastSetBy = criterion.first;
}
else
{
if (this->m_theItkFilter->GetNumberOfLevels() != impliedNumberOfResolutions)
{
// TODO log error?
std::cout << "A conflicting NumberOfLevels was set by " << this->m_NumberOfLevelsLastSetBy << std::endl;
meetsCriteria = false;
return meetsCriteria;;
}
}
itk::Array<itk::SizeValueType> shrinkFactorsPerLevel;
shrinkFactorsPerLevel.SetSize(NumberOfResolutions);
shrinkFactorsPerLevel.SetSize(impliedNumberOfResolutions);
unsigned int resolutionIndex = 0;
for (auto const & criterionValue : criterion.second) // auto&& preferred?
......@@ -328,6 +377,45 @@ ItkImageRegistrationMethodv4Component< Dimensionality, TPixel >
// try catch?
this->m_theItkFilter->SetShrinkFactorsPerLevel(shrinkFactorsPerLevel);
}
else if (criterion.first == "SmoothingSigmasPerLevel") //Supports this?
{
meetsCriteria = true;
const int impliedNumberOfResolutions = criterion.second.size();
if (this->m_NumberOfLevelsLastSetBy == "") // check if some other settings set the NumberOfLevels
{
// try catch?
this->m_theItkFilter->SetNumberOfLevels(impliedNumberOfResolutions);
this->m_NumberOfLevelsLastSetBy = criterion.first;
}
else
{
if (this->m_theItkFilter->GetNumberOfLevels() != impliedNumberOfResolutions)
{
// TODO log error?
std::cout << "A conflicting NumberOfLevels was set by " << this->m_NumberOfLevelsLastSetBy << std::endl;
meetsCriteria = false;
return meetsCriteria;;
}
}
itk::Array<TransformInternalComputationValueType> smoothingSigmasPerLevel;
smoothingSigmasPerLevel.SetSize(impliedNumberOfResolutions);
unsigned int resolutionIndex = 0;
for (auto const & criterionValue : criterion.second) // auto&& preferred?
{
smoothingSigmasPerLevel[resolutionIndex] = std::stoi(criterionValue);
++resolutionIndex;
}
// try catch?
// Smooth by specified gaussian sigmas for each level. These values are specified in
// physical units.
this->m_theItkFilter->SetSmoothingSigmasPerLevel(smoothingSigmasPerLevel);
}
return meetsCriteria;
}
} //end namespace selx
......@@ -34,6 +34,7 @@
#include "selxItkMeanSquaresImageToImageMetricv4.h"
#include "selxItkGradientDescentOptimizerv4.h"
#include "selxItkGaussianExponentialDiffeomorphicTransform.h"
#include "selxItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent.h"
#include "selxItkTransformDisplacementFilter.h"
#include "selxItkResampleFilter.h"
#include "selxRegistrationController.h"
......@@ -74,6 +75,7 @@ public:
ItkMeanSquaresImageToImageMetricv4Component< 2, float >,
ItkGradientDescentOptimizerv4Component< double >,
ItkGaussianExponentialDiffeomorphicTransformComponent< double, 2 >,
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 2, double >,
ItkTransformDisplacementFilterComponent< 2, float, double >,
ItkResampleFilterComponent< 2, float, double >,
RegistrationControllerComponent< >> RegisterComponents;
......@@ -142,14 +144,18 @@ TEST_F( WBIRDemoTest, itkv4_SVF_ANTSCC )
{
/** make example blueprint configuration */
blueprint = Blueprint::New();
blueprint->AddComponent("RegistrationMethod", { { "NameOfClass", { "ItkImageRegistrationMethodv4Component" } },
{ "ShrinkFactorsPerLevel", { "4", "2", "1" } } });
blueprint->AddComponent( "RegistrationMethod", { { "NameOfClass", { "ItkImageRegistrationMethodv4Component" } } } );
blueprint->AddComponent( "Metric", { { "NameOfClass", { "ItkANTSNeighborhoodCorrelationImageToImageMetricv4Component" } } } );
blueprint->AddComponent( "Optimizer", { { "NameOfClass", { "ItkGradientDescentOptimizerv4Component" } },
{ "NumberOfIterations", { "100" } },
{ "LearningRate", { "100" } } } );
blueprint->AddComponent( "Transform", { { "NameOfClass", { "ItkGaussianExponentialDiffeomorphicTransformComponent" } } } );
blueprint->AddComponent("TransformResolutionAdaptor", { { "NameOfClass", { "ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent" } },
{ "ShrinkFactorsPerLevel", { "4", "2", "1" } } });
blueprint->AddComponent( "ResampleFilter", { { "NameOfClass", { "ItkResampleFilterComponent" } } } );
blueprint->AddComponent( "TransformDisplacementFilter", { { "NameOfClass", { "ItkTransformDisplacementFilterComponent" } } } );
......@@ -181,6 +187,8 @@ TEST_F( WBIRDemoTest, itkv4_SVF_ANTSCC )
blueprint->AddConnection( "FixedImageSource", "Transform", { {} } );
blueprint->AddConnection( "Transform", "RegistrationMethod", { {} } );
blueprint->AddConnection( "FixedImageSource", "TransformResolutionAdaptor", { {} });
blueprint->AddConnection( "TransformResolutionAdaptor", "RegistrationMethod", { {} });
blueprint->AddConnection( "Optimizer", "RegistrationMethod", { {} } );
blueprint->AddConnection( "RegistrationMethod", "TransformDisplacementFilter", { {} } );
blueprint->AddConnection( "FixedImageSource", "TransformDisplacementFilter", { {} } );
......@@ -191,8 +199,7 @@ TEST_F( WBIRDemoTest, itkv4_SVF_ANTSCC )
blueprint->AddConnection( "RegistrationMethod", "Controller", { {} } ); //RunRegistrationInterface
blueprint->AddConnection( "ResampleFilter", "Controller", { {} } ); //ReconnectTransformInterface
blueprint->AddConnection( "TransformDisplacementFilter", "Controller", { {} } ); //ReconnectTransformInterface
blueprint->AddConnection( "ResultImageSink", "Controller", { {} } ); //AfterRegistrationInterface
blueprint->AddConnection( "ResultDisplacementFieldSink", "Controller", { {} } ); //AfterRegistrationInterface
// Data manager provides the paths to the input and output data for unit tests
DataManagerType::Pointer dataManager = DataManagerType::New();
......
......@@ -114,7 +114,21 @@ Overlord::ApplyNodeConfiguration()
Blueprint::ParameterMapType currentProperty = this->m_Blueprint->GetComponent( name );
for( auto const & criterion : currentProperty )
{
std::cout << " " << criterion.first << ": " << criterion.second[ 0 ] << std::endl;
std::cout << " " << criterion.first << ": ";
if (criterion.second.size() > 1)
{
std::cout << "[ ";
for (auto const element : criterion.second)
{
std::cout << element << " ";
}
std::cout << "]";
}
else
{
std::cout << criterion.second[0];
}
std::cout << std::endl;
currentComponentSelector->AddCriterion( criterion );
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment