cmtkVoxelRegistration.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //  Copyright 2004-2010 SRI International
00005 //
00006 //  This file is part of the Computational Morphometry Toolkit.
00007 //
00008 //  http://www.nitrc.org/projects/cmtk/
00009 //
00010 //  The Computational Morphometry Toolkit is free software: you can
00011 //  redistribute it and/or modify it under the terms of the GNU General Public
00012 //  License as published by the Free Software Foundation, either version 3 of
00013 //  the License, or (at your option) any later version.
00014 //
00015 //  The Computational Morphometry Toolkit is distributed in the hope that it
00016 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00017 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 //  GNU General Public License for more details.
00019 //
00020 //  You should have received a copy of the GNU General Public License along
00021 //  with the Computational Morphometry Toolkit.  If not, see
00022 //  <http://www.gnu.org/licenses/>.
00023 //
00024 //  $Revision: 2398 $
00025 //
00026 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00027 //
00028 //  $LastChangedBy: torstenrohlfing $
00029 //
00030 */
00031 
00032 #include <Registration/cmtkVoxelRegistration.h>
00033 
00034 #include <Base/cmtkVector.h>
00035 #include <Base/cmtkXform.h>
00036 #include <Base/cmtkAffineXform.h>
00037 
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 VoxelRegistration::VoxelRegistration () 
00055   : m_Metric( 0 ),
00056     m_DeltaFThreshold( 0.0 ),
00057     m_PreprocessorRef( "Reference", "ref" ),
00058     m_PreprocessorFlt( "Floating", "flt" ),
00059     m_InitialTransformation( NULL ),
00060     m_InitialXformIsInverse( false ),
00061     m_Xform( NULL ),
00062     m_Optimizer( NULL )
00063 { 
00064   this->m_Callback = RegistrationCallback::SmartPtr( new RegistrationCallback() );
00065   this->m_Protocol = NULL; 
00066 
00067   this->m_Exploration = -1;
00068   this->m_Accuracy = -1;
00069   this->m_Sampling = -1;
00070   this->CoarsestResolution = -1;
00071   this->m_UseOriginalData = true;
00072 
00073   this->m_Algorithm = 0;
00074   UseMaxNorm = true;
00075   OptimizerStepFactor = 0.5;
00076 
00077 }
00078 
00079 VoxelRegistration::~VoxelRegistration () 
00080 {
00081   free( this->m_Protocol );
00082 }
00083 
00084 CallbackResult
00085 VoxelRegistration::InitRegistration ()
00086 {
00087   if ( this->m_Sampling <= 0 )
00088     this->m_Sampling = std::max( this->m_Volume_1->GetMaxDelta(), this->m_Volume_2->GetMaxDelta() );
00089   
00090   if ( this->m_Exploration <= 0 )
00091     this->m_Exploration = 8.0 * this->m_Sampling;
00092   
00093   if ( this->m_Accuracy <= 0 )
00094     this->m_Accuracy = this->m_Sampling / 128;
00095   
00096   TimeStartLevel = TimeStartRegistration = cmtk::Timers::GetTimeProcess();
00097   WalltimeStartLevel = WalltimeStartRegistration = cmtk::Timers::GetWalltime();
00098   ThreadTimeStartLevel = ThreadTimeStartRegistration = cmtk::Timers::GetTimeThread();
00099 
00100   return CALLBACK_OK;
00101 }
00102 
00103 CallbackResult
00104 VoxelRegistration::Register ()
00105 {
00106   CallbackResult irq = this->InitRegistration();
00107   if ( irq != CALLBACK_OK ) 
00108     {
00109     this->DoneRegistration();
00110     return irq;
00111     }
00112 
00113   this->m_Optimizer->SetDeltaFThreshold( this->m_DeltaFThreshold );
00114   
00115   Types::Coordinate currentExploration = this->m_Exploration;
00116   CoordinateVector::SmartPtr v( new CoordinateVector() );
00117   int NumResolutionLevels = FunctionalStack.size();
00118 
00119   Progress::Begin( 0, NumResolutionLevels, 1, "Multi-level Registration" );
00120 
00121   int index = 1;
00122   while ( ! FunctionalStack.empty() && ( irq == CALLBACK_OK ) ) 
00123     {
00124     Functional::SmartPtr nextFunctional = FunctionalStack.top();
00125     FunctionalStack.pop();
00126     
00127     this->m_Optimizer->SetFunctional( nextFunctional );
00128 
00129     int doneResolution = 0;
00130     while ( ! doneResolution && ( irq == CALLBACK_OK )  ) 
00131       {
00132       this->EnterResolution( v, nextFunctional, index, NumResolutionLevels );
00133       
00134       if ( irq == CALLBACK_OK ) 
00135         {
00136         Types::Coordinate effectiveAccuracy = (index == NumResolutionLevels) ? std::max<Types::Coordinate>( this->m_Accuracy, currentExploration/1024 ) : this->m_Accuracy;
00137         
00138         irq = this->m_Optimizer->Optimize( *v, currentExploration, effectiveAccuracy );
00139         this->m_Xform->SetParamVector( *v );
00140         }
00141       
00142       doneResolution = this->DoneResolution( v, nextFunctional, index, NumResolutionLevels );
00143       }
00144     
00145     this->m_Optimizer->SetFunctional( Functional::SmartPtr::Null );
00146     
00147     currentExploration *= 0.5;
00148 
00149     Progress::SetProgress( index );
00150 
00151     ++index;
00152     }
00153 
00154   Progress::Done();
00155 
00156   this->OutputResult( v );
00157   this->DoneRegistration( v );
00158   
00159   return irq;
00160 }
00161 
00162 void
00163 VoxelRegistration::DoneRegistration( const CoordinateVector* v )
00164 {
00165   if ( v )
00166     this->m_Xform->SetParamVector( *v );
00167 }
00168 
00169 void
00170 VoxelRegistration::EnterResolution
00171 ( CoordinateVector::SmartPtr& v, Functional::SmartPtr& f, 
00172   const int idx, const int total ) 
00173 {
00174   if ( this->m_Callback ) 
00175     {
00176     char comment[128];
00177     snprintf( comment, sizeof( comment ), "Entering resolution level %d out of %d.", idx, total );
00178     this->m_Callback->Comment( comment );
00179     }
00180   
00181   TimeStartLevel = cmtk::Timers::GetTimeProcess();
00182   WalltimeStartLevel = cmtk::Timers::GetWalltime();
00183   ThreadTimeStartLevel = cmtk::Timers::GetTimeThread();
00184   
00185   f->GetParamVector( *v );
00186 }
00187 
00188 } // namespace cmtk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines