Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #ifdef HAVE_IEEEFP_H
00034 #  include <ieeefp.h>
00035 #endif
00036 
00037 namespace
00038 cmtk
00039 {
00040 
00043 template <class TInterpolationFunction>
00044 bool
00045 UniformVolumeInterpolator<TInterpolationFunction>
00046 ::GetDataAt(const Vector3D& v, Types::DataItem& value) const
00047 {
00048   Types::Coordinate lScaled[3];
00049   int imageGridPoint[3];
00050   for ( int n = 0; n < 3; ++n )
00051     {
00052     lScaled[n] = (v[n] - this->m_VolumeOffset[n]) / this->m_VolumeDeltas[n];
00053     imageGridPoint[n] = (int) floor( lScaled[n] );
00054     if ( ( imageGridPoint[n] < 0 ) || ( imageGridPoint[n] >= this->m_VolumeDims[n]-1 ) )
00055       return false;
00056     }
00057 
00058   const int xx = imageGridPoint[0] + 1 - TInterpolationFunction::RegionSizeLeftRight;
00059   const int yy = imageGridPoint[1] + 1 - TInterpolationFunction::RegionSizeLeftRight;
00060   const int zz = imageGridPoint[2] + 1 - TInterpolationFunction::RegionSizeLeftRight;
00061 
00062   Types::Coordinate interpolationWeights[3][2 * TInterpolationFunction::RegionSizeLeftRight];
00063 
00064   for ( int n = 0; n < 3; ++n )
00065     {
00066     const Types::Coordinate relative = lScaled[n] - imageGridPoint[n];
00067     for ( int m = 1-TInterpolationFunction::RegionSizeLeftRight; m <= TInterpolationFunction::RegionSizeLeftRight; ++m )
00068       {
00069       interpolationWeights[n][m+TInterpolationFunction::RegionSizeLeftRight-1] = TInterpolationFunction::GetWeight( m, relative );
00070       }
00071     }
00072 
00073   const int iMin = std::max( 0, -xx );
00074   const int iMax = std::min( 2 * TInterpolationFunction::RegionSizeLeftRight, this->m_VolumeDims[0] - xx );
00075 
00076   const int jMin = std::max( 0, -yy );
00077   const int jMax = std::min( 2 * TInterpolationFunction::RegionSizeLeftRight, this->m_VolumeDims[1] - yy );
00078 
00079   const int kMin = std::max( 0, -zz );
00080   const int kMax = std::min( 2 * TInterpolationFunction::RegionSizeLeftRight, this->m_VolumeDims[2] - zz );
00081 
00082   Types::DataItem interpolatedData = 0;
00083   Types::Coordinate totalWeight = 0;
00084 
00085   for ( int k = kMin; k < kMax; ++k )
00086     {
00087     for ( int j = jMin; j < jMax; ++j )
00088       {
00089       const Types::Coordinate weightJK = interpolationWeights[1][j] * interpolationWeights[2][k];
00090       size_t offset = this->GetOffsetFromIndex( xx + iMin, yy + j, zz + k );
00091       for ( int i = iMin; i < iMax; ++i, ++offset )
00092         {
00093         const Types::DataItem data = this->m_VolumeDataArray[offset];
00094         if ( finite( data ) )
00095           {
00096           const Types::Coordinate weightIJK = interpolationWeights[0][i] * weightJK;
00097           interpolatedData += static_cast<Types::DataItem>( data * weightIJK );
00098           totalWeight += weightIJK;
00099           }
00100         }
00101       }
00102     }
00103 
00104   if ( totalWeight == 0 )
00105     return false;
00106   else
00107     value = static_cast<Types::DataItem>( interpolatedData / totalWeight );
00108 
00109   return true;
00110 }
00111 
00112 template <class TInterpolationFunction>
00113 Types::DataItem
00114 UniformVolumeInterpolator<TInterpolationFunction>
00115 ::GetDataDirect( const int* imageGridPoint, const Types::Coordinate* insidePixel ) const
00116 {
00117   Types::Coordinate interpolationWeights[3][2 * TInterpolationFunction::RegionSizeLeftRight];
00118 
00119   for ( int n = 0; n < 3; ++n )
00120     {
00121     for ( int m = 1-TInterpolationFunction::RegionSizeLeftRight; m <= TInterpolationFunction::RegionSizeLeftRight; ++m )
00122       {
00123       interpolationWeights[n][m+TInterpolationFunction::RegionSizeLeftRight-1] = TInterpolationFunction::GetWeight( m, insidePixel[n] );
00124       }
00125     }
00126 
00127   const int xx = imageGridPoint[0] + 1 - TInterpolationFunction::RegionSizeLeftRight;
00128   const int yy = imageGridPoint[1] + 1 - TInterpolationFunction::RegionSizeLeftRight;
00129   const int zz = imageGridPoint[2] + 1 - TInterpolationFunction::RegionSizeLeftRight;
00130 
00131   const int iMin = std::max( 0, -xx );
00132   const int iMax = std::min( 2 * TInterpolationFunction::RegionSizeLeftRight, this->m_VolumeDims[0] - xx );
00133 
00134   const int jMin = std::max( 0, -yy );
00135   const int jMax = std::min( 2 * TInterpolationFunction::RegionSizeLeftRight, this->m_VolumeDims[1] - yy );
00136 
00137   const int kMin = std::max( 0, -zz );
00138   const int kMax = std::min( 2 * TInterpolationFunction::RegionSizeLeftRight, this->m_VolumeDims[2] - zz );
00139 
00140   Types::DataItem interpolatedData = 0;
00141   Types::Coordinate totalWeight = 0;
00142 
00143   for ( int k = kMin; k < kMax; ++k )
00144     {
00145     for ( int j = jMin; j < jMax; ++j )
00146       {
00147       const Types::Coordinate weightJK = interpolationWeights[1][j] * interpolationWeights[2][k];
00148       size_t offset = (xx + iMin) + (yy + j) * this->m_NextJ + (zz + k) * this->m_NextK;
00149       for ( int i = iMin; i < iMax; ++i, ++offset )
00150         {
00151         const Types::DataItem data = this->m_VolumeDataArray[offset];
00152         if ( finite( data ) )
00153           {
00154           const Types::Coordinate weightIJK = interpolationWeights[0][i] * weightJK;
00155           interpolatedData += static_cast<Types::DataItem>( data * weightIJK );
00156           totalWeight += weightIJK;
00157           }
00158         }
00159       }
00160     }
00161   
00162   if ( totalWeight == 0 )
00163     return 0;
00164   else
00165     return static_cast<Types::DataItem>( interpolatedData / totalWeight );
00166 }
00167 
00168 }