[Insight-users] Problems with the convergence using Regular step descendent and Bsplines
Ariel Hernán Curiale
curiale at gmail.com
Sat Sep 29 07:54:59 EDT 2012
Hi,
I'm trying to use a simple metric like MeanSquaresImageToImageMetric with a BsplineInterpolatorImageFunction and RegularStepGradientDescendetOptimizer to solve a particular registration problem but the optimizer can achieve the convergence (any convergence) and the result destroy the image. I used ITK-4.2.0 and ITK-4.1 with the same problem.
In my code and in the past I've used the optimizer of LBFGSBoptimizer but I've never got a stable convergence and change this for the RegularStepGradient (any help with LBFGSoptimizer is accepted too).
If anyone have an example how to use MeansSquares metric, Bspline interpolation and RegularStepGradient with the successfully result please send me the code.
I use the code with following parameters and two image of 200x200:
--numberTrheads 1
--numberLevels 5
--space 16
--metricType SSD
--optimizerType RSGD
--interpolatorType BSI
--maxIt 500
--relaxFact 0.8
--steplength 0.001 2
An extract of my code consern to the RESGOptimizer, SSDMetric and BsplineInterpolator is:
typedef itk::SingleValuedNonLinearOptimizer OptimizerType;//Abstract Optimizer
typedef itk::RegularStepGradientDescentOptimizer RSGDOptimizerType;
typedef itk::ImageToImageMetric<FixedImageType,MovingImageType > MetricType;//Abstract Metric
typedef itk::MeanSquaresImageToImageMetric<FixedImageType,MovingImageType > SSDMetricType;
typedef itk::InterpolateImageFunction< MovingImageType,double> InterpolatorType;
typedef itk::BSplineInterpolateImageFunction<MovingImageType,double, double> BsplineInterpolatorType;
typedef itk::MultiResolutionImageRegistrationMethod<FixedImageType,MovingImageType > MultiRegistrationType;
typedef itk::MultiResolutionPyramidImageFilter<FixedImageType,MovingImageType > FixedImagePyramidType;
typedef itk::MultiResolutionPyramidImageFilter<FixedImageType,MovingImageType > MovingImagePyramidType;
typedef itk::ResampleImageFilter<FixedImageType,MovingImageType > ResampleFilterType;
typename MetricType::Pointer metric = NULL;
typename InterpolatorType::Pointer interpolator = NULL;
typename OptimizerType::Pointer optimizer = NULL;
optimizer = RSGDOptimizerType::New();
metric = SSDMetricType::New();
interpolator = BsplineInterpolatorType::New();
typedef BsplineInterpolatorType * InterpolatorPointer;
InterpolatorPointer int_aux = dynamic_cast< InterpolatorPointer >(interpolator.GetPointer());
int_aux->SetSplineOrder(3);
typename TransformType::Pointer transform = TransformType::New();
typename MultiRegistrationType::Pointer multiregistration = MultiRegistrationType::New();
multiregistration->SetNumberOfThreads(this->m_NumberOfThreads);
typename FixedImagePyramidType::Pointer fixedImagePyramid = FixedImagePyramidType::New();
typename MovingImagePyramidType::Pointer movingImagePyramid = MovingImagePyramidType::New();
typename FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion();
multiregistration->SetMetric( metrics[i] );
multiregistration->SetOptimizer( optimizer );
multiregistration->SetInterpolator( interpolator );
multiregistration->SetTransform( transform );
// Setup the registration
multiregistration->SetFixedImagePyramid( fixedImagePyramid );
multiregistration->SetMovingImagePyramid( movingImagePyramid );
multiregistration->SetFixedImage( fixedImage );
multiregistration->SetMovingImage( movingImage);
multiregistration->SetFixedImageRegion( fixedRegion );
// Here we define the parameters of the BSplineDeformableTransform grid. We
// arbitrarily decide to use a grid with $5 \times 5$ nodes within the image.
// The reader should note that the BSpline computation requires a
// finite support region ( 1 grid node at the lower borders and 2
// grid nodes at upper borders). Therefore in this example, we set
// the grid size to be $8 \times 8$ and place the grid origin such that
// grid node (1,1) coincides with the first pixel in the fixed image.
unsigned int numberOfGridNodesInOneDimension = 1 + fixedImage->GetLargestPossibleRegion().GetSize()[0] / space;
#if ITK_VERSION_MAJOR < 4
typename TransformType::RegionType bsplineRegion;
typename TransformType::RegionType::SizeType gridSizeOnImage;
typename TransformType::RegionType::SizeType gridBorderSize;
typename TransformType::RegionType::SizeType totalGridSize;
gridSizeOnImage.Fill( numberOfGridNodesInOneDimension );
gridBorderSize.Fill( SplineOrder ); // Border for spline order = 3 ( 1 lower, 2 upper )
totalGridSize = gridSizeOnImage + gridBorderSize;
bsplineRegion.SetSize( totalGridSize );
typename TransformType::SpacingType spacing = fixedImage->GetSpacing();
typename TransformType::OriginType origin = fixedImage->GetOrigin();
typename FixedImageType::SizeType fixedImageSize = fixedRegion.GetSize();
for(unsigned int r=0; r<Dimension; r++)
{
spacing[r] *= static_cast<double>(fixedImageSize[r] - 1) /
static_cast<double>(gridSizeOnImage[r] - 1);
}
typename FixedImageType::DirectionType gridDirection = fixedImage->GetDirection();
typename TransformType::SpacingType gridOriginOffset = gridDirection * spacing;
typename TransformType::OriginType gridOrigin = origin - gridOriginOffset;
transform->SetGridSpacing( spacing );
transform->SetGridOrigin( gridOrigin );
transform->SetGridRegion( bsplineRegion );
transform->SetGridDirection( gridDirection );
#else
typename TransformType::PhysicalDimensionsType fixedPhysicalDimensions;
typename TransformType::MeshSizeType meshSize;
typename TransformType::OriginType fixedOrigin;
for( unsigned int k=0; k< Dimension; k++ )
{
fixedOrigin = fixedImage->GetOrigin()[k];
fixedPhysicalDimensions[k] = fixedImage->GetSpacing()[k] *
static_cast<double>(
fixedImage->GetLargestPossibleRegion().GetSize()[k] - 1 );
}
meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder );
transform->SetTransformDomainOrigin( fixedOrigin );
transform->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
transform->SetTransformDomainMeshSize( meshSize );
transform->SetTransformDomainDirection( fixedImage->GetDirection() );
#endif
const unsigned int numberOfParameters = transform->GetNumberOfParameters();
typename TransformType::ParametersType parameters( numberOfParameters );
parameters.Fill( 0.0 );
transform->SetParameters( parameters );
// We now pass the parameters of the current transform as the initial
// parameters to be used when the registration process starts.
multiregistration->SetInitialTransformParameters( transform->GetParameters() );
multiregistration->SetNumberOfLevels( numberLevels );
// Set the parameters of the RegularStepGradientDescentOptimizer Optimizer.
typedef RSGDOptimizerType * OptimizerPointer;
OptimizerPointer opt = dynamic_cast< OptimizerPointer >(optimizer.GetPointer());
opt->SetNumberOfIterations( maxIt );
opt->SetRelaxationFactor( relaxFact );
opt->SetMaximumStepLength( steplength[1] );
opt->SetMinimumStepLength( steplength[0] );
std::cout << "Initial Parameters = " << std::endl;
std::cout << transform->GetParameters() << std::endl;
CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
optimizer->AddObserver( itk::IterationEvent(), observer );
std::string metric_name = metric->GetNameOfClass();
std::cout << std::endl << "Starting " <<metric_name<<" Registration" <<std::endl;
multiregistration->StartRegistration();
std::cout << "Optimizer stop condition = "
<< multiregistration->GetOptimizer()->GetStopConditionDescription()
<< std::endl;
std::string prefix = "SSD";
// the parameters type are the same for both optimizer.
typename RSGDOptimizerType::ParametersType finalParameters;
finalParameters = multiregistration->GetLastTransformParameters();
std::cout << "Last Transform Parameters" << std::endl;
std::cout << finalParameters << std::endl;
unsigned int numberOfIterations = 0;
double bestValue = 0;
typedef RSGDOptimizerType * OptimizerPointer;
OptimizerPointer opt = dynamic_cast< OptimizerPointer >(optimizer.GetPointer());
numberOfIterations = opt->GetCurrentIteration();
bestValue = opt->GetValue();
// Print out results
//
std::cout << "Result: " << std::endl;
std::cout << " Iterations = " << numberOfIterations << std::endl;
std::cout << " Metric value = " << bestValue << std::endl;
transform->SetParameters( finalParameters );
typename ResampleFilterType::Pointer resample = ResampleFilterType::New();
resample->SetTransform( transform );
resample->SetInput( movingImage );
resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
resample->SetOutputOrigin( fixedImage->GetOrigin() );
resample->SetOutputSpacing( fixedImage->GetSpacing() );
resample->SetOutputDirection( fixedImage->GetDirection() );
resample->SetDefaultPixelValue( 100 );
resample->Update();
typedef itk::CastImageFilter<FixedImageType,OutputImageType > CastFilterType;
typename OutputWriterType::Pointer writer = OutputWriterType::New();
typename CastFilterType::Pointer caster = CastFilterType::New();
if(salidaResample)
{
writer->SetFileName( (prefix+"_"+filenameResample).c_str() );
caster->SetInput( resample->GetOutput() );
writer->SetInput( caster->GetOutput() );
try
{
writer->Update();
}
catch( itk::ExceptionObject & err )
{
std::cerr << "ExceptionObject caught !" << std::endl;
std::cerr << err << std::endl;
return EXIT_FAILURE;
}
}
Please any help will be useful
Thanks,
__________________________________
| Ariel Hernán Curiale Ph.D Student
| ETSI Telecomunicación
| Universidad de Valladolid
| Campus Miguel Delibes
| 47011 Valladolid, Spain
| Phone: 983-423000 ext. 5590
| Web: www.curiale.com.ar
|_________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20120929/19a7a994/attachment-0001.htm>
More information about the Insight-users
mailing list