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

itkOptLinearInterpolateImageFunction.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Insight Segmentation & Registration Toolkit
00004   Module:    $RCSfile: itkOptLinearInterpolateImageFunction.h,v $
00005   Language:  C++
00006   Date:      $Date: 2009-10-29 11:19:19 $
00007   Version:   $Revision: 1.11 $
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      This software is distributed WITHOUT ANY WARRANTY; without even 
00013      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014      PURPOSE.  See the above copyright notices for more information.
00015 
00016 =========================================================================*/
00017 #ifndef __itkOptLinearInterpolateImageFunction_h
00018 #define __itkOptLinearInterpolateImageFunction_h
00019 
00020 #include "itkInterpolateImageFunction.h"
00021 
00022 namespace itk
00023 {
00024 
00042 template <class TInputImage, class TCoordRep = double>
00043 class ITK_EXPORT LinearInterpolateImageFunction : 
00044   public InterpolateImageFunction<TInputImage,TCoordRep> 
00045 {
00046 public:
00048   typedef LinearInterpolateImageFunction                    Self;
00049   typedef InterpolateImageFunction<TInputImage,TCoordRep>   Superclass;
00050   typedef SmartPointer<Self>                                Pointer;
00051   typedef SmartPointer<const Self>                          ConstPointer;
00052 
00054   itkTypeMacro(LinearInterpolateImageFunction, InterpolateImageFunction);
00055 
00057   itkNewMacro(Self);  
00058 
00060   typedef typename Superclass::OutputType OutputType;
00061 
00063   typedef typename Superclass::InputImageType InputImageType;
00064 
00066   typedef typename Superclass::InputPixelType InputPixelType;
00067 
00069   typedef typename Superclass::RealType RealType;
00070 
00072   itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension);
00073 
00075   typedef typename Superclass::IndexType       IndexType;
00076   typedef typename Superclass::IndexValueType  IndexValueType;
00077 
00079   typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
00080 
00089   virtual inline OutputType EvaluateAtContinuousIndex( const 
00090                                                          ContinuousIndexType &
00091                                                             index ) const
00092     {
00093     return this->EvaluateOptimized( Dispatch< ImageDimension >(), index );
00094     }
00095 
00096 protected:
00097   LinearInterpolateImageFunction();
00098   ~LinearInterpolateImageFunction();
00099   void PrintSelf(std::ostream& os, Indent indent) const;
00100 
00101 private:
00102   LinearInterpolateImageFunction( const Self& ); //purposely not implemented
00103   void operator=( const Self& ); //purposely not implemented
00104 
00106   static const unsigned long  m_Neighbors;  
00107 
00108   struct DispatchBase {};
00109   template< unsigned int > struct Dispatch : DispatchBase {};
00110 
00111   inline OutputType EvaluateOptimized( const Dispatch<0> &,
00112                                        const ContinuousIndexType & index) const
00113     {
00114     return 0;
00115     }
00116 
00117   inline OutputType EvaluateOptimized( const Dispatch<1>&,
00118                                        const ContinuousIndexType & index) const
00119     {
00120     IndexType basei;
00121 
00122     basei[0] = Math::Floor<IndexValueType>(index[0]);
00123     if( basei[0] < this->m_StartIndex[0] )
00124       {
00125       basei[0] = this->m_StartIndex[0];
00126       }
00127 
00128     const double distance = index[0] - static_cast<double>(basei[0]);
00129 
00130     const RealType val0 = this->GetInputImage()->GetPixel( basei );
00131 
00132     if(distance <= 0.)
00133       {
00134       return( static_cast<OutputType>( val0 ) );
00135       }
00136 
00137     ++basei[0];
00138     if(basei[0]>this->m_EndIndex[0])
00139       {
00140       return( static_cast<OutputType>( val0 ) );
00141       }
00142     const RealType val1 = this->GetInputImage()->GetPixel( basei );
00143 
00144     return( static_cast<OutputType>( val0 + ( val1 - val0 ) * distance ) );
00145     }
00146 
00147   inline OutputType EvaluateOptimized( const Dispatch<2>&,
00148                                        const ContinuousIndexType & index) const
00149     {
00150     IndexType basei;
00151 
00152     basei[0] = Math::Floor<IndexValueType>(index[0]);
00153     if( basei[0] < this->m_StartIndex[0] )
00154       {
00155       basei[0] = this->m_StartIndex[0];
00156       }
00157     const double distance0 = index[0] - static_cast<double>(basei[0]);
00158 
00159     basei[1] = Math::Floor<IndexValueType>(index[1]);
00160     if( basei[1] < this->m_StartIndex[1] )
00161       {
00162       basei[1] = this->m_StartIndex[1];
00163       }
00164     const double distance1 = index[1] - static_cast<double>(basei[1]);
00165 
00166 
00167     const RealType val00 = this->GetInputImage()->GetPixel( basei );
00168     if(distance0 <= 0. && distance1 <= 0.)
00169       {
00170       return( static_cast<OutputType>( val00 ) );
00171       }
00172     else if(distance1 <= 0.) // if they have the same "y"
00173       {
00174       ++basei[0];  // then interpolate across "x"
00175       if(basei[0]>this->m_EndIndex[0])
00176         {
00177         return( static_cast<OutputType>( val00 ) );
00178         }
00179       const RealType val10 = this->GetInputImage()->GetPixel( basei );
00180       return( static_cast<OutputType>(val00 + (val10 - val00) * distance0) );
00181       }
00182     else if(distance0 <= 0.) // if they have the same "x"
00183       {
00184       ++basei[1];  // then interpolate across "y"
00185       if(basei[1]>this->m_EndIndex[1])
00186         {
00187         return( static_cast<OutputType>( val00 ) );
00188         }
00189       const RealType val01 = this->GetInputImage()->GetPixel( basei );
00190       return( static_cast<OutputType>(val00 + (val01 - val00) * distance1) );
00191       }
00192     else // interpolate across "xy"
00193       {
00194       ++basei[0];
00195       if(basei[0]>this->m_EndIndex[0]) // interpolate across "y"
00196         {
00197         --basei[0];
00198         ++basei[1];
00199         if(basei[1]>this->m_EndIndex[1])
00200           {
00201           return( static_cast<OutputType>( val00 ) );
00202           }
00203         const RealType val01 = this->GetInputImage()->GetPixel( basei );
00204         return( static_cast<OutputType>(val00 + (val01 - val00) * distance1) );
00205         }
00206       const RealType val10 = this->GetInputImage()->GetPixel( basei );
00207 
00208       const RealType valx0 = val00 + (val10 - val00) * distance0;
00209       
00210       ++basei[1];
00211       if(basei[1]>this->m_EndIndex[1]) // interpolate across "x"
00212         {
00213         return( static_cast<OutputType>( valx0 ) );
00214         }
00215       const RealType val11 = this->GetInputImage()->GetPixel( basei );
00216       --basei[0];
00217       const RealType val01 = this->GetInputImage()->GetPixel( basei );
00218 
00219       const RealType valx1 = val01 + (val11 - val01) * distance0;
00220 
00221       return( static_cast<OutputType>( valx0 + (valx1-valx0) * distance1 ) );
00222       }
00223     }
00224 
00225   inline OutputType EvaluateOptimized( const Dispatch<3>&,
00226                                        const ContinuousIndexType & index) const
00227     {
00228     IndexType basei;
00229 
00230     basei[0] = Math::Floor<IndexValueType>(index[0]);
00231     if( basei[0] < this->m_StartIndex[0] )
00232       {
00233       basei[0] = this->m_StartIndex[0];
00234       }
00235     const double distance0 = index[0] - static_cast<double>(basei[0]);
00236  
00237     basei[1] = Math::Floor<IndexValueType>(index[1]);
00238     if( basei[1] < this->m_StartIndex[1] )
00239       {
00240       basei[1] = this->m_StartIndex[1];
00241       }
00242     const double distance1 = index[1] - static_cast<double>(basei[1]);
00243  
00244     basei[2] = Math::Floor<IndexValueType>(index[2]);
00245     if( basei[2] < this->m_StartIndex[2] )
00246       {
00247       basei[2] = this->m_StartIndex[2];
00248       }
00249     const double distance2 = index[2] - static_cast<double>(basei[2]);
00250 
00251     if(distance0<=0. && distance1<=0. && distance2<=0.)
00252       {
00253       return( static_cast<OutputType>( this->GetInputImage()->GetPixel( basei ) ) );
00254       }
00255 
00256 
00257     const RealType val000 = this->GetInputImage()->GetPixel( basei );
00258     
00259     if(distance2 <= 0.)
00260       {
00261       if(distance1 <= 0.) // interpolate across "x"
00262         {
00263         ++basei[0];
00264         if(basei[0]>this->m_EndIndex[0])
00265           {
00266           return( static_cast<OutputType>( val000 ) );
00267           }
00268         const RealType val100 = this->GetInputImage()->GetPixel( basei );
00269  
00270         return static_cast<OutputType>( val000 + (val100-val000) * distance0 );
00271         }
00272       else if(distance0 <= 0.) // interpolate across "y"
00273         {
00274         ++basei[1];
00275         if(basei[1]>this->m_EndIndex[1])
00276           {
00277           return( static_cast<OutputType>( val000 ) );
00278           }
00279         const RealType val010 = this->GetInputImage()->GetPixel( basei );
00280  
00281         return static_cast<OutputType>( val000 + (val010-val000) * distance1 );
00282         }
00283       else  // interpolate across "xy"
00284         {
00285         ++basei[0];
00286         if(basei[0]>this->m_EndIndex[0]) // interpolate across "y"
00287           {
00288           --basei[0];
00289           ++basei[1];
00290           if(basei[1]>this->m_EndIndex[1])
00291             {
00292             return( static_cast<OutputType>( val000 ) );
00293             }
00294           const RealType val010 = this->GetInputImage()->GetPixel( basei );
00295 
00296           return static_cast<OutputType>( val000 + (val010-val000) * distance1 );
00297           }
00298         const RealType val100 = this->GetInputImage()->GetPixel( basei );
00299 
00300         const RealType valx00 = val000 + (val100-val000) * distance0;
00301 
00302         ++basei[1];
00303         if(basei[1]>this->m_EndIndex[1]) // interpolate across "x"
00304           {
00305           return( static_cast<OutputType>( valx00 ) );
00306           }
00307         const RealType val110 = this->GetInputImage()->GetPixel( basei );
00308 
00309         --basei[0];
00310         const RealType val010 = this->GetInputImage()->GetPixel( basei );
00311 
00312         const RealType valx10 = val010 + (val110-val010) * distance0;
00313 
00314         return static_cast<OutputType>( valx00 + (valx10-valx00) * distance1 );
00315         }
00316       }
00317     else
00318       {
00319       if(distance1 <= 0.)
00320         {
00321         if(distance0 <= 0.) // interpolate across "z"
00322           {
00323           ++basei[2];
00324           if(basei[2]>this->m_EndIndex[2])
00325             {
00326             return( static_cast<OutputType>( val000 ) );
00327             }
00328           const RealType val001 = this->GetInputImage()->GetPixel( basei );
00329           
00330           return static_cast<OutputType>( val000 + (val001-val000) * distance2 );
00331           }
00332         else // interpolate across "xz"
00333           {
00334           ++basei[0];
00335           if(basei[0]>this->m_EndIndex[0]) // interpolate across "z"
00336             {
00337             --basei[0];
00338             ++basei[2];
00339             if(basei[2]>this->m_EndIndex[2])
00340               {
00341               return( static_cast<OutputType>( val000 ) );
00342               }
00343             const RealType val001 = this->GetInputImage()->GetPixel( basei );
00344 
00345             return static_cast<OutputType>( val000 + (val001-val000) * distance2 );
00346             }
00347           const RealType val100 = this->GetInputImage()->GetPixel( basei );
00348 
00349           const RealType valx00 = val000 + (val100-val000) * distance0;
00350 
00351           ++basei[2];
00352           if(basei[2]>this->m_EndIndex[2]) // interpolate across "x"
00353             {
00354             return( static_cast<OutputType>( valx00 ) );
00355             }
00356           const RealType val101 = this->GetInputImage()->GetPixel( basei );
00357 
00358           --basei[0];
00359           const RealType val001 = this->GetInputImage()->GetPixel( basei );
00360 
00361           const RealType valx01 = val001 + (val101-val001) * distance0;
00362 
00363           return static_cast<OutputType>( valx00 + (valx01-valx00) * distance2 );
00364           }
00365         }
00366       else if(distance0 <= 0.) // interpolate across "yz"
00367         {
00368         ++basei[1];
00369         if(basei[1]>this->m_EndIndex[1]) // interpolate across "z"
00370           {
00371           --basei[1];
00372           ++basei[2];
00373           if(basei[2]>this->m_EndIndex[2])
00374             {
00375             return( static_cast<OutputType>( val000 ) );
00376             }
00377           const RealType val001 = this->GetInputImage()->GetPixel( basei );
00378 
00379           return static_cast<OutputType>( val000 + (val001-val000) * distance2 );
00380           }
00381         const RealType val010 = this->GetInputImage()->GetPixel( basei );
00382 
00383         const RealType val0x0 = val000 + (val010-val000) * distance1;
00384 
00385         ++basei[2];
00386         if(basei[2]>this->m_EndIndex[2]) // interpolate across "y"
00387           {
00388           return( static_cast<OutputType>( val0x0 ) );
00389           }
00390         const RealType val011 = this->GetInputImage()->GetPixel( basei );
00391 
00392         --basei[1];
00393         const RealType val001 = this->GetInputImage()->GetPixel( basei );
00394 
00395         const RealType val0x1 = val001 + (val011-val001) * distance1;
00396 
00397         return static_cast<OutputType>( val0x0 + (val0x1-val0x0) * distance2 );
00398         }
00399       else // interpolate across "xyz"
00400         {
00401         ++basei[0];
00402         if(basei[0]>this->m_EndIndex[0]) // interpolate across "yz"
00403           {
00404           --basei[0];
00405           ++basei[1];
00406           if(basei[1]>this->m_EndIndex[1])  // interpolate across "z"
00407             {
00408             --basei[1];
00409             ++basei[2];
00410             if(basei[2]>this->m_EndIndex[2])
00411               {
00412               return( static_cast<OutputType>( val000 ) );
00413               }
00414             const RealType val001 = this->GetInputImage()->GetPixel( basei );
00415             
00416             return static_cast<OutputType>( val000 + (val001-val000) * distance2 );
00417             }
00418           const RealType val010 = this->GetInputImage()->GetPixel( basei );
00419 
00420           const RealType val0x0 = val000 + (val010-val000) * distance1;
00421 
00422           ++basei[2];
00423           if(basei[2]>this->m_EndIndex[2]) // interpolate across "y"
00424             {
00425             return( static_cast<OutputType>( val0x0 ) );
00426             }
00427           const RealType val011 = this->GetInputImage()->GetPixel( basei );
00428 
00429           --basei[1];
00430           const RealType val001 = this->GetInputImage()->GetPixel( basei );
00431 
00432           const RealType val0x1 = val001 + (val011-val001) * distance1;
00433 
00434           return static_cast<OutputType>( val0x0 + (val0x1-val0x0) * distance2 );
00435           }
00436         const RealType val100 = this->GetInputImage()->GetPixel( basei );
00437 
00438         const RealType valx00 = val000 + (val100-val000) * distance0;
00439 
00440         ++basei[1];
00441         if(basei[1]>this->m_EndIndex[1]) // interpolate across "xz"
00442           {
00443           --basei[1];
00444           ++basei[2];
00445           if(basei[2]>this->m_EndIndex[2]) // interpolate across "x"
00446             {
00447             return( static_cast<OutputType>( valx00 ) );
00448             }
00449           const RealType val101 = this->GetInputImage()->GetPixel( basei );
00450 
00451           --basei[0];
00452           const RealType val001 = this->GetInputImage()->GetPixel( basei );
00453 
00454           const RealType valx01 = val001 + (val101-val001) * distance0;
00455 
00456           return static_cast<OutputType>( valx00 + (valx01-valx00) * distance2 );
00457           }
00458         const RealType val110 = this->GetInputImage()->GetPixel( basei );
00459 
00460         --basei[0];
00461         const RealType val010 = this->GetInputImage()->GetPixel( basei );
00462 
00463         const RealType valx10 = val010 + (val110-val010) * distance0;
00464 
00465         const RealType valxx0 = valx00 + (valx10-valx00) * distance1;
00466 
00467         
00468         ++basei[2];
00469         if(basei[2]>this->m_EndIndex[2]) // interpolate across "xy"
00470           {
00471           return( static_cast<OutputType>( valxx0 ) );
00472           }
00473         const RealType val011 = this->GetInputImage()->GetPixel( basei );
00474 
00475         ++basei[0];
00476         const RealType val111 = this->GetInputImage()->GetPixel( basei );
00477 
00478         --basei[1];
00479         const RealType val101 = this->GetInputImage()->GetPixel( basei );
00480 
00481         --basei[0];
00482         const RealType val001 = this->GetInputImage()->GetPixel( basei );
00483 
00484         const RealType valx01 = val001 + (val101-val001) * distance0;
00485         const RealType valx11 = val011 + (val111-val011) * distance0;
00486         const RealType valxx1 = valx01 + (valx11-valx01) * distance1;
00487 
00488         return( static_cast<OutputType>( valxx0 + (valxx1-valxx0) * distance2 ) );
00489         }
00490       }
00491     }
00492 
00493   inline OutputType EvaluateOptimized( const DispatchBase &,
00494                                        const ContinuousIndexType & index) const
00495     {
00496     return this->EvaluateUnoptimized( index );
00497     }
00498                                        
00499   virtual inline OutputType EvaluateUnoptimized( 
00500                                        const ContinuousIndexType & index) const;
00501 };
00502 
00503 } // end namespace itk
00504 
00505 // Define instantiation macro for this template.
00506 #define ITK_TEMPLATE_LinearInterpolateImageFunction(_, EXPORT, x, y) namespace itk { \
00507   _(2(class EXPORT LinearInterpolateImageFunction< ITK_TEMPLATE_2 x >)) \
00508   namespace Templates { typedef LinearInterpolateImageFunction< ITK_TEMPLATE_2 x > \
00509                                                   LinearInterpolateImageFunction##y; } \
00510   }
00511 
00512 #if ITK_TEMPLATE_EXPLICIT
00513 # include "Templates/itkLinearInterpolateImageFunction+-.h"
00514 #endif
00515 
00516 #if ITK_TEMPLATE_TXX
00517 # include "itkOptLinearInterpolateImageFunction.txx"
00518 #endif
00519 
00520 #endif
00521 

Generated at Mon Jul 12 2010 19:21:28 for ITK by doxygen 1.7.1 written by Dimitri van Heesch, © 1997-2000