cmtkDeformationField.cxx

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: 2453 $
00026 //
00027 //  $LastChangedDate: 2010-10-18 10:33:06 -0700 (Mon, 18 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
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   // Do some precomputations.
00120   for ( int dim = 0; dim<3; ++dim ) 
00121     {
00122     // This is the (real-valued) index of the control point grid cell the
00123     // given location is in.
00124     r[dim] = this->InverseSpacing[dim] * ( v[dim] - this->m_Offset[dim] );
00125     // This is the actual cell index.
00126     grid[dim] = std::min( static_cast<int>( r[dim] ), this->m_Dims[dim]-2 );
00127     // And here's the relative position within the cell.
00128     f[dim] = r[dim] - grid[dim];
00129     }
00130   
00131   // Create a pointer to the front-lower-left corner of the c.p.g. cell.
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     // Loop over 4 c.p.g. planes in z-direction.
00140     for ( int m = 0; m < 2; ++m ) 
00141       {
00142       Types::Coordinate ll = 0;
00143       Types::Coordinate *coeff_ll = coeff_mm;
00144       
00145       // Loop over 4 c.p.g. planes in y-direction.
00146       for ( int l = 0; l < 2; ++l ) 
00147         {
00148         Types::Coordinate kk = 0;
00149         Types::Coordinate *coeff_kk = coeff_ll;
00150         
00151         // Loop over 4 c.p.g. planes in x-direction.
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 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines