ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkFEMFiniteDifferenceFunctionLoad.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkFEMFiniteDifferenceFunctionLoad_h
00019 #define __itkFEMFiniteDifferenceFunctionLoad_h
00020 
00021 #include "itkFEMLoadElementBase.h"
00022 
00023 #include "itkFEMObject.h"
00024 #include "itkImage.h"
00025 #include "itkTranslationTransform.h"
00026 
00027 #include "itkImageRegionIteratorWithIndex.h"
00028 #include "itkNeighborhoodIterator.h"
00029 #include "itkNeighborhoodIterator.h"
00030 #include "itkNeighborhoodInnerProduct.h"
00031 #include "itkDerivativeOperator.h"
00032 #include "itkForwardDifferenceOperator.h"
00033 #include "itkLinearInterpolateImageFunction.h"
00034 #include "vnl/vnl_math.h"
00035 
00036 #include "itkDemonsRegistrationFunction.h"
00037 #include "itkMeanSquareRegistrationFunction.h"
00038 #include "itkNCCRegistrationFunction.h"
00039 #include "itkMIRegistrationFunction.h"
00040 
00041 namespace itk
00042 {
00043 namespace fem
00044 {
00045 
00066 template <class TMoving, class TFixed>
00067 class ITK_EXPORT FiniteDifferenceFunctionLoad : public LoadElement
00068 {
00069 public:
00070 
00072   typedef FiniteDifferenceFunctionLoad Self;
00073   typedef LoadElement                  Superclass;
00074   typedef SmartPointer<Self>           Pointer;
00075   typedef SmartPointer<const Self>     ConstPointer;
00076 
00078   itkSimpleNewMacro(Self);
00079 
00081   itkTypeMacro(FiniteDifferenceFunctionLoad, LoadElement);
00082 
00083 
00086   virtual::itk::LightObject::Pointer CreateAnother(void) const;
00087 
00088   // Necessary typedefs for dealing with images BEGIN
00089   typedef typename LoadElement::Float Float;
00090 
00091   typedef TMoving                                MovingImageType;
00092   typedef typename MovingImageType::ConstPointer MovingConstPointer;
00093   typedef MovingImageType *                      MovingPointer;
00094   typedef TFixed                                 FixedImageType;
00095   typedef FixedImageType *                       FixedPointer;
00096   typedef typename FixedImageType::ConstPointer  FixedConstPointer;
00097 
00099   itkStaticConstMacro(ImageDimension, unsigned int,
00100                       MovingImageType::ImageDimension);
00101 
00102   typedef ImageRegionIteratorWithIndex<MovingImageType> MovingRegionIteratorType;
00103   typedef ImageRegionIteratorWithIndex<FixedImageType>  FixedRegionIteratorType;
00104 
00105   typedef NeighborhoodIterator<MovingImageType>
00106   MovingNeighborhoodIteratorType;
00107   typedef typename MovingNeighborhoodIteratorType::IndexType
00108   MovingNeighborhoodIndexType;
00109   typedef typename MovingNeighborhoodIteratorType::RadiusType
00110   MovingRadiusType;
00111   typedef typename MovingNeighborhoodIteratorType::RadiusType
00112   RadiusType;
00113   typedef NeighborhoodIterator<FixedImageType>
00114   FixedNeighborhoodIteratorType;
00115   typedef typename FixedNeighborhoodIteratorType::IndexType
00116   FixedNeighborhoodIndexType;
00117   typedef typename FixedNeighborhoodIteratorType::RadiusType
00118   FixedRadiusType;
00119 
00120   // Typedefs for Image Data
00121   typedef   typename  MovingImageType::PixelType MovingPixelType;
00122   typedef   typename  FixedImageType::PixelType  FixedPixelType;
00123   typedef   Float                                PixelType;
00124   typedef   Float                                ComputationType;
00125   typedef   Image<PixelType, itkGetStaticConstMacro(ImageDimension)>
00126   ImageType;
00127   typedef   itk::Vector<float, itkGetStaticConstMacro(ImageDimension)>
00128   VectorType;
00129   typedef   vnl_vector<Float> FEMVectorType;
00130   typedef   Image<VectorType, itkGetStaticConstMacro(ImageDimension)>
00131   DisplacementFieldType;
00132   typedef   typename DisplacementFieldType::Pointer DisplacementFieldTypePointer;
00133 
00134   typedef NeighborhoodIterator<DisplacementFieldType>
00135   FieldIteratorType;
00136 
00137 
00139   typedef PDEDeformableRegistrationFunction<FixedImageType, MovingImageType,
00140                                             DisplacementFieldType>
00141   FiniteDifferenceFunctionType;
00142   typedef typename FiniteDifferenceFunctionType::Pointer FiniteDifferenceFunctionTypePointer;
00143 
00144   typedef typename FiniteDifferenceFunctionType::TimeStepType TimeStepType;
00145 
00146   typedef MeanSquareRegistrationFunction<FixedImageType, MovingImageType,
00147                                          DisplacementFieldType>  MeanSquareRegistrationFunctionType;
00148 
00149   typedef DemonsRegistrationFunction<FixedImageType, MovingImageType,
00150                                      DisplacementFieldType>  DemonsRegistrationFunctionType;
00151 
00152   typedef NCCRegistrationFunction<FixedImageType, MovingImageType,
00153                                   DisplacementFieldType>  NCCRegistrationFunctionType;
00154 
00155   typedef MIRegistrationFunction<FixedImageType, MovingImageType,
00156                                  DisplacementFieldType>  MIRegistrationFunctionType;
00157 
00158   typedef unsigned long                                        ElementIdentifier;
00159   typedef VectorContainer<ElementIdentifier, Element::Pointer> ElementContainerType;
00160 
00161 
00162   /* This method sets the pointer to a FiniteDifferenceFunction object that
00163    * will be used by the filter to calculate updates at image pixels.
00164    * \returns A FiniteDifferenceObject pointer. */
00165   void SetDifferenceFunction( FiniteDifferenceFunctionTypePointer drfp)
00166   {
00167     drfp->SetFixedImage(m_FixedImage);
00168     drfp->SetMovingImage(m_MovingImage);
00169     drfp->SetRadius(m_MetricRadius);
00170     drfp->SetDisplacementField(m_DisplacementField);
00171     drfp->InitializeIteration();
00172     this->m_DifferenceFunction = drfp;
00173   }
00174 
00175   void SetMetric( FiniteDifferenceFunctionTypePointer drfp )
00176   {
00177     this->SetDifferenceFunction( static_cast<FiniteDifferenceFunctionType *>(
00178                                    drfp.GetPointer() ) );
00179 
00180     m_FixedSize = m_DisplacementField->GetLargestPossibleRegion().GetSize();
00181   }
00182 
00184   void SetMovingImage(MovingImageType* R)
00185   {
00186     m_MovingImage = R;
00187     m_MovingSize = m_MovingImage->GetLargestPossibleRegion().GetSize();
00188     if( this->m_DifferenceFunction )
00189       {
00190       this->m_DifferenceFunction->SetMovingImage(m_MovingImage);
00191       }
00192   }
00194 
00196   void SetFixedImage(FixedImageType* T)
00197   {
00198     m_FixedImage = T;
00199     m_FixedSize = T->GetLargestPossibleRegion().GetSize();
00200     if( this->m_DifferenceFunction )
00201       {
00202       this->m_DifferenceFunction->SetFixedImage(m_MovingImage);
00203       }
00204   }
00206 
00207   MovingPointer GetMovingImage()
00208   {
00209     return m_MovingImage;
00210   }
00211 
00212   FixedPointer GetFixedImage()
00213   {
00214     return m_FixedImage;
00215   }
00216 
00218   void SetMetricRadius(MovingRadiusType T)
00219   {
00220     m_MetricRadius  = T;
00221   }
00222 
00224   MovingRadiusType GetMetricRadius()
00225   {
00226     return m_MetricRadius;
00227   }
00228 
00233   void SetNumberOfIntegrationPoints(unsigned int i)
00234   {
00235     m_NumberOfIntegrationPoints = i;
00236   }
00237 
00238   unsigned int GetNumberOfIntegrationPoints()
00239   {
00240     return m_NumberOfIntegrationPoints;
00241   }
00242 
00246   void SetDescentDirectionMinimize( )
00247   {
00248     m_Sign = 1.0;
00249   }
00250 
00251   void SetDescentDirectionMaximize()
00252   {
00253     m_Sign = -1.0;
00254   }
00255 
00256   void IsDirectionMaximize()
00257   {
00258     if (m_Sign == -1.0)
00259     {
00260       return true;
00261     }
00262     else
00263     {
00264       return false;
00265     }
00266   }
00267 
00268   void IsDirectionMinimize()
00269   {
00270     if (m_Sign == 1.0)
00271     {
00272       return true;
00273     }
00274     else
00275     {
00276       return false;
00277     }
00278   }
00279 
00280 
00282   void SetGamma(Float s)
00283   {
00284     m_Gamma = s;
00285   }
00286 
00287   void SetSolution(Solution::ConstPointer ptr)
00288   {
00289     m_Solution = ptr;
00290   }
00291 
00292   Solution::ConstPointer GetSolution()
00293   {
00294     return m_Solution;
00295   }
00296 
00297   // FIXME - WE ASSUME THE 2ND VECTOR (INDEX 1) HAS THE INFORMATION WE WANT
00298   Float GetSolution(unsigned int i, unsigned int which = 0)
00299   {
00300     return m_Solution->GetSolutionValue(i, which);
00301   }
00302 
00303   Float EvaluateMetricGivenSolution( ElementContainerType *el, Float step = 1.0);
00304 
00305 
00309   FEMVectorType Fe(FEMVectorType);
00310 
00312   void SetDisplacementField( DisplacementFieldTypePointer df)
00313   {
00314     m_DisplacementField = df;
00315   }
00316 
00318   DisplacementFieldTypePointer GetDisplacementField()
00319   {
00320     return m_DisplacementField;
00321   }
00322 
00323   void InitializeIteration();
00324 
00325   void InitializeMetric();
00326 
00327   void PrintCurrentEnergy();
00328 
00329   double GetCurrentEnergy();
00330 
00331   void  SetCurrentEnergy( double e = 0.0);
00332 
00333   virtual void ApplyLoad(Element::ConstPointer element, Element::VectorType & Fe);
00334 
00335 protected:
00336 private:
00337   FiniteDifferenceFunctionLoad(); // cannot be private until we always use smart pointers
00338 
00339   MovingPointer    m_MovingImage;
00340   FixedPointer     m_FixedImage;
00343   typename MovingImageType::SizeType  m_MovingSize;
00344   typename FixedImageType::SizeType   m_FixedSize;
00345   unsigned int                        m_NumberOfIntegrationPoints;
00346   unsigned int                        m_SolutionIndex;
00347   unsigned int                        m_SolutionIndex2;
00348   Float                               m_Gamma;
00349   typename Solution::ConstPointer     m_Solution;
00350   float                               m_GradSigma;
00351   float                               m_Sign;
00352   float                               m_WhichMetric;
00353   FiniteDifferenceFunctionTypePointer m_DifferenceFunction;
00354 
00355   typename DisplacementFieldType::Pointer             m_DisplacementField;
00356 
00357 };
00358 
00359 }
00360 } // end namespace fem/itk
00361 
00362 #ifndef ITK_MANUAL_INSTANTIATION
00363 #include "itkFEMFiniteDifferenceFunctionLoad.hxx"
00364 #endif
00365 
00366 #endif
00367