cmtkImagePairRegistration.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: 2470 $
00026 //
00027 //  $LastChangedDate: 2010-10-20 11:35:16 -0700 (Wed, 20 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
00030 //
00031 */
00032 
00033 #include "cmtkImagePairRegistration.h"
00034 
00035 #include <Base/cmtkVector.h>
00036 #include <Base/cmtkXform.h>
00037 #include <Base/cmtkAffineXform.h>
00038 #include <Base/cmtkFunctional.h>
00039 
00040 #include <System/cmtkTimers.h>
00041 #include <System/cmtkProgress.h>
00042 
00043 #ifdef HAVE_SYS_UTSNAME_H
00044 #  include <sys/utsname.h>
00045 #endif
00046 
00047 namespace
00048 cmtk
00049 {
00050 
00053 
00054 ImagePairRegistration::ImagePairRegistration () 
00055   : m_Metric( 0 ),
00056     m_FloatingImageInterpolation( Interpolators::DEFAULT ),
00057     m_AutoMultiLevels( 0 ),
00058     m_MaxStepSize( -1 ),
00059     m_MinStepSize( -1 ),
00060     m_DeltaFThreshold( 0.0 ),
00061     m_Sampling( -1 ),
00062     m_ForceOutsideFlag( false ),
00063     m_ForceOutsideValue( 0.0 ),
00064     m_PreprocessorRef( "Reference", "ref" ),
00065     m_PreprocessorFlt( "Floating", "flt" ),
00066     m_InitialTransformation( NULL ),
00067     m_InitialXformIsInverse( false ),
00068     m_Xform( NULL ),
00069     m_Optimizer( NULL )
00070 { 
00071   this->m_Callback = RegistrationCallback::SmartPtr( new RegistrationCallback() );
00072 
00073   this->m_Sampling = -1;
00074   this->m_CoarsestResolution = -1;
00075   this->m_UseOriginalData = true;
00076 
00077   this->m_Algorithm = 0;
00078   this->m_UseMaxNorm = true;
00079   this->m_OptimizerStepFactor = 0.5;
00080 }
00081 
00082 CallbackResult
00083 ImagePairRegistration::InitRegistration ()
00084 {
00085   if ( this->m_AutoMultiLevels > 0 )
00086     {
00087     const Types::Coordinate minDelta = std::min( this->m_Volume_1->GetMinDelta(), this->m_Volume_2->GetMinDelta() );
00088     const Types::Coordinate maxDelta = std::max( this->m_Volume_1->GetMaxDelta(), this->m_Volume_2->GetMaxDelta() );
00089 
00090     this->m_MinStepSize = 0.1 * minDelta;
00091     this->m_Sampling = maxDelta;
00092     this->m_MaxStepSize = maxDelta * (1<<(this->m_AutoMultiLevels-1));
00093     }
00094   
00095   if ( this->m_Sampling <= 0 )
00096     this->m_Sampling = std::max( this->m_Volume_1->GetMaxDelta(), this->m_Volume_2->GetMaxDelta() );
00097   
00098   if ( this->m_MaxStepSize <= 0 )
00099     this->m_MaxStepSize = 8.0 * this->m_Sampling;
00100   
00101   if ( this->m_MinStepSize <= 0 )
00102     this->m_MinStepSize = this->m_Sampling / 128;
00103   
00104   this->m_TimeStartLevel = this->m_TimeStartRegistration = cmtk::Timers::GetTimeProcess();
00105   this->m_WalltimeStartLevel = this->m_WalltimeStartRegistration = cmtk::Timers::GetWalltime();
00106   this->m_ThreadTimeStartLevel = this->m_ThreadTimeStartRegistration = cmtk::Timers::GetTimeThread();
00107 
00108   return CALLBACK_OK;
00109 }
00110 
00111 CallbackResult
00112 ImagePairRegistration::Register ()
00113 {
00114   CallbackResult irq = this->InitRegistration();
00115   if ( irq != CALLBACK_OK ) 
00116     {
00117     this->DoneRegistration();
00118     return irq;
00119     }
00120 
00121   this->m_Optimizer->SetDeltaFThreshold( this->m_DeltaFThreshold );
00122   
00123   Types::Coordinate currentExploration = this->m_MaxStepSize;
00124   CoordinateVector::SmartPtr v( new CoordinateVector() );
00125   const size_t NumResolutionLevels = this->m_ParameterStack.size();
00126   
00127   Progress::Begin( 0, NumResolutionLevels, 1, "Multi-level Registration" );
00128 
00129   unsigned int index = 1;
00130   while ( ! this->m_ParameterStack.empty() && ( irq == CALLBACK_OK ) ) 
00131     {
00132     Functional::SmartPtr nextFunctional( this->MakeFunctional( index-1, this->m_ParameterStack.top() ) );
00133     this->m_ParameterStack.pop();
00134     
00135     // Reference functional as we still need if after the optimization when
00136     // calling DoneResolution().
00137     //    nextFunctional->Reference();
00138     
00139     this->m_Optimizer->SetFunctional( nextFunctional );
00140 
00141     int doneResolution = 0;
00142     while ( ! doneResolution && ( irq == CALLBACK_OK )  ) 
00143       {
00144       this->EnterResolution( v, nextFunctional, index, NumResolutionLevels );
00145       
00146       if ( irq == CALLBACK_OK ) 
00147         {
00148         Types::Coordinate effectiveAccuracy = (index == NumResolutionLevels) ? std::max<Types::Coordinate>( this->m_MinStepSize, currentExploration/1024 ) : this->m_MinStepSize;
00149         
00150         irq = this->m_Optimizer->Optimize( *v, currentExploration, effectiveAccuracy );
00151         this->m_Xform->SetParamVector( *v );
00152         }
00153       
00154       doneResolution = this->DoneResolution( v, nextFunctional, index, NumResolutionLevels );
00155       }
00156     
00157     this->m_Optimizer->SetFunctional( Functional::SmartPtr::Null );
00158     
00159     currentExploration *= 0.5;
00160 
00161     Progress::SetProgress( index );
00162 
00163     ++index;
00164     }
00165 
00166   Progress::Done();
00167 
00168   this->OutputResult( v );
00169   this->DoneRegistration( v );
00170   
00171   return irq;
00172 }
00173 
00174 void
00175 ImagePairRegistration::DoneRegistration( const CoordinateVector* v )
00176 {
00177   if ( v )
00178     this->m_Xform->SetParamVector( *v );
00179 }
00180 
00181 void
00182 ImagePairRegistration::EnterResolution
00183 ( CoordinateVector::SmartPtr& v, Functional::SmartPtr& f, 
00184   const int idx, const int total ) 
00185 {
00186   if ( this->m_Callback ) 
00187     {
00188     char comment[128];
00189     snprintf( comment, sizeof( comment ), "Entering resolution level %d out of %d.", idx, total );
00190     this->m_Callback->Comment( comment );
00191     }
00192   
00193   this->m_TimeStartLevel = cmtk::Timers::GetTimeProcess();
00194   this->m_WalltimeStartLevel = cmtk::Timers::GetWalltime();
00195   this->m_ThreadTimeStartLevel = cmtk::Timers::GetTimeThread();
00196   
00197   f->GetParamVector( *v );
00198 }
00199 
00200 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines