Commit ab5906cb authored by Floris Berendsen's avatar Floris Berendsen

ENH: removed deprecated ElastixComponent

parent 7dc499e4
/*=========================================================================
*
* 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 selxElastixComponent_h
#define selxElastixComponent_h
#include "selxSuperElastixComponent.h"
#include "selxSinksAndSourcesInterfaces.h"
#include "selxItkObjectInterfaces.h"
#include "itkImageSource.h"
#include "elxElastixFilter.h"
#include "elxParameterObject.h"
#include "elxTransformixFilter.h"
#include <string.h>
namespace selx
{
template< int Dimensionality, class TPixel >
class ElastixComponent :
public SuperElastixComponent<
Accepting<
itkImageFixedInterface< Dimensionality, TPixel >,
itkImageMovingInterface< Dimensionality, TPixel >
>,
Providing<
itkImageInterface< Dimensionality, TPixel >,
UpdateInterface
>
>
{
public:
/** Standard ITK typedefs. */
typedef ElastixComponent<
Dimensionality, TPixel
> Self;
typedef SuperElastixComponent<
Accepting<
itkImageFixedInterface< Dimensionality, TPixel >,
itkImageMovingInterface< Dimensionality, TPixel >
>,
Providing<
itkImageInterface< Dimensionality, TPixel >,
UpdateInterface
>
> Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
ElastixComponent( const std::string & name, LoggerImpl & logger );
virtual ~ElastixComponent();
typedef typename ComponentBase::CriterionType CriterionType;
typedef TPixel PixelType;
// the in and output image type of the component are chosen to be the same
typedef itk::Image< PixelType, Dimensionality > ConnectionImageType;
// fixed and moving image types are all the same, these aliases can be used to be explicit.
typedef itk::Image< PixelType, Dimensionality > FixedImageType;
typedef itk::Image< PixelType, Dimensionality > MovingImageType;
typedef typename ConnectionImageType::Pointer ItkImagePointer;
typedef elastix::ElastixFilter< FixedImageType, MovingImageType > ElastixFilterType;
typedef elastix::ParameterObject elxParameterObjectType;
typedef elxParameterObjectType::Pointer elxParameterObjectPointer;
typedef elastix::TransformixFilter< FixedImageType > TransformixFilterType;
virtual int Accept( typename itkImageFixedInterface< Dimensionality, TPixel >::Pointer ) override;
virtual int Accept( typename itkImageMovingInterface< Dimensionality, TPixel >::Pointer ) override;
virtual ItkImagePointer GetItkImage() override;
virtual void Update() override;
virtual bool MeetsCriterion( const CriterionType & criterion ) override;
static const char * GetDescription() { return "Elastix Component"; }
private:
typename ElastixFilterType::Pointer m_elastixFilter;
typename TransformixFilterType::Pointer m_transformixFilter;
//selxParameterObjectPointer m_ParameterObject;
ItkImagePointer m_OutputImage;
protected:
// return the class name and the template arguments to uniquely identify this component.
static inline const std::map< std::string, std::string > TemplateProperties()
{
return { { keys::NameOfClass, "ElastixComponent" }, { keys::PixelType, PodString< TPixel >::Get() }, { keys::Dimensionality, std::to_string( Dimensionality ) } };
}
};
} //end namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxElastixComponent.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 "selxElastixComponent.h"
#include "selxCheckTemplateProperties.h"
namespace selx
{
template< int Dimensionality, class TPixel >
ElastixComponent< Dimensionality, TPixel >::ElastixComponent( const std::string & name, LoggerImpl & logger ) : Superclass( name, logger )
{
m_elastixFilter = ElastixFilterType::New();
m_transformixFilter = TransformixFilterType::New();
// TODO: Due to some issues with Criteria being propagated as elastix settings, I need to empty the selxparameterObject.
elxParameterObjectPointer elxParameterObject = elxParameterObjectType::New();
typename elxParameterObjectType::ParameterMapType defaultParameters = elxParameterObject->GetDefaultParameterMap( "rigid" );
elxParameterObject->SetParameterMap( defaultParameters );
m_elastixFilter->SetParameterObject( elxParameterObject );
m_elastixFilter->LogToConsoleOn();
m_elastixFilter->LogToFileOff();
m_elastixFilter->SetOutputDirectory( "." );
m_transformixFilter->ComputeDeformationFieldOn();
m_transformixFilter->LogToConsoleOn();
m_transformixFilter->LogToFileOff();
m_transformixFilter->SetOutputDirectory( "." );
//TODO m_elastixFilter returns a nullptr GetTransformParameterObject instead of a valid object. However, we need this object to satisfy the input conditions of m_transformixFilter
//m_transformixFilter->SetTransformParameterObject(m_elastixFilter->GetTransformParameterObject());
m_transformixFilter->SetTransformParameterObject( elxParameterObject ); // supply a dummy object
//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 TPixel >
ElastixComponent< Dimensionality, TPixel >::~ElastixComponent()
{
}
template< int Dimensionality, class TPixel >
int
ElastixComponent< Dimensionality, TPixel >::Accept( typename itkImageFixedInterface< Dimensionality, TPixel >::Pointer component )
{
auto fixedImage = component->GetItkImageFixed();
// connect the itk pipeline
this->m_elastixFilter->SetFixedImage( fixedImage );
return 0;
}
template< int Dimensionality, class TPixel >
int
ElastixComponent< Dimensionality, TPixel >::Accept( typename itkImageMovingInterface< Dimensionality, TPixel >::Pointer component )
{
auto movingImage = component->GetItkImageMoving();
// connect the itk pipeline
this->m_elastixFilter->SetMovingImage( movingImage );
// In the current transformix filter an input image is required even if we want a deformation field only.
this->m_transformixFilter->SetMovingImage( movingImage );
return 0;
}
//Since elastixFilter is not a true itkfilter we cannot use itkImageSourceInterface (yet)
/*template<int Dimensionality, class TPixel>
typename ElastixComponent< Dimensionality, TPixel>::ItkImageSourcePointer ElastixComponent< Dimensionality, TPixel>::GetItkImageSource()
{
return (ItkImageSourcePointer) this->m_theItkFilter;
}
*/
template< int Dimensionality, class TPixel >
typename ElastixComponent< Dimensionality, TPixel >::ItkImagePointer
ElastixComponent< Dimensionality, TPixel >::GetItkImage()
{
return this->m_transformixFilter->GetOutput();
}
template< int Dimensionality, class TPixel >
void
ElastixComponent< Dimensionality, TPixel >::Update( void )
{
// TODO currently, the pipeline with elastix and tranformix can only be created after the update of elastix
this->m_elastixFilter->Update();
this->m_transformixFilter->SetTransformParameterObject( this->m_elastixFilter->GetTransformParameterObject() );
this->m_transformixFilter->Update();
}
template< int Dimensionality, class TPixel >
bool
ElastixComponent< Dimensionality, TPixel >
::MeetsCriterion( const CriterionType & criterion )
{
bool hasUndefinedCriteria( false );
bool meetsCriteria( false );
auto status = CheckTemplateProperties( this->TemplateProperties(), criterion );
if( status == CriterionStatus::Satisfied )
{
return true;
}
else if( status == CriterionStatus::Failed )
{
return false;
} // else: CriterionStatus::Unknown
else if( criterion.first == "RegistrationPreset" ) //Supports this?
{
// Temporary solution: RegistrationPreset: rigid, nonrigid, etc overwrite the current selxparameterObject.
// Warning: the order of Criteria matters, since selxparameterObject may be overwritten
// Warning: this probably fails because the Criteria map entries are processed in arbitrary order.
elxParameterObjectPointer elxParameterObject = elxParameterObjectType::New();
meetsCriteria = true;
for( auto const & presetName : criterion.second ) // auto&& preferred?
{
typename elxParameterObjectType::ParameterMapType presetParameters = elxParameterObject->GetDefaultParameterMap( presetName );
elxParameterObject->SetParameterMap( presetParameters );
try
{
this->m_elastixFilter->SetParameterObject( elxParameterObject );
}
catch( itk::ExceptionObject & err )
{
this->Error( err.what() );
meetsCriteria = false;
}
}
}
else
{
// temporary solution: pass all SuperElastixComponent parameters as is to elastix. This should be defined in deeper hierarchy of the criteria, but for now we have a flat mapping only.
elxParameterObjectPointer elxParameterObject = this->m_elastixFilter->GetParameterObject();
typename elxParameterObjectType::ParameterMapType newParameterMap = elxParameterObject->GetParameterMap( 0 ); //copy const paramtermap to a non const map
newParameterMap[ criterion.first ] = criterion.second; //overwrite element
elxParameterObjectPointer newParameterObject = elxParameterObjectType::New();
newParameterObject->SetParameterMap( newParameterMap );
this->m_elastixFilter->SetParameterObject( newParameterObject );
meetsCriteria = true;
}
return meetsCriteria;
}
} //end namespace selx
......@@ -20,14 +20,12 @@
#include "selxTypeList.h"
//Component group Elastix
#include "selxElastixComponent.h"
#include "selxMonolithicElastixComponent.h"
#include "selxMonolithicTransformixComponent.h"
namespace selx
{
using ModuleElastixComponents = selx::TypeList<
ElastixComponent< 2, float >,
MonolithicElastixComponent< 2, float >,
MonolithicElastixComponent< 3, short >,
MonolithicTransformixComponent< 2, float >
......
......@@ -20,7 +20,6 @@
#include "selxSuperElastixFilterCustomComponents.h"
#include "elxParameterObject.h"
#include "selxElastixComponent.h"
#include "selxMonolithicElastixComponent.h"
#include "selxMonolithicTransformixComponent.h"
#include "selxItkImageSinkComponent.h"
......@@ -46,7 +45,7 @@ public:
typedef DataManager DataManagerType;
/** Make a list of components to be registered for this test*/
typedef TypeList< ElastixComponent< 2, float >,
typedef TypeList<
MonolithicElastixComponent< 2, float >,
MonolithicTransformixComponent< 2, float >,
ItkImageSinkComponent< 2, float >,
......@@ -86,69 +85,6 @@ public:
DataManagerType::Pointer dataManager;
};
TEST_F( ElastixComponentTest, ImagesOnly )
{
/** make example blueprint configuration */
BlueprintPointer blueprint = Blueprint::New();
ParameterMapType component0Parameters;
component0Parameters[ "NameOfClass" ] = { "ElastixComponent" };
component0Parameters[ "RegistrationSettings" ] = { "rigid" };
component0Parameters[ "MaximumNumberOfIterations" ] = { "2" };
component0Parameters[ "Dimensionality" ] = { "2" };
component0Parameters[ "PixelType" ] = { "float" };
component0Parameters[ "ResultImagePixelType" ] = { "float" };
blueprint->SetComponent( "RegistrationMethod", component0Parameters );
ParameterMapType component1Parameters;
component1Parameters[ "NameOfClass" ] = { "ItkImageSourceComponent" };
component1Parameters[ "Dimensionality" ] = { "2" }; // should be derived from the inputs
blueprint->SetComponent( "FixedImageSource", component1Parameters );
ParameterMapType component2Parameters;
component2Parameters[ "NameOfClass" ] = { "ItkImageSourceComponent" };
component2Parameters[ "Dimensionality" ] = { "2" }; // should be derived from the inputs
blueprint->SetComponent( "MovingImageSource", component2Parameters );
ParameterMapType component3Parameters;
component3Parameters[ "NameOfClass" ] = { "ItkImageSinkComponent" };
component3Parameters[ "Dimensionality" ] = { "2" }; // should be derived from the inputs
blueprint->SetComponent( "ResultImageSink", component3Parameters );
ParameterMapType connection1Parameters;
//connection1Parameters["NameOfInterface"] = { "itkImageFixedInterface" };
blueprint->SetConnection( "FixedImageSource", "RegistrationMethod", connection1Parameters );
ParameterMapType connection2Parameters;
//connection2Parameters["NameOfInterface"] = { "itkImageMovingInterface" };
blueprint->SetConnection( "MovingImageSource", "RegistrationMethod", connection2Parameters );
ParameterMapType connection3Parameters;
//connection3Parameters["NameOfInterface"] = { "GetItkImageInterface" };
blueprint->SetConnection( "RegistrationMethod", "ResultImageSink", connection3Parameters );
// Set up the readers and writers
ImageReader2DType::Pointer fixedImageReader = ImageReader2DType::New();
fixedImageReader->SetFileName( dataManager->GetInputFile( "BrainProtonDensitySliceBorder20.png" ) );
ImageReader2DType::Pointer movingImageReader = ImageReader2DType::New();
movingImageReader->SetFileName( dataManager->GetInputFile( "BrainProtonDensitySliceR10X13Y17.png" ) );
ImageWriter2DType::Pointer resultImageWriter = ImageWriter2DType::New();
resultImageWriter->SetFileName( dataManager->GetOutputFile( "ElastixComponentTest_BrainProtonDensity.mhd" ) );
superElastixFilter->SetInput( "FixedImageSource", fixedImageReader->GetOutput() );
superElastixFilter->SetInput( "MovingImageSource", movingImageReader->GetOutput() );
resultImageWriter->SetInput( superElastixFilter->GetOutput< Image2DType >( "ResultImageSink" ) );
EXPECT_NO_THROW( superElastixFilter->SetBlueprint( blueprint ) );
// Update call on the writers triggers SuperElastix to configure and execute
resultImageWriter->Update();
}
TEST_F( ElastixComponentTest, MonolithicElastixTransformix )
{
/** make example blueprint configuration */
......
......@@ -28,7 +28,6 @@
#include "selxItkImageSinkComponent.h"
//Component group Elastix
#include "selxElastixComponent.h"
#include "selxMonolithicElastixComponent.h"
#include "selxMonolithicTransformixComponent.h"
......@@ -66,7 +65,6 @@ using DefaultComponents = selx::TypeList<
ItkImageSinkComponent< 3, short >,
ItkImageSourceComponent< 2, float >,
ItkImageSourceComponent< 3, short >,
ElastixComponent< 2, float >,
MonolithicElastixComponent< 2, float >,
MonolithicElastixComponent< 3, short >,
MonolithicTransformixComponent< 2, float >,
......
Markdown is supported
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