Go to the documentation of this file.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 = 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& );
00103 void operator=( const Self& );
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.)
00173 {
00174 ++basei[0];
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.)
00183 {
00184 ++basei[1];
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
00193 {
00194 ++basei[0];
00195 if(basei[0]>this->m_EndIndex[0])
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])
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.)
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.)
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
00284 {
00285 ++basei[0];
00286 if(basei[0]>this->m_EndIndex[0])
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])
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.)
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
00333 {
00334 ++basei[0];
00335 if(basei[0]>this->m_EndIndex[0])
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])
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.)
00367 {
00368 ++basei[1];
00369 if(basei[1]>this->m_EndIndex[1])
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])
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
00400 {
00401 ++basei[0];
00402 if(basei[0]>this->m_EndIndex[0])
00403 {
00404 --basei[0];
00405 ++basei[1];
00406 if(basei[1]>this->m_EndIndex[1])
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])
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])
00442 {
00443 --basei[1];
00444 ++basei[2];
00445 if(basei[2]>this->m_EndIndex[2])
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])
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 }
00504
00505
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