/*========================================================================= Program: vtkINRIA3D Module: $Id: itkAffineRegistrationMethod.cxx 1 2008-01-22 19:01:33Z ntoussaint $ Language: C++ Author: $Author: ntoussaint $ Date: $Date: 2008-01-22 20:01:33 +0100 (Tue, 22 Jan 2008) $ Version: $Revision: 1 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. See Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkAffineRegistrationMethod_cxx #define _itkAffineRegistrationMethod_cxx #include "itkAffineRegistrationMethod.h" #include "itkAffineTransform.h" #include "itkTranslationTransform.h" namespace itk { /* * Constructor */ template AffineRegistrationMethod ::AffineRegistrationMethod() { typename LinearInterpolatorType::Pointer m_LinearInterpolator = LinearInterpolatorType::New(); this->Parameters.Metric = NULL; //bad this->Parameters.Interpolator = m_LinearInterpolator; this->Parameters.OptimizationScale = 1.0/10000.0; this->Parameters.NumberOfLevels = 3; this->Parameters.NumberOfIterationList = new unsigned int[100]; for (unsigned int i=0; i<100; i++) this->Parameters.NumberOfIterationList[i] = 10; this->SetName ("Affine Automatic"); m_AutoPyramidSchedule = 1; ScheduleType nullschedule (0,0); m_Schedule = nullschedule; } /* * Constructor */ template void AffineRegistrationMethod ::Initialize() { this->Superclass::Initialize (); } /* * PrintSelf */ template void AffineRegistrationMethod ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); } /* * Generate Data */ template void AffineRegistrationMethod ::GenerateData() { typename AffineTransformType::Pointer transform = AffineTransformType::New(); transform->SetIdentity(); typename OptimizerType::Pointer m_Optimizer = OptimizerType::New(); typename RegistrationType::Pointer m_Registration = RegistrationType::New(); typename CommandType::Pointer m_Callback = CommandType::New(); typename ImagePyramidType::Pointer m_FixedImagePyramid = ImagePyramidType::New(); typename ImagePyramidType::Pointer m_MovingImagePyramid = ImagePyramidType::New(); typename MutualInformationMetricType::Pointer m_MutualInformationMetric = MutualInformationMetricType::New(); m_MutualInformationMetric->SetNumberOfHistogramBins( 20 ); int samples = this->roundint(1.0/this->Parameters.OptimizationScale); m_MutualInformationMetric->SetNumberOfSpatialSamples( samples ); m_MutualInformationMetric->ReinitializeSeed( 76926294 ); if (m_AutoPyramidSchedule) { this->SetSchedule (this->GetOptimumSchedule(8, this->Parameters.NumberOfLevels)); } // m_FixedImagePyramid->SetSchedule (this->GetSchedule()); // m_MovingImagePyramid->SetSchedule (this->GetSchedule()); this->Parameters.Metric = m_MutualInformationMetric; // set registration parameters m_Optimizer->SetNumberOfIterations( this->Parameters.NumberOfIterationList[0]); m_Optimizer->MinimizeOn(); unsigned int N = ImageType::ImageDimension * (ImageType::ImageDimension + 1); OptimizerScalesType optimizerScales( N ); for (unsigned int i = 0; i < N - ImageType::ImageDimension; i++) optimizerScales[i] = 1.0; for (unsigned int i = N - ImageType::ImageDimension; i < N; i++) optimizerScales[i] = this->Parameters.OptimizationScale; m_Optimizer->SetScales (optimizerScales); m_Optimizer->SetMaximumStepLength (4); m_Registration->SetMetric( this->Parameters.Metric ); m_Registration->SetOptimizer( m_Optimizer ); m_Registration->SetInterpolator( this->Parameters.Interpolator ); m_Registration->SetFixedImagePyramid (m_FixedImagePyramid); m_Registration->SetMovingImagePyramid (m_MovingImagePyramid); m_Registration->SetSchedules (this->GetSchedule(), this->GetSchedule()); // m_Registration->SetNumberOfLevels( this->Parameters.NumberOfLevels ); m_Callback->SetItkObjectToWatch (this); m_Optimizer->AddObserver(itk::IterationEvent(), m_Callback); m_Registration->AddObserver(itk::IterationEvent(), m_Callback); m_Registration->SetTransform( transform ); m_Registration->SetInitialTransformParameters (transform->GetParameters()); m_Registration->SetFixedImage( this->GetFixedImage() ); m_Registration->SetMovingImage( this->GetMovingImage() ); m_Registration->SetFixedImageRegion( this->GetFixedImage()->GetLargestPossibleRegion() ); std::vector iterations; for (unsigned int i=0; iGetNumberOfLevels(); i++) { iterations.push_back (this->Parameters.NumberOfIterationList[i]); } m_Callback->SetNumberOfIterations (iterations); m_Registration->UpdateProgress (0); this->UpdateProgress(0.0); try { m_Registration->Update(); } catch( itk::ExceptionObject & e ) { this->UpdateProgress(1.0); std::cerr << e << std::endl; throw itk::ExceptionObject(__FILE__,__LINE__,"Error in AffineRegistrationMethod::GenerateData()"); } this->UpdateProgress(1.0); this->SetTransform (transform); } /* * metric parameter */ template void AffineRegistrationMethod ::SetRegistrationMetric (MetricPointerType metric) { this->Parameters.Metric = metric; } /* * interpolation parameter */ template void AffineRegistrationMethod ::SetRegistrationInterpolator (InterpolatorPointerType interpolator) { this->Parameters.Interpolator = interpolator; } /* * levels parameter */ template unsigned int AffineRegistrationMethod ::GetRegistrationNumberOfLevels (void) const { return this->Parameters.NumberOfLevels; } /* * levels parameter */ template void AffineRegistrationMethod ::SetRegistrationNumberOfLevels (unsigned int n) { this->Parameters.NumberOfLevels = n; } /* * iterations parameter */ template const unsigned int* AffineRegistrationMethod ::GetRegistrationNumberOfIterationsList (void) const { return this->Parameters.NumberOfIterationList; } /* * iterations parameter */ template void AffineRegistrationMethod ::SetRegistrationNumberOfIterationsList (unsigned int* n_list) { for (unsigned int i=0; iParameters.NumberOfLevels; i++) { this->Parameters.NumberOfIterationList[i] = n_list[i]; } } /* * translation parameter */ template double AffineRegistrationMethod ::GetTranslationScale (void) const { return this->Parameters.OptimizationScale; } /* * translation parameter */ template void AffineRegistrationMethod ::SetTranslationScale (double scale) { this->Parameters.OptimizationScale = scale; } /* * schedule */ template void AffineRegistrationMethod ::SetSchedule (ScheduleType schedule) { m_AutoPyramidSchedule = 0; m_Schedule = schedule; this->SetRegistrationNumberOfLevels (schedule.rows()); } } // end namespace itk #endif