cmtkUniformVolumeInterpolator.txx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2266 $
00026 //
00027 //  $LastChangedDate: 2010-08-19 15:30:11 -0700 (Thu, 19 Aug 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
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 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines