[Insight-users] registration using rotation + translation

Luis Ibanez luis.ibanez at kitware.com
Fri Dec 10 05:38:42 EST 2010


Hi KLN,

The itkPermuteAxesImageFilter.h
might be what you are looking for.

http://www.itk.org/Doxygen/html/classitk_1_1PermuteAxesImageFilter.html


    Regards,

         Luis

----------------------------------------------------------------
On Mon, Dec 6, 2010 at 10:57 PM, Kevin Neff <kevin.l.neff at gmail.com> wrote:
>
> My image ix 1388x560x53.  It appears that a 90 deg rotation around the x
> axis produces an image that is still 53 slices thick, rather than 1388
> slices.  Any suggestions on how to simply rotate the image?  I've tried
> changing the output size of the filter, but that produces a blank image.
>
>
>
> On Mon, Dec 6, 2010 at 12:06 PM, Kevin Neff <kevin.l.neff at gmail.com> wrote:
>>
>> Right.  After fixing this foolish error, it seems to be working.
>>
>> Still, the final dimensions are identical to the original dimensions.  If
>> I rotate the image 90 deg around the x axis, the width will not change but
>> the height and depth should change.  Is there a way to expand the "canvas"
>> (putting it in GIMP/Photoshop terms)?
>>
>> KLN
>>
>>
>>
>> On Sat, Dec 4, 2010 at 6:45 PM, Luis Ibanez <luis.ibanez at kitware.com>
>> wrote:
>>>
>>> Hi Kevin,
>>>
>>> Seth is right,
>>> the signature of the Rotate3D method is:
>>>
>>>   void Rotate3D(const OutputVectorType & axis, TScalarType angle,
>>> bool pre = 0);
>>>
>>>  ......
>>>
>>>            Luis
>>>
>>>
>>> -------------------------------------------------------------
>>> On Fri, Dec 3, 2010 at 12:07 PM, Kevin Neff <kevin.l.neff at gmail.com>
>>> wrote:
>>> >
>>> > Of the potential problems mentioned, the most obvious is getting the
>>> > data
>>> > oriented roughly, so I'm trying to do that first.  I'm using
>>> > ResampleImageFilter4.cxx, modified for 3D rotation.  Input and output
>>> > is
>>> > mhd, unsigned shorts.
>>> >
>>> > When I rotate the volume by any amount, there is no visible
>>> > difference.  I
>>> > tried 0, 1, 10, 45, 89, and 90 deg.  What am I doing wrong?
>>> >
>>> > When a volume is rotated, the dimensions of the volume in the output
>>> > mhd
>>> > file should account for it, right?  So rotating 45 deg should increase
>>> > one
>>> > of the dimensions.
>>> >
>>> >
>>> >
>>> > #include "itkImage.h"
>>> > #include "itkImageFileReader.h"
>>> > #include "itkImageFileWriter.h"
>>> > #include "itkResampleImageFilter.h"
>>> > #include "itkLinearInterpolateImageFunction.h"
>>> >
>>> >
>>> > #include "itkAffineTransform.h"
>>> >
>>> >
>>> > int main( int argc, char * argv[] )
>>> > {
>>> >   if( argc < 4 )
>>> >     {
>>> >     std::cerr << "Usage: " << std::endl;
>>> >     std::cerr << argv[0] << "  inputImageFile  outputImageFile
>>> > degrees" <<
>>> > std::endl;
>>> >     return EXIT_FAILURE;
>>> >     }
>>> >
>>> >   const     unsigned int   Dimension = 3;
>>> >   typedef   unsigned short  InputPixelType;
>>> >   typedef   unsigned short  OutputPixelType;
>>> >
>>> >   typedef itk::Image< InputPixelType,  Dimension >   InputImageType;
>>> >   typedef itk::Image< OutputPixelType, Dimension >   OutputImageType;
>>> >
>>> >   typedef itk::ImageFileReader< InputImageType  >  ReaderType;
>>> >   typedef itk::ImageFileWriter< OutputImageType >  WriterType;
>>> >
>>> >   ReaderType::Pointer reader = ReaderType::New();
>>> >   WriterType::Pointer writer = WriterType::New();
>>> >
>>> >   reader->SetFileName( argv[1] );
>>> >   writer->SetFileName( argv[2] );
>>> >
>>> >   const double angleInDegrees = atof( argv[3] );
>>> >
>>> >   typedef itk::ResampleImageFilter<
>>> >                   InputImageType, OutputImageType >  FilterType;
>>> >
>>> >   FilterType::Pointer filter = FilterType::New();
>>> >
>>> >
>>> >
>>> >   typedef itk::AffineTransform< double, Dimension >  TransformType;
>>> >   TransformType::Pointer transform = TransformType::New();
>>> >
>>> >
>>> >   typedef itk::LinearInterpolateImageFunction<
>>> >                        InputImageType, double >  InterpolatorType;
>>> >   InterpolatorType::Pointer interpolator = InterpolatorType::New();
>>> >
>>> >   filter->SetInterpolator( interpolator );
>>> >
>>> >   filter->SetDefaultPixelValue( 100 );
>>> >
>>> >
>>> >   reader->Update();
>>> >
>>> >   const InputImageType * inputImage = reader->GetOutput();
>>> >
>>> >   const InputImageType::SpacingType & spacing =
>>> > inputImage->GetSpacing();
>>> >   const InputImageType::PointType & origin  = inputImage->GetOrigin();
>>> >   InputImageType::SizeType size =
>>> >       inputImage->GetLargestPossibleRegion().GetSize();
>>> >
>>> >   filter->SetOutputOrigin( origin );
>>> >   filter->SetOutputSpacing( spacing );
>>> >   filter->SetOutputDirection( inputImage->GetDirection() );
>>> >   filter->SetSize( size );
>>> >
>>> >
>>> >   filter->SetInput( reader->GetOutput() );
>>> >   writer->SetInput( filter->GetOutput() );
>>> >
>>> >
>>> >   TransformType::OutputVectorType translation1;
>>> >
>>> >   const double imageCenterX = origin[0] + spacing[0] * size[0] / 2.0;
>>> >   const double imageCenterY = origin[1] + spacing[1] * size[1] / 2.0;
>>> >   const double imageCenterZ = origin[2] + spacing[2] * size[2] / 2.0;
>>> >
>>> >   translation1[0] =   -imageCenterX;
>>> >   translation1[1] =   -imageCenterY;
>>> >   translation1[2] =   -imageCenterZ;
>>> >   transform->Translate( translation1 );
>>> >
>>> >   std::cout << "imageCenterX = " << imageCenterX << std::endl;
>>> >   std::cout << "imageCenterY = " << imageCenterY << std::endl;
>>> >   std::cout << "imageCenterZ = " << imageCenterZ << std::endl;
>>> >
>>> >
>>> >   const double degreesToRadians = vcl_atan(1.0) / 45.0;
>>> >   const double angle = angleInDegrees * degreesToRadians;
>>> >   transform->Rotate3D( -angle, false );
>>> >
>>> >
>>> >   TransformType::OutputVectorType translation2;
>>> >   translation2[0] =   imageCenterX;
>>> >   translation2[1] =   imageCenterY;
>>> >   translation2[2] =   imageCenterZ;
>>> >   transform->Translate( translation2, false );
>>> >   filter->SetTransform( transform );
>>> >
>>> >   try
>>> >     {
>>> >     writer->Update();
>>> >     }
>>> >   catch( itk::ExceptionObject & excep )
>>> >     {
>>> >     std::cerr << "Exception caught !" << std::endl;
>>> >     std::cerr << excep << std::endl;
>>> >     }
>>> >
>>> >   return EXIT_SUCCESS;
>>> > }
>>> >
>>> >
>>> >
>>> >
>>> >
>>> >
>>> > On Tue, Nov 30, 2010 at 9:29 PM, Luis Ibanez <luis.ibanez at kitware.com>
>>> > wrote:
>>> >>
>>> >> Hi Kevin
>>> >>
>>> >> On Tue, Nov 30, 2010 at 1:23 PM, Kevin Neff <kevin.l.neff at gmail.com>
>>> >> wrote:
>>> >> >
>>> >> > Thanks, Dan.  I used the example ImageRegistration8.cxx with my
>>> >> > data.
>>> >> >
>>> >> > First, it's terribly slow.  Is there anything I can do to speed it
>>> >> > up?
>>> >>
>>> >>
>>> >> 1)  How long it took ?
>>> >>
>>> >> 2)  How many cores do you have ?
>>> >>
>>> >> 3) What version of ITK are you using ?
>>> >>
>>> >> 4) Make sure that you compile it for Release mode.
>>> >>     (that easily makes a difference of 10x with respect to Debug
>>> >> mode).
>>> >>
>>> >>
>>> >> > my limited experience, applying a threshold first and skipping
>>> >> > rotation
>>> >> > of
>>> >> > voxels below the threshold helped.  Or could I pre-compute isotropic
>>> >> > voxels
>>> >> > and skip the interpolation that follows image rotation and just
>>> >> > interpolate
>>> >> > the final solution?  Any suggestion is welcome!
>>> >> >
>>> >>
>>> >> You could also use a Mask,
>>> >> See example:
>>> >>
>>> >> ITK/Examples/Registration/ImageRegistration12.cxx
>>> >>
>>> >>
>>> >> > Second, after 200 iterations,  the output does not appear correct.
>>> >> > I
>>> >> > ran it
>>> >> > with data that had the dimensions 13888x560x48 and 1388x560x53 but
>>> >> > the
>>> >> > output had the dimensions 13888x560x48.  The volumes were of the
>>> >> > shell
>>> >> > of a
>>> >> > large object, rotated 90 deg, so I'm sure the dimension of the
>>> >> > output
>>> >> > should
>>> >> > have been much larger---something like 1388x1000x100.
>>> >>
>>> >> a) 90 degrees is beyond the capture radio of any registration method.
>>> >>    You must initialize the Transform to account for most of that
>>> >> rotation.
>>> >>    In practice you shouldn't expect the optimization process to
>>> >> correct
>>> >>    for more than 20 to 30 degrees of rotation.
>>> >>
>>> >> b) Is that rotation along the long axis of your image ? or
>>> >> perpendicular
>>> >> to it ?
>>> >>    A screen shot of your image will be very helpful...
>>> >>
>>> >> c) You should carefully control the parameter scales to make sure that
>>> >>    you account for the proportion of radians units (used for rotation)
>>> >> to
>>> >>    millimeters used for translation.
>>> >>
>>> >> d) What is the pixel spacing of your images ?
>>> >>
>>> >>
>>> >> >
>>> >> > KLN
>>> >> >
>>> >> >
>>> >> >
>>> >> >
>>> >> >
>>> >> > On Sun, Nov 21, 2010 at 7:55 AM, Dan Mueller <dan.muel at gmail.com>
>>> >> > wrote:
>>> >> >>
>>> >> >> Hi Kevin,
>>> >> >>
>>> >> >> I highly recommending the entire ITK Software Guide:
>>> >> >>    http://www.itk.org/ItkSoftwareGuide.pdf
>>> >> >>
>>> >> >> For your specific question, see section 8.8.
>>> >> >>
>>> >> >> In short:
>>> >> >>
>>> >> >> IdentityTransform: identity
>>> >> >> TranslationTransform: n-D translation
>>> >> >> ScaleTransform: n-D scaling
>>> >> >> CenteredRigid2DTransform: 2-D rotation + translation
>>> >> >> Similarity2DTransform: 2-D scaling + rotation + translation
>>> >> >> VersorTransform: 3-D rotation
>>> >> >> VersorRigid3DTransform: 3-D rotation + translation
>>> >> >> Similarity3DTransform: 3-D scaling + rotation + translation
>>> >> >> AffineTransform: n-D scaling + rotation + translation + shear
>>> >> >>
>>> >> >> HTH
>>> >> >>
>>> >> >> Cheers, Dan
>>> >> >>
>>> >> >> On 21 November 2010 13:49, Kevin Neff <kevin.l.neff at gmail.com>
>>> >> >> wrote:
>>> >> >> >
>>> >> >> > I need to register images using rotation and translation.  Is
>>> >> >> > that
>>> >> >> > possible
>>> >> >> > with theITK classes, or do I have to write my own?
>>> >> >> >
>>> >> >> > I'm basing this question on a translation-only example and the
>>> >> >> > list
>>> >> >> > of
>>> >> >> > classes derived from AffineTransform
>>> >> >> >
>>> >> >> > http://www.itk.org/Wiki/ITK_Image_Registration
>>> >> >
>>> >> >
>>> >> > _____________________________________
>>> >> > Powered by www.kitware.com
>>> >> >
>>> >> > Visit other Kitware open-source projects at
>>> >> > http://www.kitware.com/opensource/opensource.html
>>> >> >
>>> >> > Kitware offers ITK Training Courses, for more information visit:
>>> >> > http://www.kitware.com/products/protraining.html
>>> >> >
>>> >> > Please keep messages on-topic and check the ITK FAQ at:
>>> >> > http://www.itk.org/Wiki/ITK_FAQ
>>> >> >
>>> >> > Follow this link to subscribe/unsubscribe:
>>> >> > http://www.itk.org/mailman/listinfo/insight-users
>>> >> >
>>> >> >
>>> >
>>> >
>>> > _____________________________________
>>> > Powered by www.kitware.com
>>> >
>>> > Visit other Kitware open-source projects at
>>> > http://www.kitware.com/opensource/opensource.html
>>> >
>>> > Kitware offers ITK Training Courses, for more information visit:
>>> > http://www.kitware.com/products/protraining.html
>>> >
>>> > Please keep messages on-topic and check the ITK FAQ at:
>>> > http://www.itk.org/Wiki/ITK_FAQ
>>> >
>>> > Follow this link to subscribe/unsubscribe:
>>> > http://www.itk.org/mailman/listinfo/insight-users
>>> >
>>> >
>>
>
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
>


More information about the Insight-users mailing list