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 #include "cmtkUniformVolumeInterpolatorPartialVolume.h"
00034
00035 #include <math.h>
00036
00037 #ifdef HAVE_IEEEFP_H
00038 # include <ieeefp.h>
00039 #endif
00040
00041 namespace cmtk
00042 {
00043
00046
00047 bool
00048 UniformVolumeInterpolatorPartialVolume
00049 ::GetDataAt(const Vector3D& v, Types::DataItem& value) const
00050 {
00051 value=0;
00052
00053 Types::Coordinate lScaled[3];
00054 int imageGridPoint[3];
00055 for ( int n = 0; n < 3; ++n )
00056 {
00057 lScaled[n] = (v[n]-this->m_VolumeOffset[n]) / this->m_VolumeDeltas[n];
00058 imageGridPoint[n] = (int) floor( lScaled[n] );
00059 if ( ( imageGridPoint[n] < 0 ) || ( imageGridPoint[n] >= this->m_VolumeDims[n]-1 ) )
00060 return false;
00061 }
00062
00063 const size_t offset = this->GetOffsetFromIndex( imageGridPoint[0], imageGridPoint[1], imageGridPoint[2] );
00064
00065 bool done[8];
00066 Types::DataItem corners[8];
00067 bool dataPresent = false;
00068
00069 size_t idx = 0;
00070 for ( int k = 0; k < 2; ++k )
00071 {
00072 for ( int j = 0; j < 2; ++j )
00073 {
00074 for ( int i = 0; i < 2; ++i, ++idx )
00075 {
00076 corners[idx] = this->m_VolumeDataArray[offset + this->GetOffsetFromIndex( i, j, k )];
00077 const bool dataHere = finite( corners[idx] );
00078 done[idx] = !dataHere;
00079 dataPresent |= dataHere;
00080 }
00081 }
00082 }
00083
00084 if (dataPresent)
00085 {
00086 const Types::Coordinate revX = lScaled[0]-imageGridPoint[0];
00087 const Types::Coordinate revY = lScaled[1]-imageGridPoint[1];
00088 const Types::Coordinate revZ = lScaled[2]-imageGridPoint[2];
00089 const Types::Coordinate offsX = 1-revX;
00090 const Types::Coordinate offsY = 1-revY;
00091 const Types::Coordinate offsZ = 1-revZ;
00092
00093 const Types::Coordinate weights[8] =
00094 { offsX * offsY * offsZ, revX * offsY * offsZ, offsX * revY * offsZ, revX * revY * offsZ,
00095 offsX * offsY * revZ, revX * offsY * revZ, offsX * revY * revZ, revX * revY * revZ
00096 };
00097
00098 bool done[8];
00099 memset( done, 0, sizeof( done ) );
00100
00101 Types::Coordinate maxWeight = 0;
00102 for ( unsigned int j = 0; j < 8; ++j )
00103 {
00104 if ( done[j] ) continue;
00105 Types::Coordinate weight = weights[j];
00106 for ( unsigned int i = j+1; i < 8; ++i )
00107 {
00108 if ( done[i] ) continue;
00109 if ( corners[i] == corners[j] )
00110 {
00111 weight += weights[i];
00112 done[i] = true;
00113 }
00114 }
00115 if ( weight > maxWeight )
00116 {
00117 value = corners[j];
00118 maxWeight = weight;
00119 }
00120 }
00121
00122 return true;
00123 }
00124
00125 return false;
00126 }
00127
00128 Types::DataItem
00129 UniformVolumeInterpolatorPartialVolume
00130 ::GetDataDirect( const int* imageGridPoint, const Types::Coordinate* insidePixel ) const
00131 {
00132 Types::DataItem value = 0;
00133
00134 const size_t offset = this->GetOffsetFromIndex( imageGridPoint[0], imageGridPoint[1], imageGridPoint[2] );
00135
00136 bool done[8];
00137 Types::DataItem corners[8];
00138 bool dataPresent = false;
00139
00140 size_t idx = 0;
00141 for ( int k = 0; k < 2; ++k )
00142 {
00143 for ( int j = 0; j < 2; ++j )
00144 {
00145 for ( int i = 0; i < 2; ++i, ++idx )
00146 {
00147 corners[idx] = this->m_VolumeDataArray[offset + this->GetOffsetFromIndex( i, j, k )];
00148 const bool dataHere = finite( corners[idx] );
00149 done[idx] = !dataHere;
00150 dataPresent |= dataHere;
00151 }
00152 }
00153 }
00154
00155 if (dataPresent)
00156 {
00157 const Types::Coordinate offsX = 1-insidePixel[0];
00158 const Types::Coordinate offsY = 1-insidePixel[1];
00159 const Types::Coordinate offsZ = 1-insidePixel[2];
00160
00161 const Types::Coordinate weights[8] =
00162 { offsX * offsY * offsZ,
00163 insidePixel[0] * offsY * offsZ,
00164 offsX * insidePixel[1] * offsZ,
00165 insidePixel[0] * insidePixel[1] * offsZ,
00166 offsX * offsY * insidePixel[2],
00167 insidePixel[0] * offsY * insidePixel[2],
00168 offsX * insidePixel[1] * insidePixel[2],
00169 insidePixel[0] * insidePixel[1] * insidePixel[2]
00170 };
00171
00172 Types::Coordinate maxWeight = 0;
00173 for ( unsigned int j = 0; j < 8; ++j )
00174 {
00175 if ( done[j] ) continue;
00176 Types::Coordinate weight = weights[j];
00177 for ( unsigned int i = j+1; i < 8; ++i )
00178 {
00179 if ( done[i] ) continue;
00180 if ( corners[i] == corners[j] )
00181 {
00182 weight += weights[i];
00183 done[i] = true;
00184 }
00185 }
00186 if ( weight > maxWeight )
00187 {
00188 value = corners[j];
00189 maxWeight = weight;
00190 }
00191 }
00192 }
00193
00194 return value;
00195 };
00196
00197 }
00198