00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _itkFEMRegistrationFilter_h_
00019 #define _itkFEMRegistrationFilter_h_
00020
00021 #include "itkFEMLinearSystemWrapperItpack.h"
00022 #include "itkFEMLinearSystemWrapperDenseVNL.h"
00023 #include "itkFEMGenerateMesh.h"
00024 #include "itkFEMSolverCrankNicolson.h"
00025 #include "itkFEMMaterialLinearElasticity.h"
00026 #include "itkFEMImageMetricLoad.h"
00027
00028 #include "itkImage.h"
00029 #include "itkVector.h"
00030 #include "itkImageRegionIteratorWithIndex.h"
00031 #include "itkVectorCastImageFilter.h"
00032 #include "itkVectorIndexSelectionCastImageFilter.h"
00033 #include "itkWarpImageFilter.h"
00034 #include "itkImageToImageMetric.h"
00035 #include "itkTranslationTransform.h"
00036
00037
00038 #include "vnl/vnl_vector.h"
00039 #include "vnl/vnl_math.h"
00040 #include "vnl/vnl_vector_fixed.h"
00041
00042
00043 #include <iostream>
00044 #include <string>
00045
00046
00047
00048 namespace itk {
00049 namespace fem {
00050
00097 template<class TReference,class TTarget>
00098 class ITK_EXPORT FEMRegistrationFilter : public ImageToImageFilter<TReference, TTarget>
00099 {
00100 public:
00101 typedef FEMRegistrationFilter Self;
00102 typedef ImageToImageFilter<TReference, TTarget> Superclass;
00103 typedef SmartPointer<Self> Pointer;
00104 typedef SmartPointer<const Self> ConstPointer;
00105
00107 itkNewMacro(Self);
00108
00110 itkTypeMacro(FEMRegistrationFilter, ImageToImageFilter );
00111
00112 typedef TReference ImageType;
00113 typedef TTarget TargetImageType;
00114 typedef typename ImageType::PixelType ImageDataType;
00115 typedef typename ImageType::PixelType PixelType;
00116 typedef typename ImageType::SizeType ImageSizeType;
00117
00119 itkStaticConstMacro(ImageDimension, unsigned int,
00120 ImageType::ImageDimension);
00121
00122 typedef Image< float, itkGetStaticConstMacro(ImageDimension) > FloatImageType;
00123 typedef LinearSystemWrapperItpack LinearSystemSolverType;
00124 typedef SolverCrankNicolson SolverType;
00125 enum Sign { positive = 1, negative = -1 };
00126 typedef double Float;
00127
00128
00129 typedef MaterialLinearElasticity MaterialType;
00130 typedef ImageToImageMetric<ImageType,TargetImageType> MetricBaseType;
00131 typedef typename MetricBaseType::Pointer MetricBaseTypePointer;
00132 typedef itk::Vector<float,itkGetStaticConstMacro(ImageDimension)> VectorType;
00133 typedef itk::Image<VectorType,itkGetStaticConstMacro(ImageDimension)> FieldType;
00134 typedef itk::WarpImageFilter<ImageType,ImageType, FieldType> WarperType;
00135 typedef itk::ImageRegionIteratorWithIndex<ImageType> ImageIterator;
00136 typedef itk::ImageRegionIteratorWithIndex<FieldType> FieldIterator;
00137 typedef itk::VectorIndexSelectionCastImageFilter<FieldType,FloatImageType> IndexSelectCasterType;
00138
00140 typedef ImageMetricLoad<ImageType,ImageType> ImageMetricLoadType;
00141
00146 class FEMOF : public FEMObjectFactory<FEMLightObject>{};
00147
00148
00149
00151 bool ReadConfigFile(const char*);
00152
00154 void RunRegistration();
00155
00159 void WriteWarpedImage(const char* fn);
00160
00161
00165 void CreateMesh(double ElementsPerSide, Solver& S);
00166
00168 void ApplyLoads(SolverType& S,ImageSizeType Isz);
00169
00172 void CreateLinearSystemSolver();
00173
00175 void IterativeSolve(SolverType& S);
00176
00178 void MultiResSolve();
00179
00181 Float EvaluateEnergy();
00182
00187 void GetVectorField(SolverType& S);
00188
00191 FloatImageType* GetMetricImage(FieldType* F);
00192
00194 void SampleVectorFieldAtNodes(SolverType& S);
00195
00197 void WarpImage(ImageType* R);
00198
00200 int WriteDisplacementField(unsigned int index);
00201
00203 void SetReferenceFile(const char* r) {m_ReferenceFileName=r;}
00204
00205 std::string GetReferenceFile() {return m_ReferenceFileName;}
00206
00207 void SetTargetFile(const char* t) {m_TargetFileName=t;}
00208
00209 std::string GetTargetFile() {return m_TargetFileName;}
00210
00211
00215 void SetReferenceImage(ImageType* R);
00216
00218 void SetTargetImage(TargetImageType* T);
00219
00220 ImageType* GetReferenceImage(){return m_RefImg;}
00221
00222 TargetImageType* GetTargetImage(){return m_TarImg;}
00223
00224
00227 ImageType* GetWarpedImage(){return m_WarpedImage;}
00228
00230 void ComputeJacobian();
00231
00233 FloatImageType* GetJacobianImage(){return m_FloatImage;}
00234
00235
00237 FieldType* GetDeformationField(){return m_Field;}
00239 void SetDeformationField(FieldType* F)
00240 {
00241 m_FieldSize=F->GetLargestPossibleRegion().GetSize();
00242 m_Field=F;
00243 }
00244
00247 void SetLandmarkFile(const char* l) {m_LandmarkFileName=l; }
00248
00250 void UseLandmarks(bool b) {m_UseLandmarks=b;}
00251
00256 void SetResultsFile(const char* r) {m_ResultsFileName=r;}
00257
00258 void SetResultsFileName (const char* f){m_ResultsFileName=f;}
00259
00260 std::string GetResultsFileName () {return m_ResultsFileName;}
00261
00263 void SetDisplacementsFile(const char* r) {m_DisplacementsFileName=r;}
00264
00271 void SetMeshPixelsPerElementAtEachResolution(unsigned int i,unsigned int which=0){ m_MeshPixelsPerElementAtEachResolution[which]=i;}
00272
00276 void SetNumberOfIntegrationPoints(unsigned int i,unsigned int which=0){ m_NumberOfIntegrationPoints[which]=i;}
00277
00283 void SetWidthOfMetricRegion(unsigned int i,unsigned int which=0) { m_MetricWidth[which]=i;}
00284 unsigned int GetWidthOfMetricRegion(unsigned int which=0) { return m_MetricWidth[which];}
00285
00290 void SetMaximumIterations(unsigned int i,unsigned int which) { m_Maxiters[which]=i;}
00291
00294 void SetTimeStep(Float i) { m_dT=i;}
00295
00297 void SetAlpha(Float a) { m_Alpha=a;}
00298
00301 void SetEnergyReductionFactor(Float i) { m_EnergyReductionFactor=i;}
00302
00304 void SetElasticity(Float i,unsigned int which=0) { m_E[which]=i;}
00305
00307 Float GetElasticity(unsigned int which=0) { return m_E[which];}
00308
00310 void SetRho(Float r,unsigned int which=0) { m_Rho[which]=r;}
00311
00313 void SetGamma(Float r,unsigned int which=0) { m_Gamma[which]=r;}
00314
00316 void SetDescentDirectionMinimize() { m_DescentDirection=positive;}
00317
00319 void SetDescentDirectionMaximize() { m_DescentDirection=negative;}
00320
00322 void DoLineSearch(unsigned int b) { m_DoLineSearchOnImageEnergy=b; }
00323
00324
00326 void DoMultiRes(bool b) { m_DoMultiRes=b; }
00327
00329 void SetLineSearchMaximumIterations(unsigned int f) { m_LineSearchMaximumIterations=f; }
00330
00332 void SetWriteDisplacements(bool b) {m_WriteDisplacementField=b;}
00333
00335 bool GetWriteDisplacements() {return m_WriteDisplacementField;}
00336
00339 void SetConfigFileName (const char* f){m_ConfigFileName=f;}
00340
00341 std::string GetConfigFileName () {return m_ConfigFileName; }
00342
00343 ImageSizeType GetImageSize(){ return m_ImageSize; }
00344
00346 MetricBaseTypePointer GetMetric() { return m_Metric; }
00347 void SetMetric(MetricBaseTypePointer MP) { m_Metric=MP; }
00348
00351 void ChooseMetric( float whichmetric);
00352
00354 void SetElement(Element::Pointer e) {m_Element=e;}
00355
00357 void SetMaterial(MaterialType::Pointer m) {m_Material=m;}
00358
00359 void PrintVectorField();
00360
00361 Float EvaluateResidual(SolverType& mySolver,Float t);
00362
00363
00364 void FindBracketingTriplet(SolverType& mySolver,Float* a, Float* b, Float* c);
00365
00369 Float GoldenSection(SolverType& mySolver,Float tol=0.01,unsigned int MaxIters=25);
00370
00372
00373 itkGetMacro( Load, ImageMetricLoadType* );
00374
00376 FEMRegistrationFilter( );
00377 ~FEMRegistrationFilter();
00378
00379 protected :
00380
00381
00382 void PrintSelf(std::ostream& os, Indent indent) const
00383 {
00384 std::cout << "FEM registration filter "<< std::endl;
00385 Superclass::PrintSelf( os, indent );
00386 }
00387
00388 private :
00389
00390 FEMRegistrationFilter(const Self&);
00391 void operator=(const Self&);
00392
00393 std::string m_ConfigFileName;
00394 std::string m_ResultsFileName;
00395 std::string m_ReferenceFileName;
00396 std::string m_TargetFileName;
00397 std::string m_LandmarkFileName;
00398 std::string m_DisplacementsFileName;
00399 std::string m_MeshFileName;
00400
00401 unsigned int m_DoLineSearchOnImageEnergy;
00402 unsigned int m_LineSearchMaximumIterations;
00403
00404 vnl_vector<unsigned int> m_NumberOfIntegrationPoints;
00405 vnl_vector<unsigned int> m_MetricWidth;
00406 vnl_vector<unsigned int> m_Maxiters;
00407 unsigned int m_TotalIterations;
00408 unsigned int m_NumLevels;
00409 unsigned int m_MaxLevel;
00410 unsigned int m_MeshLevels;
00411 unsigned int m_MeshStep;
00412 unsigned int m_FileCount;
00413 unsigned int m_CurrentLevel;
00414 unsigned int m_WhichMetric;
00415
00418 vnl_vector<unsigned int> m_MeshPixelsPerElementAtEachResolution;
00419
00420 Float m_dT;
00421 vnl_vector<Float> m_E;
00422 vnl_vector<Float> m_Rho;
00423 vnl_vector<Float> m_Gamma;
00424 Float m_Energy;
00425 Float m_MinE;
00426 Float m_Alpha;
00428 Float m_EnergyReductionFactor;
00429 Float m_Temp;
00430
00431 bool m_WriteDisplacementField;
00432 bool m_DoMultiRes;
00433 bool m_UseLandmarks;
00434 bool m_ReadMeshFile;
00435 bool m_UseMassMatrix;
00436 Sign m_DescentDirection;
00437
00438 ImageSizeType m_ImageSize;
00439 ImageSizeType m_ImageOrigin;
00441 ImageSizeType m_ImageScaling;
00442 typename ImageType::RegionType m_FieldRegion;
00443 typename ImageType::SizeType m_FieldSize;
00444 typename FieldType::Pointer m_Field;
00445
00446 ImageMetricLoadType* m_Load;
00447
00448
00449 typename WarperType::Pointer m_Warper;
00450
00451
00452 typename ImageType::Pointer m_WarpedImage;
00453 typename FloatImageType::Pointer m_FloatImage;
00454 typename ImageType::RegionType m_Wregion;
00455 typename ImageType::IndexType m_Windex;
00456
00457
00458 typename ImageType::Pointer m_RefImg;
00459 typename ImageType::Pointer m_TarImg;
00460 typename ImageType::RegionType m_Rregion;
00461 typename ImageType::RegionType m_Tregion;
00462 typename ImageType::IndexType m_Rindex;
00463 typename ImageType::IndexType m_Tindex;
00464
00465
00466 typename Element::Pointer m_Element;
00467 typename MaterialType::Pointer m_Material;
00468 MetricBaseTypePointer m_Metric;
00469
00470
00471 };
00472
00473 }}
00474
00475 #ifndef ITK_MANUAL_INSTANTIATION
00476 #include "itkFEMRegistrationFilter.txx"
00477 #endif
00478
00479 #endif
00480