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
00141 class ElastixBase : public BaseComponent
00142 {
00143 public:
00144
00146 typedef ElastixBase Self;
00147 typedef BaseComponent Superclass;
00148
00150 typedef Configuration ConfigurationType;
00151 typedef ConfigurationType::Pointer ConfigurationPointer;
00152 typedef itk::Object ObjectType;
00153 typedef ObjectType::Pointer ObjectPointer;
00154 typedef itk::DataObject DataObjectType;
00155 typedef DataObjectType::Pointer DataObjectPointer;
00156 typedef itk::VectorContainer<
00157 unsigned int, ObjectPointer> ObjectContainerType;
00158 typedef ObjectContainerType::Pointer ObjectContainerPointer;
00159 typedef itk::VectorContainer<
00160 unsigned int, DataObjectPointer> DataObjectContainerType;
00161 typedef DataObjectContainerType::Pointer DataObjectContainerPointer;
00162 typedef itk::VectorContainer<
00163 unsigned int, std::string > FileNameContainerType;
00164 typedef FileNameContainerType::Pointer FileNameContainerPointer;
00165
00167 typedef ComponentDatabase ComponentDatabaseType;
00168 typedef ComponentDatabaseType::Pointer ComponentDatabasePointer;
00169 typedef ComponentDatabaseType::IndexType DBIndexType;
00170 typedef std::vector<double> FlatDirectionCosinesType;
00171
00175 typedef Object ITKBaseType;
00176
00178 virtual ITKBaseType * GetAsITKBaseType( void )
00179 {
00180 return dynamic_cast<ITKBaseType *>( this );
00181 }
00182
00184 elxGetObjectMacro( Configuration, ConfigurationType );
00185 elxSetObjectMacro( Configuration, ConfigurationType );
00186
00188 virtual void SetDBIndex( DBIndexType _arg );
00189 virtual DBIndexType GetDBIndex( void )
00190 {
00191 return this->m_DBIndex;
00192 }
00193
00198 elxGetObjectMacro( ComponentDatabase, ComponentDatabaseType );
00199 elxSetObjectMacro( ComponentDatabase, ComponentDatabaseType );
00200
00205 elxGetObjectMacro( RegistrationContainer, ObjectContainerType );
00206 elxGetObjectMacro( FixedImagePyramidContainer, ObjectContainerType );
00207 elxGetObjectMacro( MovingImagePyramidContainer, ObjectContainerType );
00208 elxGetObjectMacro( InterpolatorContainer, ObjectContainerType );
00209 elxGetObjectMacro( ImageSamplerContainer, ObjectContainerType );
00210 elxGetObjectMacro( MetricContainer, ObjectContainerType );
00211 elxGetObjectMacro( OptimizerContainer, ObjectContainerType );
00212 elxGetObjectMacro( ResamplerContainer, ObjectContainerType );
00213 elxGetObjectMacro( ResampleInterpolatorContainer, ObjectContainerType );
00214 elxGetObjectMacro( TransformContainer, ObjectContainerType );
00215
00220 elxSetObjectMacro( RegistrationContainer, ObjectContainerType );
00221 elxSetObjectMacro( FixedImagePyramidContainer, ObjectContainerType );
00222 elxSetObjectMacro( MovingImagePyramidContainer, ObjectContainerType );
00223 elxSetObjectMacro( InterpolatorContainer, ObjectContainerType );
00224 elxSetObjectMacro( ImageSamplerContainer, ObjectContainerType );
00225 elxSetObjectMacro( MetricContainer, ObjectContainerType );
00226 elxSetObjectMacro( OptimizerContainer, ObjectContainerType );
00227 elxSetObjectMacro( ResamplerContainer, ObjectContainerType );
00228 elxSetObjectMacro( ResampleInterpolatorContainer, ObjectContainerType );
00229 elxSetObjectMacro( TransformContainer, ObjectContainerType );
00230
00232 elxGetObjectMacro( FixedImageContainer, DataObjectContainerType );
00233 elxGetObjectMacro( MovingImageContainer, DataObjectContainerType );
00234 elxSetObjectMacro( FixedImageContainer, DataObjectContainerType );
00235 elxSetObjectMacro( MovingImageContainer, DataObjectContainerType );
00236
00238 elxGetObjectMacro( FixedMaskContainer, DataObjectContainerType );
00239 elxGetObjectMacro( MovingMaskContainer, DataObjectContainerType );
00240 elxSetObjectMacro( FixedMaskContainer, DataObjectContainerType );
00241 elxSetObjectMacro( MovingMaskContainer, DataObjectContainerType );
00242
00246 elxGetObjectMacro( FixedImageFileNameContainer, FileNameContainerType );
00247 elxGetObjectMacro( MovingImageFileNameContainer, FileNameContainerType );
00248 elxSetObjectMacro( FixedImageFileNameContainer, FileNameContainerType );
00249 elxSetObjectMacro( MovingImageFileNameContainer, FileNameContainerType );
00250
00254 elxGetObjectMacro( FixedMaskFileNameContainer, FileNameContainerType );
00255 elxGetObjectMacro( MovingMaskFileNameContainer, FileNameContainerType );
00256 elxSetObjectMacro( FixedMaskFileNameContainer, FileNameContainerType );
00257 elxSetObjectMacro( MovingMaskFileNameContainer, FileNameContainerType );
00258
00260 elxGetNumberOfMacro( Registration );
00261 elxGetNumberOfMacro( FixedImagePyramid );
00262 elxGetNumberOfMacro( MovingImagePyramid );
00263 elxGetNumberOfMacro( Interpolator );
00264 elxGetNumberOfMacro( ImageSampler );
00265 elxGetNumberOfMacro( Metric );
00266 elxGetNumberOfMacro( Optimizer );
00267 elxGetNumberOfMacro( Resampler );
00268 elxGetNumberOfMacro( ResampleInterpolator );
00269 elxGetNumberOfMacro( Transform );
00270 elxGetNumberOfMacro( FixedImage );
00271 elxGetNumberOfMacro( MovingImage );
00272 elxGetNumberOfMacro( FixedImageFileName );
00273 elxGetNumberOfMacro( MovingImageFileName );
00274 elxGetNumberOfMacro( FixedMask );
00275 elxGetNumberOfMacro( MovingMask );
00276 elxGetNumberOfMacro( FixedMaskFileName );
00277 elxGetNumberOfMacro( MovingMaskFileName );
00278
00283 elxSetObjectMacro( InitialTransform, ObjectType );
00284 elxGetObjectMacro( InitialTransform, ObjectType );
00285
00292 elxSetObjectMacro( FinalTransform, ObjectType );
00293 elxGetObjectMacro( FinalTransform, ObjectType );
00294
00296 virtual int Run( void ) = 0;
00297
00299 virtual int ApplyTransform( void ) = 0;
00300
00304 virtual int BeforeAllBase( void );
00305
00309 virtual int BeforeAllTransformixBase( void );
00310
00314 virtual void BeforeRegistrationBase( void );
00315 virtual void AfterRegistrationBase( void );
00316
00321 virtual int GetDefaultOutputPrecision( void ) const
00322 {
00323 return this->m_DefaultOutputPrecision;
00324 }
00325
00329 virtual bool GetUseDirectionCosines( void ) const;
00330
00333 virtual void SetOriginalFixedImageDirectionFlat(
00334 const FlatDirectionCosinesType & arg );
00335 virtual const FlatDirectionCosinesType &
00336 GetOriginalFixedImageDirectionFlat( void ) const;
00337
00338 protected:
00339
00340 ElastixBase();
00341 virtual ~ElastixBase() {};
00342
00343 ConfigurationPointer m_Configuration;
00344 DBIndexType m_DBIndex;
00345 ComponentDatabasePointer m_ComponentDatabase;
00346
00347 FlatDirectionCosinesType m_OriginalFixedImageDirection;
00348
00361 template < class TImage >
00362 class MultipleImageLoader
00363 {
00364 public:
00365 typedef TImage ImageType;
00366 typedef typename ImageType::Pointer ImagePointer;
00367 typedef ImageFileReader<ImageType> ImageReaderType;
00368 typedef typename ImageReaderType::Pointer ImageReaderPointer;
00369 typedef typename ImageType::DirectionType DirectionType;
00370 typedef ChangeInformationImageFilter<ImageType> ChangeInfoFilterType;
00371 typedef typename ChangeInfoFilterType::Pointer ChangeInfoFilterPointer;
00372
00373 static DataObjectContainerPointer GenerateImageContainer(
00374 FileNameContainerType * fileNameContainer, const std::string & imageDescription,
00375 bool useDirectionCosines, DirectionType * originalDirectionCosines = NULL )
00376 {
00377 DataObjectContainerPointer imageContainer = DataObjectContainerType::New();
00378
00380 for ( unsigned int i = 0; i < fileNameContainer->Size(); ++i )
00381 {
00383 ImageReaderPointer imageReader = ImageReaderType::New();
00384 imageReader->SetFileName( fileNameContainer->ElementAt( i ).c_str() );
00385 ChangeInfoFilterPointer infoChanger = ChangeInfoFilterType::New();
00386 DirectionType direction;
00387 direction.SetIdentity();
00388 infoChanger->SetOutputDirection( direction );
00389 infoChanger->SetChangeDirection( !useDirectionCosines );
00390 infoChanger->SetInput( imageReader->GetOutput() );
00391
00393 try
00394 {
00395 infoChanger->Update();
00396 }
00397 catch( itk::ExceptionObject & excp )
00398 {
00400 std::string err_str = excp.GetDescription();
00401 err_str += "\nError occurred while reading the image described as "
00402 + imageDescription + ", with file name " + imageReader->GetFileName() + "\n";
00403 excp.SetDescription( err_str );
00405 throw excp;
00406 }
00407
00409 ImagePointer image = infoChanger->GetOutput();
00410 imageContainer->CreateElementAt(i) = image.GetPointer();
00411
00413 if ( originalDirectionCosines )
00414 {
00415 *originalDirectionCosines = imageReader->GetOutput()->GetDirection();
00416 }
00417
00418 }
00419
00420 return imageContainer;
00421
00422 }
00423
00424 MultipleImageLoader(){};
00425 ~MultipleImageLoader(){};
00426
00427 };
00428
00429 private:
00430
00431 ElastixBase( const Self& );
00432 void operator=( const Self& );
00433
00434 xl::xoutrow_type m_IterationInfo;
00435
00436 int m_DefaultOutputPrecision;
00437
00441 ObjectContainerPointer m_FixedImagePyramidContainer;
00442 ObjectContainerPointer m_MovingImagePyramidContainer;
00443 ObjectContainerPointer m_InterpolatorContainer;
00444 ObjectContainerPointer m_ImageSamplerContainer;
00445 ObjectContainerPointer m_MetricContainer;
00446 ObjectContainerPointer m_OptimizerContainer;
00447 ObjectContainerPointer m_RegistrationContainer;
00448 ObjectContainerPointer m_ResamplerContainer;
00449 ObjectContainerPointer m_ResampleInterpolatorContainer;
00450 ObjectContainerPointer m_TransformContainer;
00451
00453 DataObjectContainerPointer m_FixedImageContainer;
00454 DataObjectContainerPointer m_MovingImageContainer;
00455 DataObjectContainerPointer m_FixedMaskContainer;
00456 DataObjectContainerPointer m_MovingMaskContainer;
00457
00459 FileNameContainerPointer m_FixedImageFileNameContainer;
00460 FileNameContainerPointer m_MovingImageFileNameContainer;
00461 FileNameContainerPointer m_FixedMaskFileNameContainer;
00462 FileNameContainerPointer m_MovingMaskFileNameContainer;
00463
00465 ObjectPointer m_InitialTransform;
00466 ObjectPointer m_FinalTransform;
00467
00469 bool m_UseDirectionCosines;
00470
00478 FileNameContainerPointer GenerateFileNameContainer(
00479 const std::string & optionkey,
00480 int & errorcode,
00481 bool printerrors,
00482 bool printinfo ) const;
00483
00484 };
00485
00486
00487 }
00488
00489 #undef elxGetObjectMacro
00490 #undef elxSetObjectMacro
00491 #undef elxGetNumberOfMacro
00492
00493 #endif // end #ifndef __elxElastixBase_h
00494