[Insight-users] Rigid registration of IBSR images
Andriy Fedorov
fedorov at bwh.harvard.edu
Sat Apr 7 20:37:52 EDT 2007
Luis,
Thank you for your reply and your attention to this.
As you noted correctly, I should use the image parameters of the Fixed image.
I have discovered just now (trying to understand, why your resampler
works and mine doesn't...), that IBSR_01 and IBSR_09 have different
grid parameters: spacing is 1x1x1.5 vs 0.9375x0.9375x1.5! I
initialized the parameters from the Moving image, and that caused the
illusion of a translation error in the XY plane!
This took me too long to resolve, but I am happy, I learned a very good lesson!
Thank you very very much!
Fedorov
On 7 Apr 2007 19:25:58 -0400, Luis Ibanez <luis.ibanez at kitware.com> wrote:
>
> Hi Andriy,
>
>
> Thanks for your detailed description of the problem.
>
> (That's how a reproducible experiment should be described !)
>
>
>
> We just rerun the registration and tried
> your resampling code.
>
>
> Both of them work fine.
>
>
>
> You simply get the impression that your resampled image is
> different from the image resampled by the registration
> program, because you are setting the Default pixel value to
> 0.0 while the registration program uses Default value of 100.0.
>
> If you change the default value to the same number in both
> programs, you will find that the output images are identical.
> (Well, except for the pixel type,... you may want to unify
> that too...).
>
>
> Note however that in your resampling program you are relying
> on the fixed and moving image to have the same origin, spacing,
> and grid parameters (number of pixels along every dimension).
> In the case of these two IBSR datasets, you can get away with
> this assumption, but in general you should use the grid parameters
> of the Fixed image. This includes:
>
> * Origin
> * Spacing
> * Size
> * Direction.
>
> Just for completeness we modified your resampling code in order
> top expect both the fixed and moving images as input.
>
> Please find the modified code attached to this email.
>
>
>
> Regards,
>
>
> Luis
>
>
>
> -------------------------
> Andriy Fedorov wrote:
> > Hello,
> >
> > I am using ImageRegistration8 example from the
> > Insight/Examples/Registration. I only modified it to save the final
> > transform by adding these lines:
> >
> > itk::TransformFileWriter::Pointer trWriter =
> > itk::TransformFileWriter::New();
> > trWriter->SetFileName("transform.par");
> > trWriter->SetInput(finalTransform);
> > trWriter->Update();
> >
> > The problem I am having is that if I apply this saved transform to the
> > moving image, the resulting image is different from the registered
> > image, produced by ImageRegistration8. Looks like translation is
> > incorrect, possibly incorrect translation vector direction. I did
> > check the transform as it is written and read back with
> > Print(std::cout), and it appears to be exactly the same.
> >
> > I suspect something is weird or wrong with the data I am using, or
> > with the code handling this particular kind of data, because this same
> > code and resampler work fine with the BrainWeb test images (referenced
> > in ITK guide).
> >
> > Can anybody help me what could be the problem?
> >
> > I am using IBSR "New New 18 T1 MRI" dataset, Analyze format, it can be
> > downloaded here http://www.cma.mgh.harvard.edu/ibsr/data.html.
> > Specifically, I am using image IBSR_09_ana_padded_masked.hdr as the
> > reference, and IBSR_01_ana_padded_masked.hdr as the floating image.
> >
> > I attach the resampler code that I am using.
> >
> > I tried different things to figure this out, including using
> > OrientedImage instead of just Image class, converting data from
> > Analyze to Metaheader with RPI orientation passing it through
> > OrientImage, but none seemed to work...
> >
> > I would really appreciate any help or suggestion.
> >
> > Andriy Fedorov
> >
> >
> > ------------------------------------------------------------------------
> >
> > #include "itkTransformFileReader.h"
> > #include "itkTransformFileWriter.h"
> > #include "itkLinearInterpolateImageFunction.h"
> > #include "itkNearestNeighborInterpolateImageFunction.h"
> > #include "itkImage.h"
> > #include "itkVersorRigid3DTransform.h"
> > #include "itkImageFileReader.h"
> > #include "itkImageFileWriter.h"
> > #include "itkResampleImageFilter.h"
> >
> >
> >
> > int main( int argc, char *argv[] )
> > {
> >
> > const unsigned int Dimension = 3;
> > typedef float PixelType;
> >
> > typedef itk::Image< PixelType, Dimension > ImageType;
> > typedef itk::ImageFileReader< ImageType> ReaderType;
> > typedef itk::ImageFileWriter< ImageType> WriterType;
> > typedef itk::VersorRigid3DTransform< double > VersorRigid3DTransformType;
> > typedef itk::TransformFileReader TransformReader;
> >
> > typedef itk:: LinearInterpolateImageFunction< ImageType, double >
> > LinearInterpolatorType;
> > typedef itk::ResampleImageFilter<ImageType,ImageType> ResamplerType;
> >
> > if( argc != 4 ){
> > std::cerr << "Usage: " << argv[0];
> > std::cerr << " movingImageFile "; // argv[1]
> > std::cerr << " transformFile "; // argv[2]
> > std::cerr << " outputImagefile"; // argv[3]
> > std::cerr << std::endl;
> > return -1;
> > }
> >
> > ImageType::Pointer inputImage;
> >
> > ReaderType::Pointer imageReader = ReaderType::New();
> > imageReader->SetFileName(argv[1]);
> >
> > WriterType::Pointer imageWriter = WriterType::New();
> > imageWriter->SetFileName(argv[3]);
> >
> > TransformReader::Pointer transformReader = TransformReader::New();
> > transformReader->SetFileName(argv[2]);
> >
> > ResamplerType::Pointer resampler = ResamplerType::New();
> >
> > try{
> > imageReader->Update();
> > transformReader->Update();
> > } catch(itk::ExceptionObject &e){
> > std::cerr << "Failed to read file or transform: " << e << std::endl;
> > return -1;
> > }
> >
> > inputImage = imageReader->GetOutput();
> > resampler->SetInput(inputImage);
> >
> > typedef itk::TransformFileReader::TransformListType* TransformListType;
> > TransformListType transforms = transformReader->GetTransformList();
> > itk::TransformFileReader::TransformListType::const_iterator
> > it = transforms->begin();
> >
> > if (!strcmp((*it)->GetNameOfClass(), "VersorRigid3DTransform")) {
> > VersorRigid3DTransformType::Pointer versorrigid_read =
> > static_cast<VersorRigid3DTransformType*>((*it).GetPointer());
> > resampler->SetTransform( versorrigid_read );
> > std::cout << "Applying this transform: " << versorrigid_read << std::endl;
> > } else {
> > std::cerr << "Transform " << (*it)->GetNameOfClass()
> > << " is not supported" << std::endl;
> > return 1;
> > }
> >
> > LinearInterpolatorType::Pointer linearInterpolator =
> > LinearInterpolatorType::New();
> > resampler->SetInterpolator(linearInterpolator);
> >
> > resampler->SetSize(inputImage->GetLargestPossibleRegion().GetSize());
> > resampler->SetOutputOrigin(inputImage->GetOrigin());
> > resampler->SetOutputSpacing(inputImage->GetSpacing());
> > resampler->SetDefaultPixelValue(0.0);
> >
> > imageWriter->SetInput(resampler->GetOutput());
> >
> > try{
> > imageWriter->Update();
> > } catch(itk::ExceptionObject &e){
> > std::cerr << "Failed to save the resulting image: " << e << std::endl;
> > return -1;
> > }
> >
> > return 0;
> > }
> >
> >
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > Insight-users mailing list
> > Insight-users at itk.org
> > http://www.itk.org/mailman/listinfo/insight-users
>
>
More information about the Insight-users
mailing list