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: 2008/01/10 21:01:46 $
00007   Version:   $Revision: 1.5 $
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 = float>
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::RealType RealType;
00067 
00069   itkStaticConstMacro(ImageDimension, unsigned int,Superclass::ImageDimension);
00070 
00072   typedef typename Superclass::IndexType IndexType;
00073 
00075   typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
00076 
00085   virtual inline OutputType EvaluateAtContinuousIndex( const 
00086                                                          ContinuousIndexType &
00087                                                             index ) const
00088     {
00089     return this->EvaluateOptimized( Dispatch< ImageDimension >(), index );
00090     }
00091 
00092 protected:
00093   LinearInterpolateImageFunction();
00094   ~LinearInterpolateImageFunction();
00095   void PrintSelf(std::ostream& os, Indent indent) const;
00096 
00097 private:
00098   LinearInterpolateImageFunction( const Self& ); //purposely not implemented
00099   void operator=( const Self& ); //purposely not implemented
00100 
00102   static const unsigned long  m_Neighbors;  
00103 
00104   struct DispatchBase {};
00105   template< unsigned int > struct Dispatch : DispatchBase {};
00106 
00107   inline OutputType EvaluateOptimized( const Dispatch<0> &,
00108                                        const ContinuousIndexType & index) const
00109     {
00110     return 0;
00111     }
00112 
00113   inline OutputType EvaluateOptimized( const Dispatch<1>&,
00114                                        const ContinuousIndexType & index) const
00115     {
00116     IndexType basei;
00117 
00118     double i = index[0];
00119     basei[0] = (long)i;
00120     if( i < 0.0 && double(basei[0]) != i)
00121       {
00122       basei[0]--;
00123       }
00124 
00125     double distance = i - double(basei[0]);
00126 
00127     double val0 = this->GetInputImage()->GetPixel( basei );
00128     double val1 = val0;
00129     ++basei[0];
00130     val1 = this->GetInputImage()->GetPixel( basei );
00131 
00132     return( static_cast<OutputType>( val0 + distance * ( val1 - val0 ) ) );
00133     }
00134 
00135   inline OutputType EvaluateOptimized( const Dispatch<2>&,
00136                                        const ContinuousIndexType & index) const
00137     {
00138     IndexType basei;
00139 
00140     double i = index[0];
00141     basei[0] = (long)i;
00142     if( i < 0.0 && double(basei[0]) != i)
00143       {
00144       basei[0]--;
00145       }
00146     double distance0 = i - double(basei[0]);
00147 
00148     i = index[1];
00149     basei[1] = (long)i;
00150     if( i < 0.0 && double(basei[1]) != i)
00151       {
00152       basei[1]--;
00153       }
00154     double distance1 = i - double(basei[1]);
00155 
00156 
00157     double val00 = this->GetInputImage()->GetPixel( basei );
00158     if(distance0+distance1 == 0)
00159       {
00160       return( static_cast<OutputType>( val00 ) );
00161       }
00162     else if(distance1 == 0) // if they have the same "y"
00163       {
00164       ++basei[0];  // then interpolate across "x"
00165       if(basei[0]>this->m_EndIndex[0])
00166         {
00167         return( static_cast<OutputType>( val00 ) );
00168         }
00169       double val10 = this->GetInputImage()->GetPixel( basei );
00170       return( static_cast<OutputType>(val00 + distance0 * (val10 - val00)) );
00171       }
00172     else if(distance0 == 0) // if they have the same "x"
00173       {
00174       ++basei[1];  // then interpolate across "y"
00175       if(basei[1]>this->m_EndIndex[1])
00176         {
00177         return( static_cast<OutputType>( val00 ) );
00178         }
00179       double val01 = this->GetInputImage()->GetPixel( basei );
00180       return( static_cast<OutputType>(val00 + distance1 * (val01 - val00)) );
00181       }
00182     else
00183       {
00184       ++basei[0];
00185       double val10 = this->GetInputImage()->GetPixel( basei );
00186       ++basei[1];
00187       double val11 = this->GetInputImage()->GetPixel( basei );
00188       --basei[0];
00189       double val01 = this->GetInputImage()->GetPixel( basei );
00190     
00191       double val0 = val00 + distance1 * ( val01 - val00 ); // interpolate across "y"
00192       double val1 = val10 + distance1 * ( val11 - val10 ); // interpolate across "y"
00193 
00194       return( static_cast<OutputType>( val0 + distance0 * (val1-val0) ) ); // interpolate across "X"
00195       }
00196     }
00197 
00198   inline OutputType EvaluateOptimized( const Dispatch<3>&,
00199                                        const ContinuousIndexType & index) const
00200     {
00201     IndexType basei;
00202     double val[8];
00203 
00204     unsigned long min0;
00205     unsigned long max0;
00206     unsigned long min1;
00207     unsigned long max1;
00208     unsigned long min2;
00209     unsigned long max2;
00210 
00211     double i = index[0];
00212     basei[0] = (long)i;
00213     if( i < 0.0 && double(basei[0]) != i)
00214       {
00215       basei[0]--;
00216       }
00217     double distance0 = i - double(basei[0]);
00218  
00219     i = index[1];
00220     basei[1] = (long)i;
00221     if( i < 0.0 && double(basei[1]) != i)
00222       {
00223       basei[1]--;
00224       }
00225     double distance1 = i - double(basei[1]);
00226  
00227     i = index[2];
00228     basei[2] = (long)i;
00229     if( i < 0.0 && double(basei[2]) != i)
00230       {
00231       basei[2]--;
00232       }
00233     double distance2 = i - double(basei[2]);
00234 
00235     val[0] = this->GetInputImage()->GetPixel( basei );
00236     if(distance0+distance1+distance2 == 0)
00237       {
00238       return( static_cast<OutputType>( val[0] ) );
00239       }
00240     if(distance0 > 0.0)
00241       {
00242       min0 = basei[0];
00243       max0 = basei[0]+1;
00244       if(max0>this->m_EndIndex[0])
00245         {
00246         max0 = this->m_EndIndex[0];
00247         }
00248       }
00249     if(distance1 > 0.0)
00250       {
00251       min1 = basei[1];
00252       max1 = basei[1]+1;
00253       if(max1>this->m_EndIndex[1])
00254         {
00255         max1 = this->m_EndIndex[1];
00256         }
00257       }
00258     if(distance2 > 0.0)
00259       {
00260       min2 = basei[2];
00261       max2 = basei[2]+1;
00262       if(max2>this->m_EndIndex[2])
00263         {
00264         max2 = this->m_EndIndex[2];
00265         }
00266       }
00267     if(distance2 == 0)
00268       {
00269       if(distance1 == 0)
00270         {
00271         basei[0] = max0;
00272         val[1] = this->GetInputImage()->GetPixel( basei );
00273  
00274         double val0 = val[0] + distance0 * (val[1]-val[0]);
00275  
00276         return( static_cast<OutputType>( val0 ) );
00277         }
00278       else if(distance0 == 0)
00279         {
00280         basei[1] = max1;
00281         val[2] = this->GetInputImage()->GetPixel( basei );
00282  
00283         double val0 = val[0] + distance1 * (val[2]-val[0]);
00284  
00285         return( static_cast<OutputType>( val0 ) );
00286         }
00287       else
00288         {
00289         basei[0] = max0;
00290         val[1] = this->GetInputImage()->GetPixel( basei );
00291         basei[1] = max1;
00292         val[3] = this->GetInputImage()->GetPixel( basei );
00293         basei[0] = min0;
00294         val[2] = this->GetInputImage()->GetPixel( basei );
00295  
00296         double val0 = val[0] + distance0 * (val[1]-val[0]);
00297         double val1 = val[2] + distance0 * (val[3]-val[2]);
00298 
00299         return( static_cast<OutputType>( val0 + distance1 * (val1 - val0) ) );
00300         }
00301       }
00302     else
00303       {
00304       basei[2] = max2;
00305       val[4] = this->GetInputImage()->GetPixel( basei );
00306       if(distance1 == 0)
00307         {
00308         if(distance0 == 0)
00309           {
00310           return( static_cast<OutputType>( val[0] + distance2 
00311                                                     * (val[4] - val[0]) ) );
00312           }
00313         else
00314           {
00315           basei[0] = max0;
00316           val[5] = this->GetInputImage()->GetPixel( basei );
00317           basei[2] = min2;
00318           val[1] = this->GetInputImage()->GetPixel( basei );
00319   
00320           double val0 = val[0] + distance0 * (val[1]-val[0]);
00321           double val1 = val[4] + distance0 * (val[5]-val[4]);
00322  
00323           return( static_cast<OutputType>( val0 + distance2 * (val1 - val0) ) );
00324           }
00325         }
00326       else if(distance0 == 0)
00327         {
00328         basei[1] = max1;
00329         val[6] = this->GetInputImage()->GetPixel( basei );
00330         basei[2] = min2;
00331         val[2] = this->GetInputImage()->GetPixel( basei );
00332  
00333         double val0 = val[0] + distance1 * (val[2]-val[0]);
00334         double val1 = val[4] + distance1 * (val[6]-val[4]);
00335  
00336         return( static_cast<OutputType>( val0 + distance2 * (val1 - val0) ) );
00337         }
00338       else 
00339         {
00340         basei[0] = max0;
00341         val[5] = this->GetInputImage()->GetPixel( basei );
00342         basei[1] = max1;
00343         val[7] = this->GetInputImage()->GetPixel( basei );
00344         basei[0] = min0;
00345         val[6] = this->GetInputImage()->GetPixel( basei );
00346         basei[2] = min2;
00347         val[2] = this->GetInputImage()->GetPixel( basei );
00348         basei[0] = max0;
00349         val[3] = this->GetInputImage()->GetPixel( basei );
00350         basei[1] = min1;
00351         val[1] = this->GetInputImage()->GetPixel( basei );
00352  
00353         double val00 = val[0] + distance0 * (val[1]-val[0]);
00354         double val01 = val[2] + distance0 * (val[3]-val[2]);
00355         double val0 = val00 + distance1 * (val01-val00);
00356   
00357         double val10 = val[4] + distance0 * (val[5]-val[4]);
00358         double val11 = val[6] + distance0 * (val[7]-val[6]);
00359         double val1 = val10 + distance1 * (val11-val10);
00360   
00361         return( static_cast<OutputType>( val0 + distance2 * (val1-val0) ) );
00362         }
00363       }
00364     }
00365 
00366   inline OutputType EvaluateOptimized( const DispatchBase &,
00367                                        const ContinuousIndexType & index) const
00368     {
00369     return this->EvaluateUnoptimized( index );
00370     }
00371                                        
00372   virtual inline OutputType EvaluateUnoptimized( 
00373                                        const ContinuousIndexType & index) const;
00374 };
00375 
00376 } // end namespace itk
00377 
00378 // Define instantiation macro for this template.
00379 #define ITK_TEMPLATE_LinearInterpolateImageFunction(_, EXPORT, x, y) namespace itk { \
00380   _(2(class EXPORT LinearInterpolateImageFunction< ITK_TEMPLATE_2 x >)) \
00381   namespace Templates { typedef LinearInterpolateImageFunction< ITK_TEMPLATE_2 x > \
00382                                                   LinearInterpolateImageFunction##y; } \
00383   }
00384 
00385 #if ITK_TEMPLATE_EXPLICIT
00386 # include "Templates/itkLinearInterpolateImageFunction+-.h"
00387 #endif
00388 
00389 #if ITK_TEMPLATE_TXX
00390 # include "itkOptLinearInterpolateImageFunction.txx"
00391 #endif
00392 
00393 #endif
00394 

Generated at Wed Nov 5 23:18:53 2008 for ITK by doxygen 1.5.1 written by Dimitri van Heesch, © 1997-2000