#include <iostream>
#include <cstdlib>
namespace
{
unsigned int RmsCounter = 0;
double MaxRmsE[4] = { 0.8, 0.75, 0.4, 0.2 };
}
{
public:
using Self = CommandIterationUpdate;
protected:
CommandIterationUpdate() = default;
using PixelType = short;
using InternalPixelType = float;
using RegistrationFilterType =
InternalImageType,
DisplacementFieldType>;
public:
void
{
std::cout << "Warning: The const Execute method shouldn't be called"
<< std::endl;
}
void
Execute(itk::Object * caller,
const itk::EventObject & event)
override
{
auto * filter = static_cast<RegistrationFilterType *>(caller);
if (!(itk::IterationEvent().CheckEvent(&event)))
{
return;
}
if (filter)
{
filter->SetMaximumRMSError(MaxRmsE[RmsCounter]);
std::cout << filter->GetMetric()
<< " RMS Change: " << filter->GetRMSChange() << std::endl;
std::cout << "Level Tolerance= " << filter->GetMaximumRMSError()
<< std::endl;
}
}
};
{
public:
using Self = CommandResolutionLevelUpdate;
using Pointer = itk::SmartPointer<Self>;
protected:
CommandResolutionLevelUpdate() = default;
public:
void
Execute(itk::Object * caller,
const itk::EventObject & event)
override
{
Execute((
const itk::Object *)caller, event);
}
void
Execute(
const itk::Object *,
const itk::EventObject &)
override
{
std::cout << "----------------------------------" << std::endl;
RmsCounter = RmsCounter + 1;
std::cout << "----------------------------------" << std::endl;
}
};
int
main(int argc, char * argv[])
{
if (argc != 5)
{
std::cerr << "usage: " << std::endl;
std::cerr << argv[0]
<< " fixedImage movingImage registeredImage deformationField"
<< std::endl;
return EXIT_FAILURE;
}
using PixelType = short;
using InternalPixelType = float;
auto targetReader = ReaderType::New();
targetReader->SetFileName(argv[1]);
targetReader->Update();
auto sourceReader = ReaderType::New();
sourceReader->SetFileName(argv[2]);
sourceReader->Update();
auto targetImageCaster = ImageCasterType::New();
auto sourceImageCaster = ImageCasterType::New();
targetImageCaster->SetInput(targetReader->GetOutput());
sourceImageCaster->SetInput(sourceReader->GetOutput());
using MatchingFilterType =
auto matcher = MatchingFilterType::New();
matcher->SetInput(sourceImageCaster->GetOutput());
matcher->SetReferenceImage(targetImageCaster->GetOutput());
matcher->SetNumberOfHistogramLevels(1024);
matcher->SetNumberOfMatchPoints(7);
matcher->ThresholdAtMeanIntensityOn();
using RegistrationFilterType =
InternalImageType,
DisplacementFieldType>;
auto filter = RegistrationFilterType::New();
filter->SetStandardDeviations(1.0);
auto observer = CommandIterationUpdate::New();
filter->AddObserver(itk::IterationEvent(), observer);
using MultiResRegistrationFilterType =
InternalImageType,
DisplacementFieldType>;
auto multires = MultiResRegistrationFilterType::New();
multires->SetRegistrationFilter(filter);
multires->SetNumberOfLevels(4);
multires->SetFixedImage(targetImageCaster->GetOutput());
multires->SetMovingImage(matcher->GetOutput());
unsigned int nIterations[4] = { 40, 40, 32, 32 };
multires->SetNumberOfIterations(nIterations);
auto levelobserver = CommandResolutionLevelUpdate::New();
multires->AddObserver(itk::IterationEvent(), levelobserver);
try
{
multires->Update();
}
{
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
using DisplacementFieldTransformType =
auto displacementTransform = DisplacementFieldTransformType::New();
displacementTransform->SetDisplacementField(multires->GetOutput());
using InterpolatorPrecisionType = double;
ImageType,
InterpolatorPrecisionType,
InternalPixelType>;
using InterpolatorType =
auto warper = WarperType::New();
auto interpolator = InterpolatorType::New();
const ImageType::Pointer targetImage = targetReader->GetOutput();
warper->SetInput(sourceReader->GetOutput());
warper->SetInterpolator(interpolator);
warper->SetOutputSpacing(targetImage->GetSpacing());
warper->SetOutputOrigin(targetImage->GetOrigin());
warper->SetOutputDirection(targetImage->GetDirection());
warper->SetTransform(displacementTransform);
auto writer = WriterType::New();
writer->SetFileName(argv[3]);
writer->SetInput(warper->GetOutput());
try
{
writer->Update();
}
{
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
auto defwriter = DeformationWriterType::New();
defwriter->SetFileName(argv[4]);
defwriter->SetInput(multires->GetOutput());
try
{
defwriter->Update();
}
{
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Casts input pixels to output pixel type.
Superclass for callback/observer methods.
virtual void Execute(Object *caller, const EventObject &event)=0
Abstraction of the Events used to communicating among filters and with GUIs.
Standard exception handling object.
Normalize the grayscale values for a source image by matching the shape of the source image histogram...
Data source that reads image data from a single file.
Writes image data to a single file.
Templated n-dimensional image class.
Linearly interpolate an image at specified positions.
Base class for most ITK classes.
Resample an image via a coordinate transform.
Implements transparent reference counting.
Deformably register two images using the demons algorithm.
A templated class holding a n-Dimensional vector.
BinaryGeneratorImageFilter< TInputImage1, TInputImage2, TOutputImage > Superclass
SmartPointer< Self > Pointer
constexpr unsigned int Dimension
class ITK_FORWARD_EXPORT Command