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 }