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 "cmtkDeformationField.h"
00034
00035 namespace
00036 cmtk
00037 {
00038
00041
00042 void
00043 DeformationField::InitControlPoints( const AffineXform* affineXform )
00044 {
00045 this->m_ParameterVector->Clear();
00046
00047 if ( affineXform )
00048 {
00049 Types::Coordinate *ofs = this->m_Parameters;
00050
00051 Self::SpaceVectorType p;
00052 p[2] = this->m_Offset[2];
00053 for ( int z = 0; z < this->m_Dims[2]; ++z, p[2] += this->Spacing[2] )
00054 {
00055 p[1] = this->m_Offset[1];
00056 for ( int y = 0; y < this->m_Dims[1]; ++y, p[1] += this->Spacing[1] )
00057 {
00058 p[0] = this->m_Offset[0];
00059 for ( int x = 0; x < this->m_Dims[0]; ++x, p[0] += this->Spacing[0], ofs+=3 )
00060 {
00061 Self::SpaceVectorType q( p );
00062 affineXform->ApplyInPlace( q );
00063 q -= p;
00064
00065 ofs[0] = q[0];
00066 ofs[1] = q[1];
00067 ofs[2] = q[2];
00068 }
00069 }
00070 }
00071
00072 affineXform->GetScales( this->InverseAffineScaling );
00073 this->GlobalScaling = affineXform->GetGlobalScaling();
00074 }
00075 else
00076 {
00077 this->InverseAffineScaling[0] = this->InverseAffineScaling[1] = this->InverseAffineScaling[2] = this->GlobalScaling = 1.0;
00078 }
00079 }
00080
00081 void
00082 DeformationField
00083 ::GetTransformedGrid
00084 ( Self::SpaceVectorType& v, const int idxX, const int idxY, const int idxZ ) const
00085 {
00086 const Types::Coordinate* coeff = this->m_Parameters + nextI * idxX + nextJ * idxY + nextK * idxZ;
00087
00088 v[0] = this->m_Offset[0] + this->Spacing[0] * idxX + coeff[0];
00089 v[1] = this->m_Offset[1] + this->Spacing[1] * idxY + coeff[1];
00090 v[2] = this->m_Offset[2] + this->Spacing[2] * idxZ + coeff[2];
00091 }
00092
00093 void
00094 DeformationField::GetTransformedGridRow
00095 ( Self::SpaceVectorType *const vIn, const int numPoints, const int idxX, const int idxY, const int idxZ )
00096 const
00097 {
00098 Self::SpaceVectorType *v = vIn;
00099 const Types::Coordinate* coeff = this->m_Parameters + 3 * (idxX + nextJ * (idxY + nextK * idxZ ));
00100
00101 const Types::Coordinate Y = this->m_Offset[1] + this->Spacing[1] * idxY;
00102 const Types::Coordinate Z = this->m_Offset[2] + this->Spacing[2] * idxZ;
00103
00104 for ( int n = 0; n < numPoints; ++n, ++v, coeff += 3 )
00105 {
00106 v[n][0] = this->m_Offset[0] + this->Spacing[0] * idxX + coeff[0];
00107 v[n][1] = Y + coeff[1];
00108 v[n][2] = Z + coeff[2];
00109 }
00110 }
00111
00112 void
00113 DeformationField::ApplyInPlace
00114 ( Self::SpaceVectorType& v ) const
00115 {
00116 Types::Coordinate r[3], f[3];
00117 int grid[3];
00118
00119
00120 for ( int dim = 0; dim<3; ++dim )
00121 {
00122
00123
00124 r[dim] = this->InverseSpacing[dim] * ( v[dim] - this->m_Offset[dim] );
00125
00126 grid[dim] = std::min( static_cast<int>( r[dim] ), this->m_Dims[dim]-2 );
00127
00128 f[dim] = r[dim] - grid[dim];
00129 }
00130
00131
00132 Types::Coordinate* coeff = this->m_Parameters + 3 * ( grid[0] + this->m_Dims[0] * (grid[1] + this->m_Dims[1] * grid[2]) );
00133
00134 for ( int dim = 0; dim<3; ++dim )
00135 {
00136 Types::Coordinate mm = 0;
00137 Types::Coordinate *coeff_mm = coeff;
00138
00139
00140 for ( int m = 0; m < 2; ++m )
00141 {
00142 Types::Coordinate ll = 0;
00143 Types::Coordinate *coeff_ll = coeff_mm;
00144
00145
00146 for ( int l = 0; l < 2; ++l )
00147 {
00148 Types::Coordinate kk = 0;
00149 Types::Coordinate *coeff_kk = coeff_ll;
00150
00151
00152 for ( int k = 0; k < 2; ++k, coeff_kk+=3 )
00153 {
00154 kk += ( k ? f[0] : 1-f[0] ) * (*coeff_kk);
00155 }
00156 ll += ( l ? f[1] : 1-f[1] ) * kk;
00157 coeff_ll += nextJ;
00158 }
00159 mm += ( m ? f[2] : 1-f[2] ) * ll;
00160 coeff_mm += nextK;
00161 }
00162 v[dim] += mm;
00163 ++coeff;
00164 }
00165 }
00166
00167 }