cmtkImagePairNonrigidRegistrationFunctional.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2004-2010 SRI International
00004 //
00005 //  Copyright 1997-2010 Torsten Rohlfing
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: 2660 $
00026 //
00027 //  $LastChangedDate: 2010-12-14 12:35:50 -0800 (Tue, 14 Dec 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
00030 //
00031 */
00032 
00033 #include "cmtkImagePairNonrigidRegistrationFunctional.h"
00034 
00035 #include <Base/cmtkSplineWarpXform.h>
00036 #include <Base/cmtkInterpolator.h>
00037 
00038 #include <Registration/cmtkImagePairNonrigidRegistrationFunctionalTemplate.h>
00039 
00040 #include <Registration/cmtkImagePairSimilarityMeasureCR.h>
00041 #include <Registration/cmtkImagePairSimilarityMeasureMSD.h>
00042 #include <Registration/cmtkImagePairSimilarityMeasureRMS.h>
00043 #include <Registration/cmtkImagePairSimilarityMeasureNCC.h>
00044 #include <Registration/cmtkImagePairSimilarityMeasureNMI.h>
00045 #include <Registration/cmtkImagePairSimilarityMeasureMI.h>
00046 
00047 namespace
00048 cmtk
00049 {
00050 
00053 
00054 ImagePairNonrigidRegistrationFunctional::ImagePairNonrigidRegistrationFunctional
00055 ( UniformVolume::SmartPtr& reference, UniformVolume::SmartPtr& floating )
00056   : ImagePairRegistrationFunctional( reference, floating ),
00057     m_ActiveCoordinates( NULL )
00058 {
00059   this->m_NumberOfThreads = ThreadPool::GetGlobalThreadPool().GetNumberOfThreads();
00060   this->m_NumberOfTasks = 4 * this->m_NumberOfThreads - 3;
00061     
00062   Dim = 0;
00063 
00064   ReferenceFrom = UniformVolume::CoordinateVectorType( UniformVolume::CoordinateVectorType::Init( 0 ) );
00065   ReferenceTo = reference->Size;
00066 
00067   this->m_AdaptiveFixParameters = false;
00068   this->m_AdaptiveFixThreshFactor = 0.5;
00069   this->VolumeOfInfluence = NULL;
00070 
00071   this->m_ThreadWarp.resize( this->m_NumberOfThreads );  
00072 
00073   this->m_ThreadVectorCache = Memory::AllocateArray<Vector3D*>( this->m_NumberOfThreads );
00074   for ( size_t thread = 0; thread < this->m_NumberOfThreads; ++thread )
00075     this->m_ThreadVectorCache[thread] = Memory::AllocateArray<Vector3D>( this->m_ReferenceDims[0] );
00076 
00077   this->m_WarpedVolume = NULL;
00078   
00079   this->m_DimsX = this->m_ReferenceGrid->GetDims()[0];
00080   this->m_DimsY = this->m_ReferenceGrid->GetDims()[1];
00081   this->m_DimsZ = this->m_ReferenceGrid->GetDims()[2];
00082   
00083   this->m_FltDimsX = this->m_FloatingGrid->GetDims()[0];
00084   this->m_FltDimsY = this->m_FloatingGrid->GetDims()[1];
00085 }
00086 
00087 ImagePairNonrigidRegistrationFunctional::~ImagePairNonrigidRegistrationFunctional()
00088 {
00089   for ( size_t thread = 0; thread < this->m_NumberOfThreads; ++thread )
00090     if ( this->m_ThreadVectorCache[thread] ) 
00091       Memory::DeleteArray( this->m_ThreadVectorCache[thread] );
00092   Memory::DeleteArray( this->m_ThreadVectorCache );
00093 }
00094 
00095 void
00096 ImagePairNonrigidRegistrationFunctional::WeightedDerivative
00097 ( double& lower, double& upper, SplineWarpXform& warp, 
00098   const int param, const Types::Coordinate step ) const
00099 {
00100   if ( this->m_JacobianConstraintWeight > 0 )
00101     {
00102     double lowerConstraint = 0, upperConstraint = 0;
00103     warp.GetJacobianConstraintDerivative( lowerConstraint, upperConstraint, param, VolumeOfInfluence[param], step );
00104     lower -= this->m_JacobianConstraintWeight * lowerConstraint;
00105     upper -= this->m_JacobianConstraintWeight * upperConstraint;
00106     } 
00107 
00108   if ( this->m_GridEnergyWeight > 0 ) 
00109     {
00110     double lowerEnergy = 0, upperEnergy = 0;
00111     warp.GetGridEnergyDerivative( lowerEnergy, upperEnergy, param, step );
00112     lower -= this->m_GridEnergyWeight * lowerEnergy;
00113     upper -= this->m_GridEnergyWeight * upperEnergy;
00114     }
00115 
00116   // Catch infinite values that result from a folding grid. Effectively
00117   // prevent this by setting the gradient term to 0.
00118   if ( !finite(upper) || !finite(lower) ) 
00119     {
00120     lower = upper = 0;
00121     }
00122   else
00123     {
00124     if ( this->m_MatchedLandmarkList ) 
00125       {
00126       double lowerMSD, upperMSD;
00127       warp.GetDerivativeLandmarksMSD( lowerMSD, upperMSD, this->m_MatchedLandmarkList, param, step );
00128       lower -= this->m_LandmarkErrorWeight * lowerMSD;
00129       upper -= this->m_LandmarkErrorWeight * upperMSD;
00130       }
00131     if ( this->m_InverseTransformation ) 
00132       {
00133       double lowerIC, upperIC;
00134       warp.GetDerivativeInverseConsistencyError( lowerIC, upperIC, this->m_InverseTransformation, this->m_ReferenceGrid, &(this->VolumeOfInfluence[param]), param, step );
00135       lower -= this->m_InverseConsistencyWeight * lowerIC;
00136       upper -= this->m_InverseConsistencyWeight * upperIC;
00137       }
00138     }
00139 }
00140 
00141 void
00142 ImagePairNonrigidRegistrationFunctional::SetWarpXform
00143 ( SplineWarpXform::SmartPtr& warp )
00144 {
00145   this->m_Warp = warp;
00146   if ( this->m_Warp )
00147     {
00148     this->m_Warp->RegisterVolume( this->m_ReferenceGrid );
00149     if ( Dim != this->m_Warp->VariableParamVectorDim() ) 
00150       {
00151       Dim = this->m_Warp->VariableParamVectorDim();
00152       this->m_StepScaleVector.resize( Dim );
00153       VolumeOfInfluence = Memory::AllocateArray<DataGrid::RegionType>( Dim );
00154       }
00155     
00156     DataGrid::RegionType *VOIptr = VolumeOfInfluence;
00157     Vector3D fromVOI, toVOI;
00158     for ( size_t dim=0; dim<Dim; ++dim, ++VOIptr ) 
00159       {
00160       this->m_StepScaleVector[dim] = this->GetParamStep( dim );
00161       this->m_Warp->GetVolumeOfInfluence( dim, ReferenceFrom, ReferenceTo, fromVOI, toVOI );
00162       *VOIptr = this->GetReferenceGridRange( fromVOI, toVOI );
00163       }
00164     
00165     for ( size_t thread = 0; thread < this->m_NumberOfThreads; ++thread ) 
00166       {
00167       if ( thread ) 
00168         {
00169         this->m_ThreadWarp[thread] = this->m_Warp->Clone();
00170         this->m_ThreadWarp[thread]->RegisterVolume( this->m_ReferenceGrid );
00171         } 
00172       else 
00173         {
00174         this->m_ThreadWarp[thread] = this->m_Warp;
00175         }
00176       } 
00177     }
00178 }
00179 
00180 ImagePairNonrigidRegistrationFunctional* 
00181 ImagePairNonrigidRegistrationFunctional::Create
00182 ( const int metric,
00183   UniformVolume::SmartPtr& refVolume, 
00184   UniformVolume::SmartPtr& fltVolume,
00185   const Interpolators::InterpolationEnum interpolation )
00186 {
00187   switch ( metric ) 
00188     {
00189     case 0:
00190       return new ImagePairNonrigidRegistrationFunctionalTemplate<ImagePairSimilarityMeasureNMI>( refVolume, fltVolume, interpolation );
00191     case 1:
00192       return new ImagePairNonrigidRegistrationFunctionalTemplate<ImagePairSimilarityMeasureMI>( refVolume, fltVolume, interpolation );
00193     case 2:
00194       return new ImagePairNonrigidRegistrationFunctionalTemplate<ImagePairSimilarityMeasureCR>( refVolume, fltVolume, interpolation );
00195     case 3:
00196       return new ImagePairNonrigidRegistrationFunctionalTemplate<ImagePairSimilarityMeasureRMS>( refVolume, fltVolume, interpolation );
00197     case 4:
00198       return new ImagePairNonrigidRegistrationFunctionalTemplate<ImagePairSimilarityMeasureMSD>( refVolume, fltVolume, interpolation );
00199     case 5:
00200       return new ImagePairNonrigidRegistrationFunctionalTemplate<ImagePairSimilarityMeasureNCC>( refVolume, fltVolume, interpolation );
00201     default:
00202       return NULL;
00203     }
00204 
00205   return NULL;
00206 }
00207 
00208 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines