itkMultiResolutionImageRegistrationMethod

#include "itkMultiResolutionImageRegistrationMethod.h"
#include "itkTranslationTransform.h"
#include "itkMattesMutualInformationImageToImageMetric.h"
#include "itkRegularStepGradientDescentOptimizer.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkResampleImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkCheckerBoardImageFilter.h"

#include "itkSubtractImageFilter.h"
#include "core.h"
#include "itkCommand.h"


template <typename TRegistration>
class RegistrationInterfaceCommand : public itk::Command
{
public:
    using Self = RegistrationInterfaceCommand;
    using Superclass = itk::Command;
    using Pointer = itk::SmartPointer<Self>;
    itkNewMacro(Self);

protected:
    RegistrationInterfaceCommand() = default;

public:
    using RegistrationType = TRegistration;
    using RegistrationPointer = RegistrationType * ;
    using OptimizerType = itk::RegularStepGradientDescentOptimizer;
    using OptimizerPointer = OptimizerType * ;

    void
        Execute(itk::Object * object, const itk::EventObject & event) override
    {
        if (!(itk::IterationEvent().CheckEvent(&event)))
        {
            return;
        }
        auto registration = static_cast<RegistrationPointer>(object);
        if (registration == nullptr)
        {
            return;
        }
        auto optimizer =
            static_cast<OptimizerPointer>(registration->GetModifiableOptimizer());

        std::cout << "-------------------------------------" << std::endl;
        std::cout << "MultiResolution Level : " << registration->GetCurrentLevel()
            << std::endl;
        std::cout << std::endl;

        if (registration->GetCurrentLevel() == 0)
        {
            optimizer->SetMaximumStepLength(16.00);
            optimizer->SetMinimumStepLength(0.01);
        }
        else
        {
            optimizer->SetMaximumStepLength(optimizer->GetMaximumStepLength() /
                4.0);
            optimizer->SetMinimumStepLength(optimizer->GetMinimumStepLength() /
                10.0);
        }
    }

    void
        Execute(const itk::Object *, const itk::EventObject &) override
    {
        return;
    }
};


//  The following section of code implements an observer
//  that will monitor the evolution of the registration process.
//
class CommandIterationUpdate : public itk::Command
{
public:
    using Self = CommandIterationUpdate;
    using Superclass = itk::Command;
    using Pointer = itk::SmartPointer<Self>;
    itkNewMacro(Self);

protected:
    CommandIterationUpdate() = default;

public:
    using OptimizerType = itk::RegularStepGradientDescentOptimizer;
    using OptimizerPointer = const OptimizerType *;

    void
        Execute(itk::Object * caller, const itk::EventObject & event) override
    {
        Execute((const itk::Object *)caller, event);
    }

    void
        Execute(const itk::Object * object, const itk::EventObject & event) override
    {
        auto optimizer = static_cast<OptimizerPointer>(object);
        if (!(itk::IterationEvent().CheckEvent(&event)))
        {
            return;
        }
        std::cout << optimizer->GetCurrentIteration() << "   ";
        std::cout << optimizer->GetValue() << "   ";
        std::cout << optimizer->GetCurrentPosition() << std::endl;
    }
};


