00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00024 #ifndef __elxElastixBase_h
00025 #define __elxElastixBase_h
00026
00027 #include "elxBaseComponent.h"
00028 #include "elxComponentDatabase.h"
00029 #include "elxConfiguration.h"
00030 #include "itkObject.h"
00031 #include "itkDataObject.h"
00032 #include "elxMacro.h"
00033 #include "xoutmain.h"
00034 #include "itkVectorContainer.h"
00035 #include "itkImageFileReader.h"
00036 #include "itkChangeInformationImageFilter.h"
00037
00038 #include <fstream>
00039 #include <iomanip>
00040
00047 #define elxGetObjectMacro(_name,_type) \
00048 virtual _type * Get##_name (void) const \
00049 { \
00050 return this->m_##_name .GetPointer(); \
00051 }
00052
00053
00054 #define elxSetObjectMacro(_name,_type) \
00055 virtual void Set##_name (_type * _arg) \
00056 { \
00057 if ( this->m_##_name != _arg ) \
00058 { \
00059 this->m_##_name = _arg; \
00060 this->GetAsITKBaseType()->Modified(); \
00061 } \
00062 }
00063
00064
00066 #define elxGetNumberOfMacro(_name) \
00067 virtual unsigned int GetNumberOf##_name##s(void) const \
00068 { \
00069 if ( this->Get##_name##Container() != 0 ) \
00070 { \
00071 return this->Get##_name##Container()->Size(); \
00072 } \
00073 return 0; \
00074 }
00075
00076
00077 namespace elastix
00078 {
00079 using namespace itk;
00080
00132 class ElastixBase : public BaseComponent
00133 {
00134 public:
00135
00137 typedef ElastixBase Self;
00138 typedef BaseComponent Superclass;
00139
00141 typedef Configuration ConfigurationType;
00142 typedef ConfigurationType::Pointer ConfigurationPointer;
00143 typedef itk::Object ObjectType;
00144 typedef ObjectType::Pointer ObjectPointer;
00145 typedef itk::DataObject DataObjectType;
00146 typedef DataObjectType::Pointer DataObjectPointer;
00147 typedef itk::VectorContainer<
00148 unsigned int, ObjectPointer> ObjectContainerType;
00149 typedef ObjectContainerType::Pointer ObjectContainerPointer;
00150 typedef itk::VectorContainer<
00151 unsigned int, DataObjectPointer> DataObjectContainerType;
00152 typedef DataObjectContainerType::Pointer DataObjectContainerPointer;
00153 typedef itk::VectorContainer<
00154 unsigned int, std::string > FileNameContainerType;
00155 typedef FileNameContainerType::Pointer FileNameContainerPointer;
00156
00158 typedef ComponentDatabase ComponentDatabaseType;
00159 typedef ComponentDatabaseType::Pointer ComponentDatabasePointer;
00160 typedef ComponentDatabaseType::IndexType DBIndexType;
00161 typedef std::vector<double> FlatDirectionCosinesType;
00162
00166 typedef Object ITKBaseType;
00167
00169 virtual ITKBaseType * GetAsITKBaseType( void )
00170 {
00171 return dynamic_cast<ITKBaseType *>( this );
00172 }
00173
00175 elxGetObjectMacro( Configuration, ConfigurationType );
00176 elxSetObjectMacro( Configuration, ConfigurationType );
00177
00179 virtual void SetDBIndex( DBIndexType _arg );
00180 virtual DBIndexType GetDBIndex( void )
00181 {
00182 return this->m_DBIndex;
00183 }
00184
00189 elxGetObjectMacro( ComponentDatabase, ComponentDatabaseType );
00190 elxSetObjectMacro( ComponentDatabase, ComponentDatabaseType );
00191
00196 elxGetObjectMacro( RegistrationContainer, ObjectContainerType );
00197 elxGetObjectMacro( FixedImagePyramidContainer, ObjectContainerType );
00198 elxGetObjectMacro( MovingImagePyramidContainer, ObjectContainerType );
00199 elxGetObjectMacro( InterpolatorContainer, ObjectContainerType );
00200 elxGetObjectMacro( ImageSamplerContainer, ObjectContainerType );
00201 elxGetObjectMacro( MetricContainer, ObjectContainerType );
00202 elxGetObjectMacro( OptimizerContainer, ObjectContainerType );
00203 elxGetObjectMacro( ResamplerContainer, ObjectContainerType );
00204 elxGetObjectMacro( ResampleInterpolatorContainer, ObjectContainerType );
00205 elxGetObjectMacro( TransformContainer, ObjectContainerType );
00206
00211 elxSetObjectMacro( RegistrationContainer, ObjectContainerType );
00212 elxSetObjectMacro( FixedImagePyramidContainer, ObjectContainerType );
00213 elxSetObjectMacro( MovingImagePyramidContainer, ObjectContainerType );
00214 elxSetObjectMacro( InterpolatorContainer, ObjectContainerType );
00215 elxSetObjectMacro( ImageSamplerContainer, ObjectContainerType );
00216 elxSetObjectMacro( MetricContainer, ObjectContainerType );
00217 elxSetObjectMacro( OptimizerContainer, ObjectContainerType );
00218 elxSetObjectMacro( ResamplerContainer, ObjectContainerType );
00219 elxSetObjectMacro( ResampleInterpolatorContainer, ObjectContainerType );
00220 elxSetObjectMacro( TransformContainer, ObjectContainerType );
00221
00223 elxGetObjectMacro( FixedImageContainer, DataObjectContainerType );
00224 elxGetObjectMacro( MovingImageContainer, DataObjectContainerType );
00225 elxSetObjectMacro( FixedImageContainer, DataObjectContainerType );
00226 elxSetObjectMacro( MovingImageContainer, DataObjectContainerType );
00227
00229 elxGetObjectMacro( FixedMaskContainer, DataObjectContainerType );
00230 elxGetObjectMacro( MovingMaskContainer, DataObjectContainerType );
00231 elxSetObjectMacro( FixedMaskContainer, DataObjectContainerType );
00232 elxSetObjectMacro( MovingMaskContainer, DataObjectContainerType );
00233
00237 elxGetObjectMacro( FixedImageFileNameContainer, FileNameContainerType );
00238 elxGetObjectMacro( MovingImageFileNameContainer, FileNameContainerType );
00239 elxSetObjectMacro( FixedImageFileNameContainer, FileNameContainerType );
00240 elxSetObjectMacro( MovingImageFileNameContainer, FileNameContainerType );
00241
00245 elxGetObjectMacro( FixedMaskFileNameContainer, FileNameContainerType );
00246 elxGetObjectMacro( MovingMaskFileNameContainer, FileNameContainerType );
00247 elxSetObjectMacro( FixedMaskFileNameContainer, FileNameContainerType );
00248 elxSetObjectMacro( MovingMaskFileNameContainer, FileNameContainerType );
00249
00251 elxGetNumberOfMacro( Registration );
00252 elxGetNumberOfMacro( FixedImagePyramid );
00253 elxGetNumberOfMacro( MovingImagePyramid );
00254 elxGetNumberOfMacro( Interpolator );
00255 elxGetNumberOfMacro( ImageSampler );
00256 elxGetNumberOfMacro( Metric );
00257 elxGetNumberOfMacro( Optimizer );
00258 elxGetNumberOfMacro( Resampler );
00259 elxGetNumberOfMacro( ResampleInterpolator );
00260 elxGetNumberOfMacro( Transform );
00261 elxGetNumberOfMacro( FixedImage );
00262 elxGetNumberOfMacro( MovingImage );
00263 elxGetNumberOfMacro( FixedImageFileName );
00264 elxGetNumberOfMacro( MovingImageFileName );
00265 elxGetNumberOfMacro( FixedMask );
00266 elxGetNumberOfMacro( MovingMask );
00267 elxGetNumberOfMacro( FixedMaskFileName );
00268 elxGetNumberOfMacro( MovingMaskFileName );
00269
00274 elxSetObjectMacro( InitialTransform, ObjectType );
00275 elxGetObjectMacro( InitialTransform, ObjectType );
00276
00283 elxSetObjectMacro( FinalTransform, ObjectType );
00284 elxGetObjectMacro( FinalTransform, ObjectType );
00285
00287 virtual int Run( void ) = 0;
00288
00290 virtual int ApplyTransform( void ) = 0;
00291
00295 virtual int BeforeAllBase( void );
00296
00300 virtual int BeforeAllTransformixBase( void );
00301
00305 virtual void BeforeRegistrationBase( void );
00306 virtual void AfterRegistrationBase( void );
00307
00312 virtual int GetDefaultOutputPrecision( void ) const
00313 {
00314 return this->m_DefaultOutputPrecision;
00315 }
00316
00320 virtual bool GetUseDirectionCosines( void ) const;
00321
00324 virtual void SetOriginalFixedImageDirectionFlat(
00325 const FlatDirectionCosinesType & arg );
00326 virtual const FlatDirectionCosinesType &
00327 GetOriginalFixedImageDirectionFlat( void ) const;
00328
00329 protected:
00330
00331 ElastixBase();
00332 virtual ~ElastixBase() {};
00333
00334 ConfigurationPointer m_Configuration;
00335 DBIndexType m_DBIndex;
00336 ComponentDatabasePointer m_ComponentDatabase;
00337
00338 FlatDirectionCosinesType m_OriginalFixedImageDirection;
00339
00352 template < class TImage >
00353 class MultipleImageLoader
00354 {
00355 public:
00356 typedef TImage ImageType;
00357 typedef typename ImageType::Pointer ImagePointer;
00358 typedef ImageFileReader<ImageType> ImageReaderType;
00359 typedef typename ImageReaderType::Pointer ImageReaderPointer;
00360 typedef typename ImageType::DirectionType DirectionType;
00361 typedef ChangeInformationImageFilter<ImageType> ChangeInfoFilterType;
00362 typedef typename ChangeInfoFilterType::Pointer ChangeInfoFilterPointer;
00363
00364 static DataObjectContainerPointer GenerateImageContainer(
00365 FileNameContainerType * fileNameContainer, const std::string & imageDescription,
00366 bool useDirectionCosines, DirectionType * originalDirectionCosines = NULL )
00367 {
00368 DataObjectContainerPointer imageContainer = DataObjectContainerType::New();
00369
00371 for ( unsigned int i = 0; i < fileNameContainer->Size(); ++i )
00372 {
00374 ImageReaderPointer imageReader = ImageReaderType::New();
00375 imageReader->SetFileName( fileNameContainer->ElementAt( i ).c_str() );
00376 ChangeInfoFilterPointer infoChanger = ChangeInfoFilterType::New();
00377 DirectionType direction;
00378 direction.SetIdentity();
00379 infoChanger->SetOutputDirection( direction );
00380 infoChanger->SetChangeDirection( !useDirectionCosines );
00381 infoChanger->SetInput( imageReader->GetOutput() );
00382
00384 try
00385 {
00386 infoChanger->Update();
00387 }
00388 catch( itk::ExceptionObject & excp )
00389 {
00391 std::string err_str = excp.GetDescription();
00392 err_str += "\nError occurred while reading the image described as "
00393 + imageDescription + ", with file name " + imageReader->GetFileName() + "\n";
00394 excp.SetDescription( err_str );
00396 throw excp;
00397 }
00398
00400 ImagePointer image = infoChanger->GetOutput();
00401 imageContainer->CreateElementAt(i) = image.GetPointer();
00402
00404 if ( originalDirectionCosines )
00405 {
00406 *originalDirectionCosines = imageReader->GetOutput()->GetDirection();
00407 }
00408
00409 }
00410
00411 return imageContainer;
00412
00413 }
00414
00415 MultipleImageLoader(){};
00416 ~MultipleImageLoader(){};
00417
00418 };
00419
00420 private:
00421
00422 ElastixBase( const Self& );
00423 void operator=( const Self& );
00424
00425 xl::xoutrow_type m_IterationInfo;
00426
00427 int m_DefaultOutputPrecision;
00428
00432 ObjectContainerPointer m_FixedImagePyramidContainer;
00433 ObjectContainerPointer m_MovingImagePyramidContainer;
00434 ObjectContainerPointer m_InterpolatorContainer;
00435 ObjectContainerPointer m_ImageSamplerContainer;
00436 ObjectContainerPointer m_MetricContainer;
00437 ObjectContainerPointer m_OptimizerContainer;
00438 ObjectContainerPointer m_RegistrationContainer;
00439 ObjectContainerPointer m_ResamplerContainer;
00440 ObjectContainerPointer m_ResampleInterpolatorContainer;
00441 ObjectContainerPointer m_TransformContainer;
00442
00444 DataObjectContainerPointer m_FixedImageContainer;
00445 DataObjectContainerPointer m_MovingImageContainer;
00446 DataObjectContainerPointer m_FixedMaskContainer;
00447 DataObjectContainerPointer m_MovingMaskContainer;
00448
00450 FileNameContainerPointer m_FixedImageFileNameContainer;
00451 FileNameContainerPointer m_MovingImageFileNameContainer;
00452 FileNameContainerPointer m_FixedMaskFileNameContainer;
00453 FileNameContainerPointer m_MovingMaskFileNameContainer;
00454
00456 ObjectPointer m_InitialTransform;
00457 ObjectPointer m_FinalTransform;
00458
00460 bool m_UseDirectionCosines;
00461
00469 FileNameContainerPointer GenerateFileNameContainer(
00470 const std::string & optionkey,
00471 int & errorcode,
00472 bool printerrors,
00473 bool printinfo ) const;
00474
00475 };
00476
00477
00478 }
00479
00480 #undef elxGetObjectMacro
00481 #undef elxSetObjectMacro
00482 #undef elxGetNumberOfMacro
00483
00484 #endif // end #ifndef __elxElastixBase_h
00485