#include "vtkVersion.h"
#include "vtkSmartPointer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageActor.h"
#include "vtkImageMapper3D.h"
using PixelType = unsigned char;
template <typename TImage>
{
public:
using Self = IterationUpdate;
protected:
IterationUpdate() = default;
public:
using OptimizerPointer = const OptimizerType *;
void
{
}
void
{
auto optimizer = static_cast<OptimizerPointer>(object);
if (!(itk::IterationEvent().CheckEvent(&event)))
{
return;
}
m_Transform->SetParameters(optimizer->GetCurrentPosition());
m_Filter->Update();
m_Connector->SetInput(m_Filter->GetOutput());
m_Connector->Update();
#if VTK_MAJOR_VERSION <= 5
m_ImageActor->SetInput(m_Connector->GetOutput());
#else
m_Connector->Update();
m_ImageActor->GetMapper()->SetInputData(m_Connector->GetOutput());
#endif
m_RenderWindow->Render();
}
void
{
m_Transform = transform;
}
void
{
m_Filter = filter;
}
void
{
m_Connector = connector;
}
void
SetImageActor(vtkImageActor * actor)
{
m_ImageActor = actor;
}
void
SetRenderWindow(vtkRenderWindow * renderWindow)
{
m_RenderWindow = renderWindow;
}
vtkImageActor * m_ImageActor;
vtkRenderWindow * m_RenderWindow;
};
int
main(int argc, char * argv[])
{
if (argc > 2)
{
fixedImage = itk::ReadImage<InputImageType>(argv[1]);
movingImage = itk::ReadImage<InputImageType>(argv[2]);
}
else
{
std::cout << "Usage: " << argv[0] << " fixedImage movingImage" << std::endl;
return EXIT_FAILURE;
}
fixedNormalizer->SetInput(fixedImage);
movingNormalizer->SetInput(movingImage);
fixedSmoother->SetVariance(3.0);
fixedSmoother->SetInput(fixedNormalizer->GetOutput());
movingSmoother->SetVariance(3.0);
movingSmoother->SetInput(movingNormalizer->GetOutput());
initializer->SetFixedImage(fixedImage);
initializer->SetMovingImage(movingImage);
initializer->SetTransform(transform);
transform->SetIdentity();
initializer->GeometryOn();
initializer->InitializeTransform();
registration->SetOptimizer(optimizer);
registration->SetTransform(transform);
registration->SetInterpolator(interpolator);
registration->SetMetric(metric);
registration->SetFixedImage(fixedSmoother->GetOutput());
registration->SetMovingImage(movingSmoother->GetOutput());
fixedNormalizer->Update();
registration->SetFixedImageRegion(fixedImageRegion);
using ParametersType = RegistrationType::ParametersType;
ParametersType initialParameters(transform->GetNumberOfParameters());
initialParameters[0] = 1.0;
initialParameters[1] = 0.0;
initialParameters[2] = 0.0;
initialParameters[3] = 1.0;
initialParameters[4] = 0.0;
initialParameters[5] = 0.0;
registration->SetInitialTransformParameters(initialParameters);
const auto numberOfSamples = static_cast<unsigned int>(numberOfPixels * 0.05);
metric->SetNumberOfHistogramBins(26);
metric->SetNumberOfSpatialSamples(numberOfSamples);
optimizer->MinimizeOn();
optimizer->SetMaximumStepLength(0.500);
optimizer->SetMinimumStepLength(0.001);
optimizer->SetNumberOfIterations(1000);
const unsigned int numberOfParameters = transform->GetNumberOfParameters();
using OptimizerScalesType = OptimizerType::ScalesType;
OptimizerScalesType optimizerScales(numberOfParameters);
double translationScale = 1.0 / 1000.0;
optimizerScales[0] = 1.0;
optimizerScales[1] = 1.0;
optimizerScales[2] = 1.0;
optimizerScales[3] = 1.0;
optimizerScales[4] = translationScale;
optimizerScales[5] = translationScale;
optimizer->SetScales(optimizerScales);
finalTransform->SetParameters(initialParameters);
finalTransform->SetFixedParameters(transform->GetFixedParameters());
resample->SetTransform(finalTransform);
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();
CheckerBoardFilterType::PatternArrayType pattern;
pattern[0] = 4;
pattern[1] = 4;
checkerboard->SetCheckerPattern(pattern);
checkerboard->SetInput1(fixedImage);
checkerboard->SetInput2(resample->GetOutput());
bool flipAxes[3] = { false, true, false };
flip->SetFlipAxes(flipAxes);
flip->SetInput(checkerboard->GetOutput());
flip->Update();
connector->SetInput(flip->GetOutput());
#if VTK_MAJOR_VERSION <= 5
actor->SetInput(connector->GetOutput());
#else
connector->Update();
actor->GetMapper()->SetInputData(connector->GetOutput());
#endif
renderer->SetBackground(.4, .5, .6);
renderer->AddActor(actor);
renderWindow->SetSize(640, 480);
;
renderWindow->AddRenderer(renderer);
renderWindow->Render();
optimizer->AddObserver(itk::IterationEvent(), observer);
observer->SetTransform(finalTransform);
observer->SetFilter(flip);
observer->SetConnector(connector);
observer->SetImageActor(actor);
observer->SetRenderWindow(renderWindow);
try
{
registration->Update();
std::cout << "Optimizer stop condition: " << registration->GetOptimizer()->GetStopConditionDescription()
<< std::endl;
}
catch (const itk::ExceptionObject & err)
{
std::cout << "ExceptionObject caught !" << std::endl;
std::cout << err << std::endl;
return EXIT_FAILURE;
}
std::cout << "Final Transform: " << finalTransform << std::endl;
ParametersType finalParameters = registration->GetLastTransformParameters();
std::cout << "Final Parameters: " << finalParameters << std::endl;
unsigned int numberOfIterations = optimizer->GetCurrentIteration();
double bestValue = optimizer->GetValue();
std::cout << std::endl;
std::cout << "Result = " << std::endl;
std::cout << " Iterations = " << numberOfIterations << std::endl;
std::cout << " Metric value = " << bestValue << std::endl;
std::cout << " Numb. Samples = " << numberOfSamples << std::endl;
interactor->SetInteractorStyle(style);
interactor->SetRenderWindow(renderWindow);
interactor->Start();
return EXIT_SUCCESS;
}