itkOptLinearInterpolateImageFunction.h
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
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& );
00102 void operator=( const Self& );
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.)
00172 {
00173 ++basei[0];
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.)
00182 {
00183 ++basei[1];
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
00192 {
00193 ++basei[0];
00194 if(basei[0]>this->m_EndIndex[0])
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])
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.)
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