Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

itkOptBSplineInterpolateImageFunction.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Insight Segmentation & Registration Toolkit
00004   Module:    $RCSfile: itkOptBSplineInterpolateImageFunction.h,v $
00005   Language:  C++
00006   Date:      $Date: 2009-02-07 16:05:47 $
00007   Version:   $Revision: 1.10 $
00008 
00009   Copyright (c) Insight Software Consortium. All rights reserved.
00010   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012   Portions of this code are covered under the VTK copyright.
00013   See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
00014 
00015      This software is distributed WITHOUT ANY WARRANTY; without even
00016      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00017      PURPOSE.  See the above copyright notices for more information.
00018 
00019 =========================================================================*/
00020 #ifndef __itkOptBSplineInterpolateImageFunction_h
00021 #define __itkOptBSplineInterpolateImageFunction_h
00022 
00023 #include <vector>
00024 
00025 #include "itkImageLinearIteratorWithIndex.h"
00026 #include "itkInterpolateImageFunction.h"
00027 #include "vnl/vnl_matrix.h"
00028 
00029 #include "itkBSplineDecompositionImageFilter.h"
00030 #include "itkConceptChecking.h"
00031 #include "itkCovariantVector.h"
00032 
00033 namespace itk
00034 {
00068 template <
00069   class TImageType,
00070   class TCoordRep = double,
00071   class TCoefficientType = double >
00072 class ITK_EXPORT BSplineInterpolateImageFunction :
00073     public InterpolateImageFunction<TImageType,TCoordRep>
00074 {
00075 public:
00077   typedef BSplineInterpolateImageFunction                   Self;
00078   typedef InterpolateImageFunction<TImageType,TCoordRep>    Superclass;
00079   typedef SmartPointer<Self>                                Pointer;
00080   typedef SmartPointer<const Self>                          ConstPointer;
00081 
00083   itkTypeMacro(BSplineInterpolateImageFunction, InterpolateImageFunction);
00084 
00085 
00087   itkNewMacro( Self );
00088 
00090   typedef typename Superclass::OutputType OutputType;
00091 
00093   typedef typename Superclass::InputImageType InputImageType;
00094 
00096   itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension);
00097 
00099   typedef typename Superclass::IndexType IndexType;
00100 
00102   typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
00103 
00105   typedef typename Superclass::PointType PointType;
00106 
00108   typedef ImageLinearIteratorWithIndex<TImageType> Iterator;
00109 
00111   typedef TCoefficientType CoefficientDataType;
00112   typedef Image<CoefficientDataType,
00113                      itkGetStaticConstMacro(ImageDimension) >
00114                                                            CoefficientImageType;
00115 
00117   typedef BSplineDecompositionImageFilter<TImageType,
00118                                                CoefficientImageType>
00119                                                               CoefficientFilter;
00120   typedef typename CoefficientFilter::Pointer CoefficientFilterPointer;
00121 
00123   typedef CovariantVector<OutputType,
00124                           itkGetStaticConstMacro(ImageDimension) >
00125                                                             CovariantVectorType;
00126 
00127 
00136   virtual OutputType Evaluate( const PointType & point ) const
00137     {
00138     ContinuousIndexType index;
00139     this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point,
00140                                                                     index );
00141     // No thread info passed in, so call method that doesn't need thread ID.
00142     return ( this->EvaluateAtContinuousIndex( index ) );
00143     }
00145 
00146   virtual OutputType Evaluate( const PointType & point,
00147                                unsigned int threadID ) const
00148     {
00149     ContinuousIndexType index;
00150     this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point,
00151                                                                     index );
00152     return ( this->EvaluateAtContinuousIndex( index, threadID ) );
00153     }
00154 
00155   virtual OutputType EvaluateAtContinuousIndex( const ContinuousIndexType &
00156                                                                  index ) const
00157     {
00158     // Don't know thread information, make evaluateIndex, weights on the stack.
00159     // Slower, but safer.
00160     vnl_matrix<long>        evaluateIndex(ImageDimension, ( m_SplineOrder + 1 ));
00161     vnl_matrix<double>      weights(ImageDimension, ( m_SplineOrder + 1 ));
00162 
00163     // Pass evaluateIndex, weights by reference. They're only good as long
00164     // as this method is in scope.
00165     return this->EvaluateAtContinuousIndexInternal( index,
00166                                                     evaluateIndex,
00167                                                     weights);
00168     }
00169 
00170   virtual OutputType EvaluateAtContinuousIndex( const ContinuousIndexType &
00171                                                                         index,
00172                                                 unsigned int threadID ) const;
00173 
00174   CovariantVectorType EvaluateDerivative( const PointType & point ) const
00175     {
00176     ContinuousIndexType index;
00177     this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point,
00178                                                                     index );
00179     // No thread info passed in, so call method that doesn't need thread ID.
00180     return ( this->EvaluateDerivativeAtContinuousIndex( index ) );
00181     }
00182 
00183   CovariantVectorType EvaluateDerivative( const PointType & point,
00184                                           unsigned int threadID ) const
00185     {
00186     ContinuousIndexType index;
00187     this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point,
00188                                                                     index );
00189     return ( this->EvaluateDerivativeAtContinuousIndex( index, threadID ) );
00190     }
00191 
00192   CovariantVectorType EvaluateDerivativeAtContinuousIndex(
00193                                          const ContinuousIndexType & x ) const
00194     {
00195     // Don't know thread information, make evaluateIndex, weights, weightsDerivative
00196     // on the stack.
00197     // Slower, but safer.
00198     vnl_matrix<long>          evaluateIndex(ImageDimension, ( m_SplineOrder + 1 ));
00199     vnl_matrix<double>        weights(ImageDimension, ( m_SplineOrder + 1 ));
00200     vnl_matrix<double>        weightsDerivative(ImageDimension, ( m_SplineOrder + 1));
00201 
00202     // Pass evaluateIndex, weights, weightsDerivative by reference. They're only good
00203     // as long as this method is in scope.
00204     return this->EvaluateDerivativeAtContinuousIndexInternal( x,
00205                                                               evaluateIndex,
00206                                                               weights,
00207                                                               weightsDerivative );
00208     }
00209 
00210   CovariantVectorType EvaluateDerivativeAtContinuousIndex(
00211                                          const ContinuousIndexType & x,
00212                                          unsigned int threadID ) const;
00213 
00214   void EvaluateValueAndDerivative( const PointType & point,
00215                                    OutputType & value,
00216                                    CovariantVectorType & deriv ) const
00217     {
00218     ContinuousIndexType index;
00219     this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point,
00220                                                                     index );
00221 
00222     // No thread info passed in, so call method that doesn't need thread ID.
00223     this->EvaluateValueAndDerivativeAtContinuousIndex( index,
00224                                                        value,
00225                                                        deriv );
00226     }
00227 
00228   void EvaluateValueAndDerivative( const PointType & point,
00229                                    OutputType & value,
00230                                    CovariantVectorType & deriv,
00231                                    unsigned int threadID ) const
00232     {
00233     ContinuousIndexType index;
00234     this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point,
00235                                                                     index );
00236     this->EvaluateValueAndDerivativeAtContinuousIndex( index,
00237                                                        value,
00238                                                        deriv,
00239                                                        threadID );
00240     }
00241 
00242   void EvaluateValueAndDerivativeAtContinuousIndex(
00243                                                 const ContinuousIndexType & x,
00244                                                 OutputType & value,
00245                                                 CovariantVectorType & deriv
00246                                                 ) const
00247     {
00248     // Don't know thread information, make evaluateIndex, weights, weightsDerivative
00249     // on the stack.
00250     // Slower, but safer.
00251     vnl_matrix<long>          evaluateIndex(ImageDimension, ( m_SplineOrder + 1 ));
00252     vnl_matrix<double>        weights(ImageDimension, ( m_SplineOrder + 1 ));
00253     vnl_matrix<double>        weightsDerivative(ImageDimension, ( m_SplineOrder + 1));
00254 
00255     // Pass evaluateIndex, weights, weightsDerivative by reference. They're only good
00256     // as long as this method is in scope.
00257     this->EvaluateValueAndDerivativeAtContinuousIndexInternal(x,
00258                                                               value,
00259                                                               deriv,
00260                                                               evaluateIndex,
00261                                                               weights,
00262                                                               weightsDerivative );
00263     }
00264 
00265   void EvaluateValueAndDerivativeAtContinuousIndex(
00266                                                 const ContinuousIndexType & x,
00267                                                 OutputType & value,
00268                                                 CovariantVectorType & deriv,
00269                                                 unsigned int threadID ) const;
00270 
00271 
00274   void SetSplineOrder(unsigned int SplineOrder);
00275   itkGetConstMacro(SplineOrder, int);
00277 
00278   void SetNumberOfThreads(unsigned int numThreads);
00279   itkGetMacro(NumberOfThreads, int);
00280 
00282   virtual void SetInputImage(const TImageType * inputData);
00283 
00284 
00297   itkSetMacro( UseImageDirection, bool );
00298   itkGetMacro( UseImageDirection, bool );
00299   itkBooleanMacro( UseImageDirection );
00301 
00302 
00303 protected:
00304 
00323   virtual OutputType EvaluateAtContinuousIndexInternal( const ContinuousIndexType & index,
00324                                                         vnl_matrix<long>& evaluateIndex,
00325                                                         vnl_matrix<double>& weights) const;
00326 
00327   virtual void EvaluateValueAndDerivativeAtContinuousIndexInternal( const ContinuousIndexType & x,
00328                                                        OutputType & value,
00329                                                        CovariantVectorType & derivativeValue,
00330                                                        vnl_matrix<long>& evaluateIndex,
00331                                                        vnl_matrix<double>& weights,
00332                                                        vnl_matrix<double>& weightsDerivative
00333                                                        ) const;
00334 
00335   virtual CovariantVectorType EvaluateDerivativeAtContinuousIndexInternal( const ContinuousIndexType & x,
00336                                                                            vnl_matrix<long>& evaluateIndex,
00337                                                                            vnl_matrix<double>& weights,
00338                                                                            vnl_matrix<double>& weightsDerivative
00339                                                                            ) const;
00340 
00341 
00342   BSplineInterpolateImageFunction();
00343   ~BSplineInterpolateImageFunction();
00344   void PrintSelf(std::ostream& os, Indent indent) const;
00345 
00346   // These are needed by the smoothing spline routine.
00347   // temp storage for processing of Coefficients
00348   std::vector<CoefficientDataType>    m_Scratch;
00349   // Image size
00350   typename TImageType::SizeType       m_DataLength;
00351   // User specified spline order (3rd or cubic is the default)
00352   unsigned int                        m_SplineOrder;
00353 
00354   // Spline coefficients
00355   typename CoefficientImageType::ConstPointer       m_Coefficients;
00356 
00357 private:
00358   BSplineInterpolateImageFunction( const Self& ); //purposely not implemented
00359   void operator=( const Self& ); //purposely not implemented
00360 
00362   void SetInterpolationWeights( const ContinuousIndexType & x,
00363                                 const vnl_matrix<long> & EvaluateIndex,
00364                                 vnl_matrix<double> & weights,
00365                                 unsigned int splineOrder ) const;
00366 
00368   void SetDerivativeWeights( const ContinuousIndexType & x,
00369                              const vnl_matrix<long> & EvaluateIndex,
00370                              vnl_matrix<double> & weights,
00371                              unsigned int splineOrder ) const;
00372 
00375   void GeneratePointsToIndex(  );
00376 
00378   void DetermineRegionOfSupport( vnl_matrix<long> & evaluateIndex,
00379                                  const ContinuousIndexType & x,
00380                                  unsigned int splineOrder ) const;
00381 
00384   void ApplyMirrorBoundaryConditions(vnl_matrix<long> & evaluateIndex,
00385                                      unsigned int splineOrder) const;
00386 
00387 
00388   Iterator                  m_CIterator;    // Iterator for traversing spline coefficients.
00389   unsigned long             m_MaxNumberInterpolationPoints; // number of neighborhood points used for interpolation
00390   std::vector<IndexType>    m_PointsToIndex;  // Preallocation of interpolation neighborhood indicies
00391 
00392   CoefficientFilterPointer     m_CoefficientFilter;
00393 
00394   // flag to take or not the image direction into account when computing the
00395   // derivatives.
00396   bool m_UseImageDirection;
00397 
00398   unsigned int         m_NumberOfThreads;
00399   vnl_matrix<long>   * m_ThreadedEvaluateIndex;
00400   vnl_matrix<double> * m_ThreadedWeights;
00401   vnl_matrix<double> * m_ThreadedWeightsDerivative;
00402 };
00403 
00404 } // namespace itk
00405 
00406 #ifndef ITK_MANUAL_INSTANTIATION
00407 #include "itkOptBSplineInterpolateImageFunction.txx"
00408 #endif
00409 
00410 #endif
00411 

Generated at Sat Feb 28 13:11:14 2009 for ITK by doxygen 1.5.6 written by Dimitri van Heesch, © 1997-2000