template < class TOptimizer >
{
public:
using Self = IterationCallback;
itkTypeMacro( IterationCallback, Superclass );
itkNewMacro( Self );
using OptimizerType = TOptimizer;
void SetOptimizer( OptimizerType * optimizer )
{
m_Optimizer = optimizer;
m_Optimizer->AddObserver( itk::IterationEvent(), this );
}
{
}
{
if( typeid( event ) == typeid( itk::StartEvent ) )
{
std::cout << std::endl << "Position Value";
std::cout << std::endl << std::endl;
}
else if( typeid( event ) == typeid( itk::IterationEvent ) )
{
std::cout << m_Optimizer->GetCurrentIteration() << " ";
std::cout << m_Optimizer->GetValue() << " ";
std::cout << m_Optimizer->GetCurrentPosition() << std::endl;
}
else if( typeid( event ) == typeid( itk::EndEvent ) )
{
std::cout << std::endl << std::endl;
std::cout << "After " << m_Optimizer->GetCurrentIteration();
std::cout << " iterations " << std::endl;
std::cout << "Solution is = " << m_Optimizer->GetCurrentPosition();
std::cout << std::endl;
}
}
protected:
IterationCallback() {};
};
template <typename TFixedImage, typename TMovingSpatialObject>
class SimpleImageToSpatialObjectMetric :
{
public:
using Self = SimpleImageToSpatialObjectMetric;
using Superclass =
using PointListType = std::list<PointType>;
using MovingSpatialObjectType = TMovingSpatialObject;
itkNewMacro(Self);
itkTypeMacro(SimpleImageToSpatialObjectMetric, ImageToSpatialObjectMetric);
static constexpr unsigned int ParametricSpaceDimension = 3;
{
if(!this->m_FixedImage)
{
std::cout << "Please set the image before the moving spatial object" << std::endl;
return;
}
this->m_MovingSpatialObject = object;
m_PointList.clear();
myIteratorType it(this->m_FixedImage,this->m_FixedImage->GetBufferedRegion());
while( !it.IsAtEnd() )
{
this->m_FixedImage->TransformIndexToPhysicalPoint( it.GetIndex(), point );
if(this->m_MovingSpatialObject->IsInside(point,99999))
{
m_PointList.push_back( point );
}
++it;
}
std::cout << "Number of points in the metric = " << static_cast<unsigned long>( m_PointList.size() ) << std::endl;
}
void GetDerivative(
const ParametersType &, DerivativeType & )
const
{
return;
}
MeasureType
GetValue(
const ParametersType & parameters )
const override
{
double value;
this->m_Transform->SetParameters( parameters );
value = 0;
for(PointListType::const_iterator it = m_PointList.begin();
it != m_PointList.end(); ++it)
{
PointType transformedPoint = this->m_Transform->TransformPoint(*it);
if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) )
{
value += this->m_Interpolator->Evaluate( transformedPoint );
}
}
return value;
}
MeasureType & Value, DerivativeType & Derivative ) const override
{
}
private:
PointListType m_PointList;
};
int main( int argc, char *argv[] )
{
if( argc > 1 )
{
std::cerr << "Too many parameters " << std::endl;
std::cerr << "Usage: " << argv[0] << std::endl;
}
EllipseType::Pointer ellipse1 = EllipseType::New();
EllipseType::Pointer ellipse2 = EllipseType::New();
EllipseType::Pointer ellipse3 = EllipseType::New();
ellipse1->SetRadius( 10.0 );
ellipse2->SetRadius( 10.0 );
ellipse3->SetRadius( 10.0 );
EllipseType::TransformType::OffsetType offset;
offset[ 0 ] = 100.0;
offset[ 1 ] = 40.0;
ellipse1->GetObjectToParentTransform()->SetOffset(offset);
ellipse1->ComputeObjectToWorldTransform();
offset[ 0 ] = 40.0;
offset[ 1 ] = 150.0;
ellipse2->GetObjectToParentTransform()->SetOffset(offset);
ellipse2->ComputeObjectToWorldTransform();
offset[ 0 ] = 150.0;
offset[ 1 ] = 150.0;
ellipse3->GetObjectToParentTransform()->SetOffset(offset);
ellipse3->ComputeObjectToWorldTransform();
GroupType::Pointer group = GroupType::New();
group->AddSpatialObject( ellipse1 );
group->AddSpatialObject( ellipse2 );
group->AddSpatialObject( ellipse3 );
using SpatialObjectToImageFilterType =
SpatialObjectToImageFilterType::Pointer imageFilter =
SpatialObjectToImageFilterType::New();
imageFilter->SetInput( group );
size[ 0 ] = 200;
size[ 1 ] = 200;
imageFilter->Update();
using GaussianFilterType =
GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
gaussianFilter->SetInput( imageFilter->GetOutput() );
constexpr double variance = 20;
gaussianFilter->SetVariance(variance);
gaussianFilter->Update();
using RegistrationType =
RegistrationType::Pointer registration = RegistrationType::New();
using MetricType = SimpleImageToSpatialObjectMetric< ImageType, GroupType >;
MetricType::Pointer metric = MetricType::New();
using InterpolatorType =
InterpolatorType::Pointer interpolator = InterpolatorType::New();
OptimizerType::Pointer optimizer = OptimizerType::New();
TransformType::Pointer transform = TransformType::New();
generator->Initialize(12345);
optimizer->SetNormalVariateGenerator( generator );
optimizer->Initialize( 10 );
optimizer->SetMaximumIteration( 400 );
TransformType::ParametersType parametersScale;
parametersScale.set_size(3);
parametersScale[0] = 1000;
for( unsigned int i=1; i<3; i++ )
{
parametersScale[i] = 2;
}
optimizer->SetScales( parametersScale );
using IterationCallbackType = IterationCallback< OptimizerType >;
IterationCallbackType::Pointer callback = IterationCallbackType::New();
callback->SetOptimizer( optimizer );
registration->SetFixedImage( gaussianFilter->GetOutput() );
registration->SetMovingSpatialObject( group );
registration->SetTransform( transform );
registration->SetInterpolator( interpolator );
registration->SetOptimizer( optimizer );
registration->SetMetric( metric );
TransformType::ParametersType initialParameters(
transform->GetNumberOfParameters() );
initialParameters[0] = 0.2;
initialParameters[1] = 7.0;
initialParameters[2] = 6.0;
registration->SetInitialTransformParameters(initialParameters);
std::cout << "Initial Parameters : " << initialParameters << std::endl;
optimizer->MaximizeOn();
try
{
registration->Update();
std::cout << "Optimizer stop condition: "
<< registration->GetOptimizer()->GetStopConditionDescription()
<< std::endl;
}
{
std::cerr << "Exception caught ! " << std::endl;
std::cerr << exp << std::endl;
}
RegistrationType::ParametersType finalParameters
= registration->GetLastTransformParameters();
std::cout << "Final Solution is : " << finalParameters << std::endl;
return EXIT_SUCCESS;
}