Hello All,
I have 21 3D MR brain images… as a format
…/MPRAGE_copy/KKI-2009-01-MPRAGE.nii for one image in MPRAGE_copy folder…
Out of the 21 images I would like to use the first image as fixed image and register the rest of the 20 images on that reference fixed image.
I want to write the code in self-dependent where I do not have to provide any input.
I am using GCC/6.0.0 compiler…
have four folders:
- ITKAffReg3: where the code will be named ITKAffReg3.cxx and CMakeLists.txt which will contain all dependency and executable information.
- ITKAffReg3-build: here I will run ccmake and make and contain all the binaries.
- MPRAGE_copy: where all the 21 .nii images are present.
- AffineFiles: where all affine registered 20 files will be saved.
I have written a code but the error I am getting is too big to print:
I will share the code instead:
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkAffineTransform.h"
#include "itkImageRegistrationMethod.h"
#include "itkResampleImageFilter.h"
#include "itkMeanSquaresImageToImageMetric.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkRegularStepGradientDescentOptimizer.h"
#include <string>
/*
class OptimizationObserver : public itk::Command
{
public:
typedef OptimizationObserver Self ;
typedef itk::Command Superclass ;
typedef itk::SmartPointer < Self > Pointer ;
itkNewMacro ( Self ) ;
typedef itk::RegularStepGradientDescentOptimizer OptimizerType ;
typedef const OptimizerType * OptimizerPointerType ;
void Execute (itk::Object *caller, const itk::EventObject &event)
{
Execute ( (const itk::Object *) caller, event ) ;
}
void Execute (const itk::Object *caller, const itk::EventObject &event)
{
OptimizerPointerType optimizer = dynamic_cast < OptimizerPointerType > ( caller ) ;
std::cout << "OptimizerObserver" << optimizer->GetCurrentIteration() << " " << optimizer->GetValue() << std::end\
l ;
}
protected:
OptimizationObserver() {} ;
};
class RegistrationObserver : public itk::Command
{
public:
typedef RegistrationObserver Self ;
typedef itk::Command Superclass ;
typedef itk::SmartPointer < Self > Pointer ;
itkNewMacro ( Self ) ;
typedef itk::RegularStepGradientDescentOptimizer OptimizerType ;
typedef OptimizerType * OptimizerPointerType ;
typedef itk::MultiResolutionImageRegistrationMethod < ImageType, ImageType > RegistrationWrapperType ; // fixed, \
moving
typedef RegistrationWrapperType * RegistrationPointerType ;
void Execute (itk::Object *caller, const itk::EventObject &event)
{
RegistrationPointerType registrationWrapper = dynamic_cast < RegistrationPointerType > (caller ) ;
OptimizerPointerType optimizer = dynamic_cast < OptimizerPointerType > ( registrationWrapper->GetModifiableOptim\
izer() ) ;
std::cout << "RegObserver" << optimizer->GetCurrentIteration() << std::endl ;
int level = registrationWrapper->GetCurrentLevel() ;
if ( level == 0 )
optimizer->SetMaximumStepLength ( 0.0625 ) ;
else if ( level == 1 )
optimizer->SetMaximumStepLength ( 0.125 / 2 ) ;
else
optimizer->SetMaximumStepLength ( 0.25 / 2 ) ;
}
void Execute (const itk::Object *caller, const itk::EventObject &event)
{
}
protected:
RegistrationObserver() {} ;
};
*/
int
main(int argc, char *argvp[])
{
//Setup types
const unsigned int nDims = 3;
typedef itk::Image<double,nDims>ImageType;
//Create and setup a reader for the fixed image:
typedef itk::ImageFileReader<ImageType>readerType;
readerType::Pointer reader = readerType::New();
reader->SetFileName("../MPRAGE21_copy/KKI2009-21-MPRAGE.nii");
reader->Update();
ImageType::Pointer fixedImage = reader->GetOutput();
//Create and setup readers for the moving images:
typedef itk::ImageFileReader<ImageType>readerType;
// readerType::Pointer readers[21]; //**************
for (int i=1;i<=20;i++)
{
std::string digit="";
if(i<10)
{
digit="0";
}
//typedef itk::ImageFileReader<ImageType>readerType;
readerType::Pointer readers[i-1]
readers[i-1]=readerType::New();
readers[i-1]->SetFileName("../MPRAGE21_copy/KKI2009-"+digit+std::to_string(i)+"-MPRAGE.nii");
readers[i-1]->Update();
std::cerr<<"../MPRAGE21_copy/KKI2009-"+digit+std::to_string(i)+"-MPRAGE.nii"<<std::endl;
// }//*********************
//Register images:
//Setup typedefs:
typedef itk::AffineTransform<double,3>TransformType;
typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
typedef itk::MeanSquareImageToImageMetric<ImageType, ImageType>MetricType; //the two image types are fixed
//and moving images
typedef itk::ImageRegistrationMethod <ImageType, ImageType>RegistrationWrapperType;//simply RegistrationType
typedef itk::LinearInterpolateImageFunction<ImageType, ImageType>InterpolatorType; //moving image and coordinate r\
ep?? are we not using ITKv4 registration framework which has two interpolatortypes for fixed and moving images.
//Declare the variables:
TransformType::Pointer transform = TransformType::New();
OptimizerTyper::Pointer optimizer = OptimizerType::New();
MetricType::Pointer metric = MetricType::New();
RegistrationWrapperType::Pointer registrationWrapper = RegistrationWrapperType::New();
InterpolatorType::Pointer interpolator = InterpolatorType::New();
optimizer->AddObserver(itk::IterationEvent(),observer);
//Connect the pipeline: Simply connect to the instances
std::cout<<optimizer->GetMinimumStepLength()<<""<<optimizer->GetMaximumStepLength()<<""<<optimizer->GetNumberOfIte\
rations()<<""<<optimizer->GetGradientMagnitudeTolerance()<<std::endl; //what does this line doing?
transform->SetIdentity();
registrationWrapper->SetFixedImage(fixedImage);
registrationWrapper->SetMovingImage(readers[i]);
registrationWrapper->SetTransform(transform);
registrationWrapper->SetMetric(metric);
registrationWrapper->SetInterpolator(interpolator);
registrationWrapper->SetOptimizer(optimizer)
registrationWrapper->SetInitialTransformParameters(transform->GetParameters());
registraionWrapper->SetFixedImageRegion(fizedImage->GetLargestPossibleRegion());
registrationWrapper->SetNumberOfLevels(3);
//Run the registration:
try
{
registrationWrapper->Update();
}
catch (itk::ExceptionObject & excp)
{
std::cerr<<"Error in registration"<< std::endl;
std::cerr<<excp<<std::endl;
}
//Update the transform:
transform->SetParameters(registrationWrapper->GetLastTransforParameters());
//Apply the transform:
typedef itk::ResampleImageFilter<ImageType, ImageType>ResampleFilterType;
ResampleFilterType::Pointer filter = ResampleFilterType::New()
filter->SetInput(movingImage);
//*** a commented out line in Oct4
filter->SetTransform(transform);
filter->SetSize(movingImage->GetLargestPossibleRegion().GetSize());
filter->SetReferenceImage(fixedImage);
filter->UseReferenceImageOn();
filter->Update();
//write out the result:
typedef itk::ImageFileWriter<ImageType>writerType;
writerType::Pointer writer=writerType::New();
writer->SetInput(filter->GetOutput());
writer->SetFilename("../AffineFiles/AR-"+digit+std::to_string(i)+"MPRAGE.nii");
writer->Update();
}
//Done
return 0
}
I would be happy if anyone good at ITK, C++ could help me debug.
Thanks