int main(int argc, char * argv[])
{


    const unsigned int Dimension = 2;
    typedef unsigned short PixelType;
    typedef itk::Image< PixelType, Dimension > ImageType;
    typedef itk::ImageFileReader< ImageType > ImageReaderType;



    std::string pathfix = "1.png";
    std::string pathmov = "2.png";
    ImageType::Pointer fixedImage, movingImage;
    if (Dimension == 2) {
        ImageReaderType::Pointer fixedImageReader = ImageReaderType::New();
        ImageReaderType::Pointer movingImageReader = ImageReaderType::New();

        fixedImageReader->SetFileName(pathfix);
        movingImageReader->SetFileName(pathmov);
        movingImageReader->Update();
        fixedImageReader->Update();
        fixedImage = fixedImageReader->GetOutput();
        movingImage = movingImageReader->GetOutput();
    }
    else
    {
        //fixedImage = load_dicom(pathfix);
       // movingImage = load_dicom(pathmov);
    }


    using InternalPixelType = float;
    using InternalImageType = itk::Image<InternalPixelType, Dimension>;

    using TransformType = itk::TranslationTransform<double, Dimension>;
    using OptimizerType = itk::RegularStepGradientDescentOptimizer;
    using InterpolatorType = itk::LinearInterpolateImageFunction<InternalImageType, double>;
    using MetricType = itk::MattesMutualInformationImageToImageMetric<InternalImageType, InternalImageType>;
    using RegistrationType = itk::MultiResolutionImageRegistrationMethod<InternalImageType, InternalImageType>;

    using FixedImagePyramidType = itk::MultiResolutionPyramidImageFilter<InternalImageType, InternalImageType>;
    using MovingImagePyramidType = itk::MultiResolutionPyramidImageFilter<InternalImageType, InternalImageType>;


    //  All the components are instantiated using their \code{New()} method
    //  and connected to the registration object as in previous example.
    //
    TransformType::Pointer    transform = TransformType::New();
    OptimizerType::Pointer    optimizer = OptimizerType::New();
    InterpolatorType::Pointer interpolator = InterpolatorType::New();
    RegistrationType::Pointer registration = RegistrationType::New();
    MetricType::Pointer       metric = MetricType::New();

    FixedImagePyramidType::Pointer fixedImagePyramid =
        FixedImagePyramidType::New();
    MovingImagePyramidType::Pointer movingImagePyramid =
        MovingImagePyramidType::New();

    registration->SetOptimizer(optimizer);
    registration->SetTransform(transform);
    registration->SetInterpolator(interpolator);
    registration->SetMetric(metric);
    registration->SetFixedImagePyramid(fixedImagePyramid);
    registration->SetMovingImagePyramid(movingImagePyramid);


    using FixedCastFilterType =
        itk::CastImageFilter<ImageType, InternalImageType>;
    using MovingCastFilterType =
        itk::CastImageFilter<ImageType, InternalImageType>;

    FixedCastFilterType::Pointer  fixedCaster = FixedCastFilterType::New();
    MovingCastFilterType::Pointer movingCaster = MovingCastFilterType::New();

    fixedCaster->SetInput(fixedImage);
    movingCaster->SetInput(movingImage);
    fixedCaster->Update();

    registration->SetFixedImage(fixedCaster->GetOutput());
    registration->SetMovingImage(movingCaster->GetOutput());
    registration->SetFixedImageRegion(fixedCaster->GetOutput()->GetBufferedRegion());


    using ParametersType = RegistrationType::ParametersType;
    ParametersType initialParameters(transform->GetNumberOfParameters());

    initialParameters[0] = 0.0; // Initial offset in mm along X
    initialParameters[1] = 0.0; // Initial offset in mm along Y
    initialParameters[2] = 0.0; // Initial offset in mm along Z

    registration->SetInitialTransformParameters(initialParameters);

    metric->SetNumberOfHistogramBins(128);
    metric->SetNumberOfSpatialSamples(50000);
    metric->SetNumberOfHistogramBins(100);
    // metric->SetNumberOfSpatialSamples(std::stoi(argv[9]));
    metric->ReinitializeSeed(76926294);


    if (argc > 7)
    {
        // Define whether to calculate the metric derivative by explicitly
        // computing the derivatives of the joint PDF with respect to the
        // Transform parameters, or doing it by progressively accumulating
        // contributions from each bin in the joint PDF.
        metric->SetUseExplicitPDFDerivatives(std::stoi(argv[7]));
    }


    optimizer->SetNumberOfIterations(200);
    optimizer->SetRelaxationFactor(0.9);


    // Create the Command observer and register it with the optimizer.
    //
    CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
    optimizer->AddObserver(itk::IterationEvent(), observer);

    using CommandType = RegistrationInterfaceCommand<RegistrationType>;
    CommandType::Pointer command = CommandType::New();
    registration->AddObserver(itk::IterationEvent(), command);


    registration->SetNumberOfLevels(3);

    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;
    }

    ParametersType finalParameters = registration->GetLastTransformParameters();

    double TranslationAlongX = finalParameters[0];
    double TranslationAlongY = finalParameters[1];
    double TranslationAlongZ = finalParameters[2];

    unsigned int numberOfIterations = optimizer->GetCurrentIteration();

    double bestValue = optimizer->GetValue();


    // Print out results
    //
    std::cout << "Result = " << std::endl;
    std::cout << " Translation X = " << TranslationAlongX << std::endl;
    std::cout << " Translation Y = " << TranslationAlongY << std::endl;
    std::cout << " Translation Z = " << TranslationAlongZ << std::endl;
    std::cout << " Iterations    = " << numberOfIterations << std::endl;
    std::cout << " Metric value  = " << bestValue << std::endl;

    using ResampleFilterType =
        itk::ResampleImageFilter<ImageType, ImageType>;

    TransformType::Pointer finalTransform = TransformType::New();

    finalTransform->SetParameters(finalParameters);
    finalTransform->SetFixedParameters(transform->GetFixedParameters());

    PixelType backgroundGrayLevel = 100;
    if (argc > 4)
    {
        backgroundGrayLevel = std::stoi(argv[4]);
    }

    ResampleFilterType::Pointer resample = ResampleFilterType::New();
    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(backgroundGrayLevel);
    resample->SetDefaultPixelValue(0);

    using OutputPixelType = unsigned char;

    using OutputImageType = itk::Image<OutputPixelType, Dimension>;

    using CastFilterType =
        itk::CastImageFilter<ImageType, OutputImageType>;

    using WriterType = itk::ImageFileWriter<OutputImageType>;


    WriterType::Pointer     writer = WriterType::New();
    CastFilterType::Pointer caster = CastFilterType::New();


    writer->SetFileName("resample.png");

    caster->SetInput(resample->GetOutput());
    writer->SetInput(caster->GetOutput());
    writer->Update();

    //typedef itk::SubtractImageFilter <ImageType, ImageType >	mathFilterType;
    //mathFilterType::Pointer mathFilter = mathFilterType::New();
    //mathFilter->SetInput1(input1);
    //mathFilter->SetInput2(input2);
    //mathFilter->Update();
    // Generate checkerboards before and after registration
    //
    using CheckerBoardFilterType = itk::CheckerBoardImageFilter<ImageType>;
    CheckerBoardFilterType::Pointer checker = CheckerBoardFilterType::New();
    checker->SetInput1(fixedImage);
    checker->SetInput2(resample->GetOutput());
    caster->SetInput(checker->GetOutput());
    writer->SetInput(caster->GetOutput());


    // Before registration
    TransformType::Pointer identityTransform = TransformType::New();
    identityTransform->SetIdentity();
    resample->SetTransform(identityTransform);
    writer->SetFileName("before.png");
    writer->Update();

    // After registration
    resample->SetTransform(finalTransform);
    writer->SetFileName("after.png");
    writer->Update();

    return EXIT_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值