00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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& );
00099 void operator=( const Self& );
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)
00163 {
00164 ++basei[0];
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)
00173 {
00174 ++basei[1];
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 );
00192 double val1 = val10 + distance1 * ( val11 - val10 );
00193
00194 return( static_cast<OutputType>( val0 + distance0 * (val1-val0) ) );
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 }
00377
00378
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