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

WIP: added TransformParameterAdaptor

parent 18cdf09f
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* Center and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef selxItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent_h
#define selxItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent_h
#include "selxSuperElastixComponent.h"
#include "selxInterfaces.h"
#include "itkImageRegistrationMethodv4.h"
#include "itkGradientDescentOptimizerv4.h"
#include "itkImageSource.h"
#include <itkTransformToDisplacementFieldFilter.h>
#include <string.h>
#include "selxMacro.h"
#include "itkComposeDisplacementFieldsImageFilter.h"
#include "itkGaussianExponentialDiffeomorphicTransform.h"
#include "itkGaussianExponentialDiffeomorphicTransformParametersAdaptor.h"
namespace selx
{
template< int Dimensionality, class TransformInternalComputationValueType >
class ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent :
public SuperElastixComponent<
Accepting< itkImageDomainFixedInterface< Dimensionality >
>,
Providing< itkTransformParametersAdaptorInterface< itk::GaussianExponentialDiffeomorphicTransform< TransformInternalComputationValueType, Dimensionality> >
>
>
{
public:
selxNewMacro( ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent, ComponentBase );
//itkStaticConstMacro(Dimensionality, unsigned int, Dimensionality);
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::ImageRegistrationMethodv4< FixedImageType, MovingImageType > TheItkFilterType;
typedef typename TheItkFilterType::ImageMetricType ImageMetricType;
typedef itk::RegistrationParameterScalesFromPhysicalShift< ImageMetricType > ScalesEstimatorType;
//Accepting Interfaces:
virtual int Set( itkImageDomainFixedInterface< Dimensionality > * ) override;
//Providing Interfaces:
virtual itkTransformParametersAdaptorInterface< TransformType >::itkTransformParametersAdaptorPointer GetItkTransformParametersAdaptor() override;
//BaseClass methods
virtual bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
//static const char * GetName() { return "ItkImageRegistrationMethodv4"; } ;
static const char * GetDescription() { return "ItkImageRegistrationMethodv4 Component"; }
private:
typename TheItkFilterType::Pointer m_theItkFilter;
protected:
/* The following struct returns the string name of computation type */
/* default implementation */
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() );
// 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"
#endif
#endif // #define GDOptimizer3rdPartyComponent_h
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* Center and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#include "selxItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent.h"
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.
}
template< int Dimensionality, class TransformInternalComputationValueType >
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >::~ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent()
{
}
template< int Dimensionality, class TransformInternalComputationValueType >
int
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >
::Set( itkImageDomainFixedInterface< Dimensionality, TransformInternalComputationValueType > * 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++ )
{
// 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::ShrinkImageFilter< FixedImageType, FixedImageType > ShrinkFilterType;
typename ShrinkFilterType::Pointer shrinkFilter = ShrinkFilterType::New();
shrinkFilter->SetShrinkFactors( 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() );
adaptors.push_back( fieldTransformAdaptor.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();
}
template< int Dimensionality, class TransformInternalComputationValueType >
typename ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >::TransformPointer
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >
::GetItkTransform()
{
return this->m_theItkFilter->GetModifiableTransform();
}
template< int Dimensionality, class TransformInternalComputationValueType >
bool
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent< Dimensionality, TransformInternalComputationValueType >
::MeetsCriterion( const ComponentBase::CriterionType & criterion )
{
bool hasUndefinedCriteria( false );
bool meetsCriteria( false );
if( criterion.first == "ComponentProperty" )
{
meetsCriteria = true;
for( auto const & criterionValue : criterion.second ) // auto&& preferred?
{
if( criterionValue != "SomeProperty" ) // e.g. "GradientDescent", "SupportsSparseSamples
{
meetsCriteria = false;
}
}
}
else if( criterion.first == "Dimensionality" ) //Supports this?
{
meetsCriteria = true;
for( auto const & criterionValue : criterion.second ) // auto&& preferred?
{
if( std::stoi( criterionValue ) != Dimensionality )
{
meetsCriteria = false;
}
}
}
else if( criterion.first == "PixelType" ) //Supports this?
{
meetsCriteria = true;
for( auto const & criterionValue : criterion.second ) // auto&& preferred?
{
if( criterionValue != Self::GetPixelTypeNameString() )
{
meetsCriteria = false;
}
}
}
return meetsCriteria;
}
} //end namespace selx
......@@ -37,6 +37,7 @@
#include "selxItkGradientDescentOptimizerv4.h"
#include "selxItkAffineTransform.h"
#include "selxItkGaussianExponentialDiffeomorphicTransform.h"
#include "selxItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent.h"
#include "selxItkTransformDisplacementFilter.h"
#include "selxItkResampleFilter.h"
#include "selxItkImageSourceFixed.h"
......@@ -95,6 +96,7 @@ public:
ItkGradientDescentOptimizerv4Component< double >,
ItkAffineTransformComponent< double, 3 >,
ItkGaussianExponentialDiffeomorphicTransformComponent< double, 3 >,
ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorComponent<double,3>,
ItkTransformDisplacementFilterComponent< 2, float, double >,
ItkTransformDisplacementFilterComponent< 3, double, double >,
ItkResampleFilterComponent< 2, float, double >,
......
......@@ -27,6 +27,7 @@
#include "itkImageToImageFilter.h"
#include "itkImageToImageMetricv4.h"
#include "itkObjectToObjectOptimizerBase.h"
#include "itkTransformParametersAdaptorBase.h"
#include "itkImage.h"
#include "itkMesh.h"
......@@ -256,6 +257,18 @@ public:
virtual TransformPointer GetItkTransform() = 0;
};
template< class TitkTransformType >
class itkTransformParametersAdaptorInterface
{
public:
typedef TitkTransformType TransformType;
typedef typename itk::TransformParametersAdaptorBase< TransformType > TransformParametersAdaptorType;
typedef typename TransformParametersAdaptorType::Pointer TransformParametersAdaptorPointer;
virtual TransformParametersAdaptorPointer GetItkTransformParametersAdaptor() = 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