Commit c4670f0b authored by Floris Berendsen's avatar Floris Berendsen
Browse files

WIP: ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent

parent bf17777d
......@@ -32,6 +32,7 @@
#include "itkComposeDisplacementFieldsImageFilter.h"
#include "itkGaussianExponentialDiffeomorphicTransform.h"
#include "itkGaussianExponentialDiffeomorphicTransformParametersAdaptor.h"
#include "itkArray.h"
namespace selx
{
......@@ -40,7 +41,7 @@ class ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent :
public SuperElastixComponent<
Accepting< itkImageDomainFixedInterface< Dimensionality >
>,
Providing< itkTransformParametersAdaptorInterface< itk::GaussianExponentialDiffeomorphicTransform< TransformInternalComputationValueType, Dimensionality> >
Providing< itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface< TransformInternalComputationValueType, Dimensionality>
>
>
{
......@@ -53,21 +54,25 @@ public:
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent();
virtual ~ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent();
typedef TPixel PixelType;
// Get the type definitions from the interfaces
typedef typename itkImageDomainFixedInterface< Dimensionality >::ItkImageDomainType FixedImageDomainType;
typedef itk::GaussianExponentialDiffeomorphicTransform< TransformInternalComputationValueType, Dimensionality> TransformType;
//typedef itk::GaussianExponentialDiffeomorphicTransform< TransformInternalComputationValueType, Dimensionality> TransformType;
// BaseTransformType acts as a container of the types: TParametersValueType, NInputDimensions, NOutputDimensions
typedef itk::Transform< TransformInternalComputationValueType, Dimensionality, Dimensionality > BaseTransformType;
using itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterfaceType = itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface< TransformInternalComputationValueType, Dimensionality >;
using TransformParametersAdaptorType = typename itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterfaceType::TransformParametersAdaptorType;;
using TransformParametersAdaptorsContainerType = typename itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterfaceType::TransformParametersAdaptorsContainerType;
typedef itk::ImageRegistrationMethodv4< FixedImageType, MovingImageType > TheItkFilterType;
typedef typename TheItkFilterType::ImageMetricType ImageMetricType;
typedef itk::RegistrationParameterScalesFromPhysicalShift< ImageMetricType > ScalesEstimatorType;
typedef itk::Array<itk::SizeValueType> ShrinkFactorsArrayType;
typedef itk::Array<TransformInternalComputationValueType> SmoothingSigmasArrayType;
//Accepting Interfaces:
virtual int Set( itkImageDomainFixedInterface< Dimensionality > * ) override;
//Providing Interfaces:
virtual itkTransformParametersAdaptorInterface< TransformType >::itkTransformParametersAdaptorPointer GetItkTransformParametersAdaptor() override;
virtual typename TransformParametersAdaptorsContainerType GetItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainer() override;
//BaseClass methods
virtual bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
......@@ -76,8 +81,15 @@ public:
static const char * GetDescription() { return "ItkImageRegistrationMethodv4 Component"; }
private:
typename TransformParametersAdaptorsContainerType m_adaptors;
typename TheItkFilterType::Pointer m_theItkFilter;
// Shrink the virtual domain by specified factors for each level. See documentation
// for the itkShrinkImageFilter for more detailed behavior.
ShrinkFactorsArrayType m_shrinkFactorsPerLevel;
// Smooth by specified gaussian sigmas for each level. These values are specified in
// physical units.
SmoothingSigmasArrayType m_smoothingSigmasPerLevel;
protected:
......@@ -86,108 +98,12 @@ protected:
static inline const std::string GetTypeNameString()
{
itkGenericExceptionMacro( << "Unknown ScalarType" << typeid( TPixel ).name() );
// TODO: provide the user instructions how to enable the compilation of the component with the required template types (if desired)
// We might define an exception object that can communicate various error messages: for simple user, for developer user, etc
}
static inline const std::string GetPixelTypeNameString()
{
itkGenericExceptionMacro( << "Unknown PixelType" << typeid( TPixel ).name() );
itkGenericExceptionMacro(<< "Unknown ScalarType" << typeid(TransformInternalComputationValueType).name());
// TODO: provide the user instructions how to enable the compilation of the component with the required template types (if desired)
// We might define an exception object that can communicate various error messages: for simple user, for developer user, etc
}
};
// unfortunately partial specialization of member functions is not allowed, without partially specializing the entire class.
/*
template <int Dimensionality>
class ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent < Dimensionality, double >
{
static inline const std::string GetPixelTypeNameString();
};
template <int Dimensionality>
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent<Dimensionality, double>
::GetPixelTypeNameString()
{
return std::string("double");
}
*/
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 2, float >
::GetPixelTypeNameString()
{
return std::string( "float" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 2, double >
::GetPixelTypeNameString()
{
return std::string( "double" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 3, float >
::GetPixelTypeNameString()
{
return std::string( "float" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 3, double >
::GetPixelTypeNameString()
{
return std::string( "double" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 2, float >
::GetTypeNameString()
{
return std::string( "2_float" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 2, double >
::GetTypeNameString()
{
return std::string( "2_double" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 3, float >
::GetTypeNameString()
{
return std::string( "3_float" );
}
template< >
inline const std::string
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< 3, double >
::GetTypeNameString()
{
return std::string( "3_double" );
}
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent.hxx"
......
......@@ -25,10 +25,6 @@ namespace selx
template< int Dimensionality, class TransformInternalComputationValueType >
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >::ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent()
{
m_theItkFilter = TheItkFilterType::New();
//TODO: instantiating the filter in the constructor might be heavy for the use in component selector factory, since all components of the database are created during the selection process.
// we could choose to keep the component light weighted (for checking criteria such as names and connections) until the settings are passed to the filter, but this requires an additional initialization step.
}
......@@ -41,72 +37,48 @@ ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensio
template< int Dimensionality, class TransformInternalComputationValueType >
int
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >
::Set( itkImageDomainFixedInterface< Dimensionality, TransformInternalComputationValueType > * component )
::Set( itkImageDomainFixedInterface< Dimensionality > * component )
{
auto fixedImageDomain = component->GetItkImageDomainFixed();
// connect the itk pipeline
this->m_theItkFilter->SetFixedImage(fixedImageDomain);
return 0;
}
// TODO for now we hard code the TransformAdaptors for stationary velocity fields.
typedef double RealType;
typedef itk::GaussianExponentialDiffeomorphicTransform< RealType, Dimensionality > ConstantVelocityFieldTransformType;
typedef typename ConstantVelocityFieldTransformType::ConstantVelocityFieldType ConstantVelocityFieldType;
typedef itk::GaussianExponentialDiffeomorphicTransformParametersAdaptor< ConstantVelocityFieldTransformType > VelocityFieldTransformAdaptorType;
typename TheItkFilterType::TransformParametersAdaptorsContainerType adaptors;
for( unsigned int level = 0; level < shrinkFactorsPerLevel.Size(); level++ )
for (unsigned int level = 0; level < m_shrinkFactorsPerLevel.Size(); level++)
{
// We use the shrink image filter to calculate the fixed parameters of the virtual
// domain at each level. To speed up calculation and avoid unnecessary memory
// usage, we could calculate these fixed parameters directly.
typedef itk::Image<TransformInternalComputationValueType, Dimensionality > FixedImageType;
FixedImageType::Pointer fixedImage = FixedImageType::New();
fixedImage->CopyInformation(fixedImageDomain);
fixedImage->Allocate();
typedef itk::ShrinkImageFilter< FixedImageType, FixedImageType > ShrinkFilterType;
typename ShrinkFilterType::Pointer shrinkFilter = ShrinkFilterType::New();
shrinkFilter->SetShrinkFactors( shrinkFactorsPerLevel[ level ] );
shrinkFilter->SetInput( fixedImage );
shrinkFilter->SetShrinkFactors(m_shrinkFactorsPerLevel[level]);
shrinkFilter->SetInput(fixedImage);
shrinkFilter->Update();
typename VelocityFieldTransformAdaptorType::Pointer fieldTransformAdaptor = VelocityFieldTransformAdaptorType::New();
fieldTransformAdaptor->SetRequiredSpacing( shrinkFilter->GetOutput()->GetSpacing() );
fieldTransformAdaptor->SetRequiredSize( shrinkFilter->GetOutput()->GetBufferedRegion().GetSize() );
fieldTransformAdaptor->SetRequiredDirection( shrinkFilter->GetOutput()->GetDirection() );
fieldTransformAdaptor->SetRequiredOrigin( shrinkFilter->GetOutput()->GetOrigin() );
typename TransformParametersAdaptorType::Pointer transformAdaptor = TransformParametersAdaptorType::New();
transformAdaptor->SetRequiredSpacing(shrinkFilter->GetOutput()->GetSpacing());
transformAdaptor->SetRequiredSize(shrinkFilter->GetOutput()->GetBufferedRegion().GetSize());
transformAdaptor->SetRequiredDirection(shrinkFilter->GetOutput()->GetDirection());
transformAdaptor->SetRequiredOrigin(shrinkFilter->GetOutput()->GetOrigin());
adaptors.push_back( fieldTransformAdaptor.GetPointer() );
m_adaptors.push_back(transformAdaptor.GetPointer());
}
/*
typename VelocityFieldTransformAdaptorType::Pointer fieldTransformAdaptor = VelocityFieldTransformAdaptorType::New();
fieldTransformAdaptor->SetRequiredSpacing(fixedImage->GetSpacing());
fieldTransformAdaptor->SetRequiredSize(fixedImage->GetBufferedRegion().GetSize());
fieldTransformAdaptor->SetRequiredDirection(fixedImage->GetDirection());
fieldTransformAdaptor->SetRequiredOrigin(fixedImage->GetOrigin());
adaptors.push_back(fieldTransformAdaptor.GetPointer());
*/
this->m_theItkFilter->SetTransformParametersAdaptorsPerLevel( adaptors );
typedef CommandIterationUpdate< TheItkFilterType > RegistrationCommandType;
typename RegistrationCommandType::Pointer registrationObserver = RegistrationCommandType::New();
this->m_theItkFilter->AddObserver( itk::IterationEvent(), registrationObserver );
// perform the actual registration
this->m_theItkFilter->Update();
return 0;
}
template< int Dimensionality, class TransformInternalComputationValueType >
typename ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >::TransformPointer
typename ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent<Dimensionality, TransformInternalComputationValueType >::TransformParametersAdaptorsContainerType
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >
::GetItkTransform()
::GetItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainer()
{
return this->m_theItkFilter->GetModifiableTransform();
return this->m_adaptors;
}
......@@ -139,17 +111,20 @@ ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensio
}
}
}
else if( criterion.first == "PixelType" ) //Supports this?
else if (criterion.first == "ShrinkFactorsPerLevel") //Supports this?
{
meetsCriteria = true;
for( auto const & criterionValue : criterion.second ) // auto&& preferred?
const int NumberOfResolutions = criterion.second.size(); // maybe check with criterion "NumberOfResolutions"?
m_shrinkFactorsPerLevel.SetSize(NumberOfResolutions);
unsigned int resolutionIndex = 0;
for (auto const & criterionValue : criterion.second) // auto&& preferred?
{
if( criterionValue != Self::GetPixelTypeNameString() )
{
meetsCriteria = false;
}
m_shrinkFactorsPerLevel[resolutionIndex] = std::stoi(criterionValue);
}
}
return meetsCriteria;
}
} //end namespace selx
......@@ -96,7 +96,7 @@ public:
ItkGradientDescentOptimizerv4Component< double >,
ItkAffineTransformComponent< double, 3 >,
ItkGaussianExponentialDiffeomorphicTransformComponent< double, 3 >,
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent<double,3>,
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent<3, double>,
ItkTransformDisplacementFilterComponent< 2, float, double >,
ItkTransformDisplacementFilterComponent< 3, double, double >,
ItkResampleFilterComponent< 2, float, double >,
......
......@@ -239,6 +239,16 @@ struct InterfaceName< ReconnectTransformInterface >
}
};
template< class InternalComputationValueType, int D >
struct InterfaceName< itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface< InternalComputationValueType, D > >
{
static const char * Get()
{
return "itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface";
}
};
// partial specialization of InterfaceName
// InterfaceName<T>::Get() should return the same name no matter whether T is an acceptor or provider interface.
template< typename T1 >
......
......@@ -28,6 +28,8 @@
#include "itkImageToImageMetricv4.h"
#include "itkObjectToObjectOptimizerBase.h"
#include "itkTransformParametersAdaptorBase.h"
#include "itkGaussianExponentialDiffeomorphicTransformParametersAdaptor.h"
#include "itkGaussianExponentialDiffeomorphicTransform.h"
#include "itkImage.h"
#include "itkMesh.h"
......@@ -269,6 +271,23 @@ public:
virtual TransformParametersAdaptorPointer GetItkTransformParametersAdaptor() = 0;
};
template< class TransformInternalComputationValueType, int Dimensionality >
class itkGaussianExponentialDiffeomorphicTransformParametersAdaptorInterface
{
public:
// Cannot use BaseTransformType
//typedef itk::Transform< TransformInternalComputationValueType, Dimensionality, Dimensionality > BaseTransformType;
using GaussianExponentialDiffeomorphicTransformType = itk::GaussianExponentialDiffeomorphicTransform< TransformInternalComputationValueType, Dimensionality >;
using TransformParametersAdaptorType = itk::GaussianExponentialDiffeomorphicTransformParametersAdaptor< GaussianExponentialDiffeomorphicTransformType >;
using TransformParametersAdaptorPointer = typename TransformParametersAdaptorType::Pointer;
using TransformParametersAdaptorsContainerType = std::vector<TransformParametersAdaptorPointer>;
//using TransformParametersAdaptorsContainerType = typename TransformParametersAdaptorType::TransformParametersAdaptorsContainerType;
virtual TransformParametersAdaptorsContainerType GetItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainer() = 0;
};
template< typename TFixedImage, typename TMovingImage >
class elastixTransformParameterObjectInterface
{
......
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