[Insight-users] Model-Based-Registration results with one ellipse (code included)

Gunther Sudra Gunther.Sudra at web.de
Thu, 19 Feb 2004 22:33:20 +0100


Hi,

at first: thank you Luis, for your prompt answers. Although I understand now the figure, I have still problems with my example:

All questions refer to my added example-code which is a smaller version of the ITKSoftwareGuide example Model-Based-Registration, using only one ellipse instead of three

1. Question: I found out that I get very good results when I feed the optimizer with the same synthetic image and incorrect small initial values, e.g. [0,10,10]. But when I move the ellipse in the synthetic image by 10 in x-direction (variable x), and 10 in y-direction (variable y) and set the initial values to [0,0,0] I get bad results. What am I doing wrong? What is the difference?

2. Question: A strong increase of the optimizer parameters (optimizer->Initialize( 10000 ) and 
optimizer->SetMaximumIteration( 10000 ) seem to have almost no effect on the quality of the result.

3. Thank you for answering all these beginner-questions.



My code:

typedef itk::GroupSpatialObject< 2 > GroupType;
typedef itk::EllipseSpatialObject< 2 > EllipseType;

typedef itk::Image< float, 2 > ImageType;

EllipseType::Pointer ellipse1 = EllipseType::New();

double radius[2] = {10.0, 15.0};
ellipse1->SetRadius( radius );

EllipseType::TransformType::OffsetType offset;
offset[ 0 ] = 100.0;
offset[ 1 ] = 40.0;

ellipse1->GetObjectToParentTransform()->SetOffset(offset);
ellipse1->ComputeObjectToWorldTransform();

GroupType::Pointer group = GroupType::New();
group->AddSpatialObject( ellipse1 );


typedef itk::SpatialObjectToImageFilter< GroupType, ImageType > 
SpatialObjectToImageFilterType;

SpatialObjectToImageFilterType::Pointer imageFilter = 
SpatialObjectToImageFilterType::New();

imageFilter->SetInput( group );

ImageType::SizeType size;
size[ 0 ] = 200;
size[ 1 ] = 200;
imageFilter->SetSize( size );

imageFilter->Update();

typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType > 
GaussianFilterType;
GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();

gaussianFilter->SetInput( imageFilter->GetOutput() );

const double variance = 20;
gaussianFilter->SetVariance(variance);
gaussianFilter->Update();

typedef itk::ImageToSpatialObjectRegistrationMethod< ImageType, GroupType >
RegistrationType;
RegistrationType::Pointer registration = RegistrationType::New();

typedef SimpleImageToSpatialObjectMetric< ImageType, GroupType > MetricType;
MetricType::Pointer metric = MetricType::New();

typedef itk::LinearInterpolateImageFunction< ImageType, double > 
InterpolatorType;
InterpolatorType::Pointer interpolator = InterpolatorType::New();

typedef itk::OnePlusOneEvolutionaryOptimizer OptimizerType;
OptimizerType::Pointer optimizer = OptimizerType::New();

typedef itk::Euler2DTransform<> TransformType;
TransformType::Pointer transform = TransformType::New();

itk::Statistics::NormalVariateGenerator::Pointer generator 
= itk::Statistics::NormalVariateGenerator::New();

generator->Initialize(12345);

optimizer->SetNormalVariateGenerator( generator );

//100
optimizer->Initialize( 100 );

//10000
optimizer->SetMaximumIteration( 1000 );

TransformType::ParametersType parametersScale;
parametersScale.set_size(3);
parametersScale[0] = 1000; // angle scale

for( unsigned int i=1; i<3; i++ )
{
parametersScale[i] = 2; // offset scale
}
optimizer->SetScales( parametersScale );

typedef IterationCallback< OptimizerType > IterationCallbackType;
IterationCallbackType::Pointer callback = IterationCallbackType::New();
callback->SetOptimizer( optimizer );


//////////////////////////////////////////////////////////////////////////
// model with same radius which is translated by x and y
//////////////////////////////////////////////////////////////////////////
int x = 10;
int y = 10;


EllipseType::Pointer ellipse_model = EllipseType::New();

ellipse_model->SetRadius( radius );

offset[ 0 ] = 100.0 + x;
offset[ 1 ] = 40.0 + y;

ellipse_model->GetObjectToParentTransform()->SetOffset(offset);
ellipse_model->ComputeObjectToWorldTransform();


GroupType::Pointer group_model= GroupType::New();
group_model->AddSpatialObject( ellipse_model );


registration->SetFixedImage( gaussianFilter->GetOutput() );
registration->SetMovingSpatialObject( group_model );
registration->SetTransform( transform );
registration->SetInterpolator( interpolator );
registration->SetOptimizer( optimizer );
registration->SetMetric( metric );

TransformType::ParametersType initialParameters( 
transform->GetNumberOfParameters() );

initialParameters[0] = 0.0; // Angle
initialParameters[1] = 0.0; // Offset X
initialParameters[2] = 0.0; // Offset Y 
registration->SetInitialTransformParameters(initialParameters);

std::cout << "Initial Parameters : " << initialParameters << std::endl;

optimizer->MaximizeOn();

try 
{
registration->StartRegistration();
}
catch( itk::ExceptionObject & exp ) 
{
std::cerr << "Exception caught ! " << std::endl;
std::cerr << exp << std::endl;
}

RegistrationType::ParametersType finalParameters 
= registration->GetLastTransformParameters();

std::cout << "Final Solution is : " << finalParameters << std::endl;


itk::Array mPositionArray;
mPositionArray = registration->GetLastTransformParameters();

double angle = mPositionArray[0];
TransformType::MatrixType matrix;
matrix[0][0] = cos(angle); matrix[0][1] = -sin(angle);
matrix[1][0] = sin(angle); matrix[1][1] = cos(angle);

offset[ 0 ] = 100 - mPositionArray[1];
offset[ 1 ] = 40 - mPositionArray[2];
ellipse_model->GetObjectToParentTransform()->SetOffset(offset);
ellipse_model->GetObjectToParentTransform()->SetMatrix(matrix);
ellipse_model->ComputeObjectToWorldTransform();

imageFilter->SetInput( group_model );
imageFilter->Update();

______________________________________________________________________________
Ein Grund zum Feiern: Die PC Praxis ermittelt zwischen 10 grossen
Mailprovidern WEB.DE FreeMail als Testsieger http://f.web.de/?mc=021190