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-07-29 07:38:01 $
00007   Version:   $Revision: 1.7 $
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 
00078   typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
00079 
00088   virtual inline OutputType EvaluateAtContinuousIndex( const 
00089                                                          ContinuousIndexType &
00090                                                             index ) const
00091     {
00092     return this->EvaluateOptimized( Dispatch< ImageDimension >(), index );
00093     }
00094 
00095 protected:
00096   LinearInterpolateImageFunction();
00097   ~LinearInterpolateImageFunction();
00098   void PrintSelf(std::ostream& os, Indent indent) const;
00099 
00100 private:
00101   LinearInterpolateImageFunction( const Self& ); //purposely not implemented
00102   void operator=( const Self& ); //purposely not implemented
00103 
00105   static const unsigned long  m_Neighbors;  
00106 
00107   struct DispatchBase {};
00108   template< unsigned int > struct Dispatch : DispatchBase {};
00109 
00110   inline OutputType EvaluateOptimized( const Dispatch<0> &,
00111                                        const ContinuousIndexType & index) const
00112     {
00113     return 0;
00114     }
00115 
00116   inline OutputType EvaluateOptimized( const Dispatch<1>&,
00117                                        const ContinuousIndexType & index) const
00118     {
00119     IndexType basei;
00120 
00121     basei[0] = Math::Floor(index[0]);
00122     if( basei[0] < this->m_StartIndex[0] )
00123       {
00124       basei[0] = this->m_StartIndex[0];
00125       }
00126 
00127     const double distance = index[0] - static_cast<double>(basei[0]);
00128 
00129     const RealType val0 = this->GetInputImage()->GetPixel( basei );
00130 
00131     if(distance <= 0.)
00132       {
00133       return( static_cast<OutputType>( val0 ) );
00134       }
00135 
00136     ++basei[0];
00137     if(basei[0]>this->m_EndIndex[0])
00138       {
00139       return( static_cast<OutputType>( val0 ) );
00140       }
00141     const RealType val1 = this->GetInputImage()->GetPixel( basei );
00142 
00143     return( static_cast<OutputType>( val0 + ( val1 - val0 ) * distance ) );
00144     }
00145 
00146   inline OutputType EvaluateOptimized( const Dispatch<2>&,
00147                                        const ContinuousIndexType & index) const
00148     {
00149     IndexType basei;
00150 
00151     basei[0] = Math::Floor(index[0]);
00152     if( basei[0] < this->m_StartIndex[0] )
00153       {
00154       basei[0] = this->m_StartIndex[0];
00155       }
00156     const double distance0 = index[0] - static_cast<double>(basei[0]);
00157 
00158     basei[1] = Math::Floor(index[1]);
00159     if( basei[1] < this->m_StartIndex[1] )
00160       {
00161       basei[1] = this->m_StartIndex[1];
00162       }
00163     const double distance1 = index[1] - static_cast<double>(basei[1]);
00164 
00165 
00166     const RealType val00 = this->GetInputImage()->GetPixel( basei );
00167     if(distance0 <= 0. && distance1 <= 0.)
00168       {
00169       return( static_cast<OutputType>( val00 ) );
00170       }
00171     else if(distance1 <= 0.) // if they have the same "y"
00172       {
00173       ++basei[0];  // then interpolate across "x"
00174       if(basei[0]>this->m_EndIndex[0])
00175         {
00176         return( static_cast<OutputType>( val00 ) );
00177         }
00178       const RealType val10 = this->GetInputImage()->GetPixel( basei );
00179       return( static_cast<OutputType>(val00 + (val10 - val00) * distance0) );
00180       }
00181     else if(distance0 <= 0.) // if they have the same "x"
00182       {
00183       ++basei[1];  // then interpolate across "y"
00184       if(basei[1]>this->m_EndIndex[1])
00185         {
00186         return( static_cast<OutputType>( val00 ) );
00187         }
00188       const RealType val01 = this->GetInputImage()->GetPixel( basei );
00189       return( static_cast<OutputType>(val00 + (val01 - val00) * distance1) );
00190       }
00191     else // interpolate across "xy"
00192       {
00193       ++basei[0];
00194       if(basei[0]>this->m_EndIndex[0]) // interpolate across "y"
00195         {
00196         --basei[0];
00197         ++basei[1];
00198         if(basei[1]>this->m_EndIndex[1])
00199           {
00200           return( static_cast<OutputType>( val00 ) );
00201           }
00202         const RealType val01 = this->GetInputImage()->GetPixel( basei );
00203         return( static_cast<OutputType>(val00 + (val01 - val00) * distance1) );
00204         }
00205       const RealType val10 = this->GetInputImage()->GetPixel( basei );
00206 
00207       const RealType valx0 = val00 + (val10 - val00) * distance0;
00208       
00209       ++basei[1];
00210       if(basei[1]>this->m_EndIndex[1]) // interpolate across "x"
00211         {
00212         return( static_cast<OutputType>( valx0 ) );
00213         }
00214       const RealType val11 = this->GetInputImage()->GetPixel( basei );
00215       --basei[0];
00216       const RealType val01 = this->GetInputImage()->GetPixel( basei );
00217 
00218       const RealType valx1 = val01 + (val11 - val01) * distance0;
00219 
00220       return( static_cast<OutputType>( valx0 + (valx1-valx0) * distance1 ) );
00221       }
00222     }
00223 
00224   inline OutputType EvaluateOptimized( const Dispatch<3>&,
00225                                        const ContinuousIndexType & index) const
00226     {
00227     IndexType basei;
00228 
00229     basei[0] = Math::Floor(index[0]);
00230     if( basei[0] < this->m_StartIndex[0] )
00231       {
00232       basei[0] = this->m_StartIndex[0];
00233       }
00234     const double distance0 = index[0] - static_cast<double>(basei[0]);
00235  
00236     basei[1] = Math::Floor(index[1]);
00237     if( basei[1] < this->m_StartIndex[1] )
00238       {
00239       basei[1] = this->m_StartIndex[1];
00240       }
00241     const double distance1 = index[1] - static_cast<double>(basei[1]);
00242  
00243     basei[2] = Math::Floor(index[2]);
00244     if( basei[2] < this->m_StartIndex[2] )
00245       {
00246       basei[2] = this->m_StartIndex[2];
00247       }
00248     const double distance2 = index[2] - static_cast<double>(basei[2]);
00249 
00250     if(distance0<=0. && distance1<=0. && distance2<=0.)
00251       {
00252       return( static_cast<OutputType>( this->GetInputImage()->GetPixel( basei ) ) );
00253       }
00254 
00255     typedef typename IndexType::IndexValueType IndexValueType;
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 Tue Sep 15 04:14:18 2009 for ITK by doxygen 1.5.8 written by Dimitri van Heesch, © 1997-2000