cmtkActiveDeformationModel.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: 2464 $
00026 //
00027 //  $LastChangedDate: 2010-10-19 09:54:33 -0700 (Tue, 19 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
00030 //
00031 */
00032 
00033 #include "cmtkActiveDeformationModel.h"
00034 
00035 #include <System/cmtkConsole.h>
00036 
00037 #include <Base/cmtkVector3D.h>
00038 #include <Base/cmtkAffineXform.h>
00039 
00040 namespace
00041 cmtk
00042 {
00043 
00046 
00047 template<class W>
00048 ActiveDeformationModel<W>::ActiveDeformationModel
00049 ( const std::list< SmartPointer<W> > deformationList, 
00050   const unsigned int numberOfModes,
00051   const bool includeScaleInModel,
00052   const bool includeReferenceInModel )
00053 {
00054   IncludeScaleInModel = includeScaleInModel;
00055   IncludeReferenceInModel = includeReferenceInModel;
00056 
00057   unsigned int numberOfSamples = deformationList.size();
00058   if ( IncludeReferenceInModel )
00059     ++numberOfSamples;
00060   
00061   Types::Coordinate** samplePoints = Memory::AllocateArray<Types::Coordinate*>( numberOfSamples );
00062   unsigned int numberOfPoints = 0;
00063   
00064   typename std::list< SmartPointer<W> >::const_iterator it = deformationList.begin();
00065 
00066   // prepare this object to act as an actual deformation.
00067   this->InitGrid( (*it)->Domain, (*it)->m_Dims );
00068   // copy Origin field of first warp.
00069   this->m_Offset = (*it)->m_Offset;
00070   
00071   unsigned int sample = 0;
00072   Types::Coordinate globalScaling = 0;
00073   if ( IncludeReferenceInModel ) 
00074     {
00075     samplePoints[sample++] = this->MakeSamplePointsReference( *it );
00076     }
00077   
00078   while ( it != deformationList.end() ) 
00079     {
00080     if ( it == deformationList.begin() ) 
00081       {
00082       numberOfPoints = (*it)->m_NumberOfParameters;
00083       } 
00084     else
00085       {
00086       if ( numberOfPoints != (*it)->m_NumberOfParameters ) 
00087         {
00088         StdErr << "WARNING: differing numbers of parameters encountered in "
00089                   << "ActiveDeformationModel constructor. Skipping this "
00090                   << "sample.";
00091         --numberOfSamples;
00092         ++it;
00093         continue;
00094         }
00095       }
00096     
00097     samplePoints[sample++] = (*it)->GetPureDeformation( this->IncludeScaleInModel );
00098     globalScaling += static_cast<Types::Coordinate>( log( (*it)->GetGlobalScaling() ) );
00099     ++it;
00100     }
00101   
00102   // Set Initial Affine Transform to Identity
00103   AffineXform::SmartPtr identity( new AffineXform() );
00104   this->SetInitialAffineXform( identity );
00105   
00106   // Set global scaling to average of individual scale factors, unless it
00107   // was preserved as part of the actual model.
00108   if ( ! IncludeScaleInModel ) 
00109     {
00110     this->GlobalScaling = exp( globalScaling / sample );
00111     } 
00112   else
00113     {
00114     this->GlobalScaling = 1.0;
00115     }
00116 
00117   this->Construct( samplePoints, numberOfSamples, numberOfPoints, numberOfModes );
00118   
00119   for ( unsigned int n = 0; n < numberOfSamples; ++n )
00120     Memory::DeleteArray( samplePoints[ n ] );
00121   Memory::DeleteArray( samplePoints );
00122 }
00123 
00124 template<class W>
00125 Types::Coordinate* 
00126 ActiveDeformationModel<W>::MakeSamplePointsReference( const W* deformation )
00127 {
00128   const unsigned int numberOfParameters = deformation->m_NumberOfParameters;
00129   Types::Coordinate* points = Memory::AllocateArray<Types::Coordinate>(  numberOfParameters  );
00130 
00131   Types::Coordinate* ptr = points;
00132   Vector3D v;
00133   for ( unsigned int pointIdx = 0; pointIdx < numberOfParameters / 3; ++pointIdx, ptr += 3 ) 
00134     {
00135     // get original (undeformed) control point position
00136     deformation->GetOriginalControlPointPositionByOffset( v, pointIdx );
00137     
00138     // copy the result into ouput array
00139     for ( unsigned int dim = 0; dim < 3; ++dim ) 
00140       ptr[dim] = v[dim];
00141     }
00142   
00143   return points;
00144 }
00145 
00146 template<class W>
00147 Types::Coordinate* 
00148 ActiveDeformationModel<W>::MakeSamplePoints( const W* deformation )
00149 {
00150   const unsigned int numberOfParameters = deformation->m_NumberOfParameters;
00151   Types::Coordinate* points = Memory::AllocateArray<Types::Coordinate>(  numberOfParameters  );
00152   memcpy( points, deformation->m_Parameters, sizeof( *points ) * numberOfParameters );
00153 
00154   AffineXform::SmartPtr xform( deformation->GetInitialAffineXform()->MakeInverse() );
00155   
00156   if ( IncludeScaleInModel ) 
00157     {
00158     xform->SetScales( 1.0, 1.0, 1.0 );
00159     }
00160   
00161   Types::Coordinate* ptr = points;
00162   Vector3D u;
00163   for ( unsigned int pointIdx = 0; pointIdx < numberOfParameters / 3; ++pointIdx, ptr += 3 ) 
00164     {
00165     FixedVector<3,Types::Coordinate> v( ptr );
00166     
00167     // undo affine transformation component
00168     xform->ApplyInPlace( v );
00169     
00170     // copy the result into ouput array
00171     for ( unsigned int dim = 0; dim < 3; ++dim ) 
00172       ptr[dim] = v[dim];
00173     }
00174   
00175   return points;
00176 }
00177 
00178 template<class W>
00179 W*
00180 ActiveDeformationModel<W>::Compose
00181 ( const Types::Coordinate* weights )
00182 {
00183   this->Generate( this->m_Parameters, weights );
00184 
00185   return this;
00186 }
00187 
00188 template<class W>
00189 float
00190 ActiveDeformationModel<W>::Decompose
00191 ( const W* input, Types::Coordinate *const weights ) const
00192 {
00193   CoordinateVector inputVector( this->GetNumberOfPoints(), input->GetPureDeformation( this->IncludeScaleInModel ) );
00194   return this->ActiveShapeModel::Decompose( &inputVector, weights );
00195 }
00196 
00198 template class ActiveDeformationModel<SplineWarpXform>;
00199 
00200 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines