[Insight-users] [Fwd: factories for FFTW filters - update]

Jakub Bican jakub.bican at matfyz.cz
Sun Oct 29 13:11:25 EST 2006


Hi,

i implemented Gaetan's idea and attached the modified files. I am 
testing it in some of my projects and it works nice;)

Please, if you find it useful, consider putting it to ITK. If it is 
necessary, i can post it in IJ, but i won't do that for these 30 lines 
implicitly :)))

Thanks,

       Jakub


Jakub Bican napsal(a):
> Thanks Luis,
>
> i studied this already, but it does not explain everything i need. 
> Moreover, implementing factory for templated class requires some extra 
> effort.
>
> Can you consider the solution suggested by Gaetan, please? It seems 
> really practical, while it does not affect existing code based on FFT 
> in any way.
>
> Regards,
>
>         Jakub
>
>
> 2006/10/26, Luis Ibanez <luis.ibanez at kitware.com 
> <mailto:luis.ibanez at kitware.com>>:
>
>
>
>     Hi Jakub,
>
>
>     If you are interested in overriding a factory with another one,
>     you may want to look at the following course material:
>
>
>     http://www.na-mic.org/Wiki/index.php/Dissemination:EPFL_Workshop_2005
>
>
>     In particular to the presentation:
>
>     http://www.na-mic.org/Wiki/images/2/24/Insight-DesignPatterns.ppt
>     <http://www.na-mic.org/Wiki/images/2/24/Insight-DesignPatterns.ppt>
>
>
>     The discussion on Factories starts on slide 53.
>
>     The source code of examples for Factories can be found at
>
>     http://www.na-mic.org:8000/svn/NAMICSandBox/trunk/ITKAdvancedCourse/
>     <http://www.na-mic.org:8000/svn/NAMICSandBox/trunk/ITKAdvancedCourse/>
>
>
>     In Exercise 29:
>     http://www.na-mic.org:8000/svn/NAMICSandBox/trunk/ITKAdvancedCourse/src/Exercises/exercise29/
>     <http://www.na-mic.org:8000/svn/NAMICSandBox/trunk/ITKAdvancedCourse/src/Exercises/exercise29/>
>
>
>         Regards,
>
>
>            Luis
>
>
>     =---------------------------
>     Jakub Bican wrote:
>     >
>     > Hi Gaetan,
>     >
>     > as i more and more understand the problem of factories, it is
>     clear to
>     > me, that this is the most elegant solution.
>     >
>     > Your suggestion have to be complicated only a little bit more by
>     > determining, if the actual PixelType matches the type of FFTW
>     library
>     > linked: i.e. use FFTW only if FFTWF is defined and PixelType is
>     float or
>     > FFTWD is defined and pixeltype is double.
>     >
>     > There should be also check if there is some factory for the
>     class, as it
>     > is in itkNewMacro (in case someone will use dynamic library with
>     new FFT
>     > implementation)
>     >
>     > Is it possible to make such change to ITK cvs version?
>     >
>     > I hope this will help to many people that are writing filters
>     using FFT.
>     >
>     > Thanks,
>     >
>     >       Jakub
>     >
>     >
>     >
>     >
>     > Gaetan Lehmann napsal(a):
>     >
>     >>
>     >> Hi Jakub,
>     >>
>     >> That's only my point of view, but don't you think that the
>     factory is
>     >> quite complicated for that case ?
>     >> IMHO opinion, a customized New() method in
>     >> RealToComplexConjugateImageFilter would do the job without problem.
>     >> Something like:
>     >>
>     >> static Pointer New()
>     >>   {
>     >> #if defined(USE_FFTWF)
>     >>   return FFTWRealToComplexConjugateImageFilter<PixelType,
>     >> ImageDimension>::New().GetPointer();
>     >> #else
>     >>   return VnlFFTRealToComplexConjugateImageFilter<PixelType,
>     >> ImageDimension>::New().GetPointer();
>     >> #endif
>     >>   }
>     >>
>     >> Regards,
>     >>
>     >> Gaetan
>     >>
>     >>
>     >>
>     >> On Thu, 26 Oct 2006 11:51:13 +0200, Jakub Bican
>     >> <jakub.bican at matfyz.cz <mailto:jakub.bican at matfyz.cz>> wrote:
>     >>
>     >>>
>     >>> Hi,
>     >>>
>     >>> things seem more clear now: I have to make just one class
>     >>> (FFTFactory:ObjectFactoryBase) that calls RegisterOverride()
>     in its
>     >>> constructor to override creation of
>     RealToComplexConjugateImageFilter
>     >>> and ComplexConjugateToRealImageFilter by available implementation
>     >>> from VNL or FFTW.
>     >>>
>     >>> But the questions remains the same:
>     >>> 1) how to register this factory as "implicit default factory" -
>     >>> without need to register it manually in every filter or every
>     program
>     >>> that uses FFT
>     >>>
>     >>> 2) what happens if there will be new FFT implementation in dynamic
>     >>> library, that will override in the same way - which factory
>     will have
>     >>> priority? (if the dynamic one overrides the default one, then
>     it is
>     >>> ok - that is the intention, but does it really happen?)
>     >>>
>     >>>
>     >>> Regards,
>     >>>
>     >>>         Jakub
>     >>>
>     >>>
>     >>>
>     >>>
>     >>> -------- Původní zpráva --------
>     >>>
>     >>> Hello,
>     >>>
>     >>> i would like to implement a factory mechanism for FFT filters. The
>     >>> point is that if the user selects "USE_FFTW" once during
>     >>> configuration, then the factory mechanism will provide him
>     FFTW-based
>     >>> classes instead of standard VNL implementation. And user can also
>     >>> create his own dll with some fft implementation and attach it
>     >>> dynamically to his project.
>     >>>
>     >>> I studied the tutorial
>     >>>
>     (http://www.na-mic.org/Wiki/images/2/24/Insight-DesignPatterns.ppt
>     <http://www.na-mic.org/Wiki/images/2/24/Insight-DesignPatterns.ppt>)
>     >>> including examples.
>     >>>
>     >>> I would like to ask someone if i understand well what i have
>     to do:
>     >>>
>     >>> step A) create factories FFTWFFTFactory and VNLFFTFactory
>     (derived
>     >>> from following class), that will override creation of
>     >>> RealToComplexConjugateImageFilter and
>     >>> ComplexConjugateToRealImageFilter types so that an instance from
>     >>> appropriate implementation is created.
>     >>>
>     >>> step B) create class FFTFactoryBase (derived from
>     ObjectFactoryBase)
>     >>> that will be implemented similary to TransformFactoryBase and that
>     >>> will register one of the above factories, depending on if the
>     FFTW is
>     >>> used or not
>     >>> (this is difference to TransformFactoryBase, which registers all
>     >>> known factories, while the new class will register only one
>     depending
>     >>> on configuration)
>     >>>
>     >>>
>     >>> And i have some questions:
>     >>>
>     >>> 1) what is the correct way of registering FFTFactoryBase
>     >>> automatically, so that it registers appropriate factory "at the
>     >>> beginning"?
>     >>> I don't want to register it explicitly at the beginning of every
>     >>> program that will use FFT - i just want to call
>     >>> RealToComplexConjugateImageFilter::New() and get FFTW
>     implementation
>     >>> if i attached FFTW library to ITK or VNL implementation otherwise.
>     >>>
>     >>> 2) what happens if someone loads dll into ITK_AUTOLOAD_PATH with a
>     >>> new FFT implementation and corresponding factory? What will be
>     >>> overriden by what?
>     >>>
>     >>> Thanks in advance for guidance and answers,
>     >>>
>     >>>    Jakub
>     >>>
>     >>>
>     >>>
>     >>>
>     >>>
>     >>> _______________________________________________
>     >>> Insight-users mailing list
>     >>> Insight-users at itk.org <mailto:Insight-users at itk.org>
>     >>> http://www.itk.org/mailman/listinfo/insight-users
>     >>
>     >>
>     >>
>     >>
>     >> --Gaëtan Lehmann
>     >> Biologie du Développement et de la Reproduction
>     >> INRA de Jouy-en-Josas (France)
>     >> tel: +33 1 34 65 29 66    fax: 01 34 65 29 09
>     >> http://voxel.jouy.inra.fr
>     >>
>     >>
>     > _______________________________________________
>     > Insight-users mailing list
>     > Insight-users at itk.org <mailto:Insight-users at itk.org>
>     > http://www.itk.org/mailman/listinfo/insight-users
>     >
>
>
-------------- next part --------------
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkFFTComplexConjugateToRealImageFilter.h,v $
  Language:  C++
  Date:      $Date: 2006/08/11 14:52:37 $
  Version:   $Revision: 1.4 $

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __itkFFTComplexConjugateToRealImageFilter_h
#define __itkFFTComplexConjugateToRealImageFilter_h


#include <itkImageToImageFilter.h>
#include <itkImage.h>
#include <complex>

namespace itk
{
/** /class FFTComplexConjugateToRealImageFilter
 * /brief 
 *
 * \ingroup 
 */

template < class TPixel,unsigned int Dimension = 3 >
class FFTComplexConjugateToRealImageFilter :
    public ImageToImageFilter< Image< std::complex< TPixel > , Dimension >,
                               Image< TPixel,Dimension > >

{
public:
  /** Standard class typedefs.*/ 
  typedef Image< std::complex< TPixel > ,Dimension> TInputImageType;
  typedef Image<TPixel,Dimension> TOutputImageType;

  typedef FFTComplexConjugateToRealImageFilter Self;
  typedef ImageToImageFilter< TInputImageType, TOutputImageType > Superclass;
  typedef SmartPointer<Self> Pointer;
  typedef SmartPointer<const Self> constPointer;

  itkStaticConstMacro(ImageDimension, unsigned int,
                      TInputImageType::ImageDimension );

  /** Run-time type information (and related methods). */
  itkTypeMacro(FFTComplexConjugateToRealImageFilter, ImageToImageFilter);

  /** Customized object creation methods that support configuration-based 
  * selection of FFT implementation.
  *
  * Default implementation is VnlFFT.
  */
  static Pointer New(void);
  virtual ::itk::LightObject::Pointer CreateAnother(void) const;

  /** Image type typedef support. */
  typedef TInputImageType ImageType;
  typedef typename ImageType::SizeType ImageSizeType;
  virtual void GenerateOutputInformation(); // figure out allocation for output image
  virtual void GenerateInputRequestedRegion();
  virtual bool FullMatrix() = 0; // must be implemented in child  
  void SetActualXDimensionIsOdd(bool isodd) 
  { 
    m_ActualXDimensionIsOdd = isodd; 
  }
  void SetActualXDimensionIsOddOn() { 
    this->SetActualXDimensionIsOdd(true);
  }
  void SetActualXDimensionIsOddOff() { 
    this->SetActualXDimensionIsOdd(false);
  }
  bool ActualXDimensionIsOdd() { return m_ActualXDimensionIsOdd; }
protected:
  FFTComplexConjugateToRealImageFilter() : m_ActualXDimensionIsOdd(false) {}
  virtual ~FFTComplexConjugateToRealImageFilter(){}

private:
  bool m_ActualXDimensionIsOdd;
  FFTComplexConjugateToRealImageFilter(const Self&); //purposely not implemented
  void operator=(const Self&); //purposely not implemented
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkFFTComplexConjugateToRealImageFilter.txx"
#endif


#endif
-------------- next part --------------
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkFFTComplexConjugateToRealImageFilter.txx,v $
  Language:  C++
  Date:      $Date: 2006/08/23 16:32:47 $
  Version:   $Revision: 1.7 $

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.


=========================================================================*/
#ifndef __itkFFTComplexConjugateToRealImageFilter_txx
#define __itkFFTComplexConjugateToRealImageFilter_txx
#include "itkFFTComplexConjugateToRealImageFilter.h"
#include "itkMetaDataDictionary.h"
#include "itkMetaDataObject.h"
#include "itkVnlFFTComplexConjugateToRealImageFilter.h"
#include "itkFFTWComplexConjugateToRealImageFilter.h"

namespace itk
{
template < class TPixel , unsigned int Dimension >
typename FFTComplexConjugateToRealImageFilter < TPixel , Dimension >::Pointer
FFTComplexConjugateToRealImageFilter < TPixel , Dimension >
::New(void)
{ 
  Pointer smartPtr = ::itk::ObjectFactory<Self>::Create();

#ifdef USE_FFTWD
  if(smartPtr.IsNull())
    {
    if (typeid(TPixel) == typeid(double))
      {
      smartPtr = dynamic_cast<Self *>(
        FFTWComplexConjugateToRealImageFilter< double, Dimension >
          ::New().GetPointer() );
      }
    }
#endif
#ifdef USE_FFTWF
  if(smartPtr.IsNull())
    {
    if (typeid(TPixel) == typeid(float))
      {
      smartPtr = dynamic_cast<Self *>(
        FFTWComplexConjugateToRealImageFilter< float, Dimension >
          ::New().GetPointer());
      }
    }
#endif

  if(smartPtr.IsNull())
    {
    smartPtr = VnlFFTComplexConjugateToRealImageFilter< TPixel, Dimension >
                  ::New().GetPointer();
    }

    return smartPtr;
}

template < class TPixel , unsigned int Dimension >
::itk::LightObject::Pointer
FFTComplexConjugateToRealImageFilter < TPixel , Dimension >
::CreateAnother(void) const
{
  ::itk::LightObject::Pointer smartPtr;
  smartPtr = Self::New().GetPointer();
  return smartPtr;
}

template <class TPixel, unsigned int Dimension>
void
FFTComplexConjugateToRealImageFilter<TPixel,Dimension>::
GenerateOutputInformation()
{
  // call the superclass' implementation of this method
  Superclass::GenerateOutputInformation();
   //
  // If this implementation returns a full result
  // instead of a 'half-complex' matrix, then none of this
  // is necessary
  if(this->FullMatrix())
    return;
 
  // get pointers to the input and output
  typename TInputImageType::ConstPointer  inputPtr  = this->GetInput();
  typename TOutputImageType::Pointer      outputPtr = this->GetOutput();

  if ( !inputPtr || !outputPtr )
    {
    return;
    }
  
  // 
  // This is all based on the same function in itk::ShrinkImageFilter
  // ShrinkImageFilter also modifies the image spacing, but spacing
  // has no meaning in the result of an FFT. For an IFFT, since the
  // spacing is propagated to the complex result, we can use the spacing
  // from the input to propagate back to the output.
  unsigned int i;
  const typename TInputImageType::SizeType&   inputSize
    = inputPtr->GetLargestPossibleRegion().GetSize();
  const typename TInputImageType::IndexType&  inputStartIndex
    = inputPtr->GetLargestPossibleRegion().GetIndex();
  
  typename TOutputImageType::SizeType     outputSize;
  typename TOutputImageType::IndexType    outputStartIndex;
  
  //
  // in 4.3.4 of the FFT documentation, they indicate the size of
  // of a real-to-complex FFT is N * N ... + (N /2+1)
  //                              1   2        d
  // complex numbers.
  // going from complex to real, you know the output is at least
  // twice the size in the last dimension as the input, but it might
  // be 2*size+1.  Consequently, the output of the FFT:R2C operation
  // 
  MetaDataDictionary &InputDic = 
    const_cast<MetaDataDictionary &>(inputPtr->GetMetaDataDictionary());

  typedef typename TInputImageType::SizeType::SizeValueType SizeScalarType;

  SizeScalarType x;

  outputSize[0] = (inputSize[0] - 1) * 2;
  if(this->ActualXDimensionIsOdd())
    {
    outputSize[0]++;
    }
  // backwards compatible/deprecated version
  if(ExposeMetaData < SizeScalarType > 
          (InputDic,std::string("FFT_Actual_RealImage_Size"),x))
    {
    outputSize[0] = x;
    }

  outputStartIndex[0] = inputStartIndex[0];

  for (i = 1; i < TOutputImageType::ImageDimension; i++)
    {
    outputSize[i] = inputSize[i];
    outputStartIndex[i] = inputStartIndex[i];
    }
  typename TOutputImageType::RegionType outputLargestPossibleRegion;
  outputLargestPossibleRegion.SetSize( outputSize );
  outputLargestPossibleRegion.SetIndex( outputStartIndex );
  
  outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
}

template <class TPixel, unsigned int Dimension>
void
FFTComplexConjugateToRealImageFilter<TPixel,Dimension>::
GenerateInputRequestedRegion()
{
  Superclass::GenerateInputRequestedRegion();
  // get pointers to the input and output
  typename TInputImageType::Pointer  inputPtr  = 
    const_cast<TInputImageType *>(this->GetInput());
  if( inputPtr )
    {
    inputPtr->SetRequestedRegionToLargestPossibleRegion();
    }
}

}
#endif
-------------- next part --------------
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkFFTRealToComplexConjugateImageFilter.h,v $
  Language:  C++
  Date:      $Date: 2006/09/26 14:02:52 $
  Version:   $Revision: 1.4 $

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __itkFFTRealToComplexConjugateImageFilter_h
#define __itkFFTRealToComplexConjugateImageFilter_h


#include <itkImageToImageFilter.h>
#include <itkImage.h>
#include <complex>

namespace itk
{
/** /class FFTRealToComplexConjugateImageFilter
 * /brief 
 *
 * \ingroup 
 */
template <class TPixel,unsigned int Dimension = 3>
class ITK_EXPORT FFTRealToComplexConjugateImageFilter :
    public ImageToImageFilter< Image< TPixel , Dimension >,
                               Image< std::complex< TPixel > , Dimension > >
{
public:
  /** Standard class typedefs.*/ 
  typedef Image<TPixel,Dimension> TInputImageType;
  typedef Image< std::complex< TPixel > , Dimension> TOutputImageType;

  typedef FFTRealToComplexConjugateImageFilter Self;
  typedef ImageToImageFilter< TInputImageType, TOutputImageType > Superclass;
  typedef SmartPointer<Self> Pointer;
  typedef SmartPointer<const Self> constPointer;

  /** Run-time type information (and related methods). */
  itkTypeMacro(FFTRealToComplexConjugateImageFilter, ImageToImageFilter);

  /** Customized object creation methods that support configuration-based 
    * selection of FFT implementation.
    *
    * Default implementation is VnlFFT.
    */
  static Pointer New(void);
  virtual ::itk::LightObject::Pointer CreateAnother(void) const;

  /** Image type typedef support. */
  typedef TInputImageType ImageType;
  typedef typename ImageType::SizeType ImageSizeType;
  virtual void GenerateOutputInformation(); // figure out allocation for output image
  virtual void GenerateInputRequestedRegion(); 
  virtual void EnlargeOutputRequestedRegion(DataObject *output); 
  virtual bool FullMatrix() = 0; // must be implemented in child
protected:
  FFTRealToComplexConjugateImageFilter() {}
  virtual ~FFTRealToComplexConjugateImageFilter(){}

private:
  FFTRealToComplexConjugateImageFilter(const Self&); //purposely not implemented
  void operator=(const Self&); //purposely not implemented
};

} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#include "itkFFTRealToComplexConjugateImageFilter.txx"
#endif

#endif
-------------- next part --------------
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkFFTRealToComplexConjugateImageFilter.txx,v $
  Language:  C++
  Date:      $Date: 2006/09/26 14:02:52 $
  Version:   $Revision: 1.3 $

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __itkFFTRealToComplexConjugateImageFilter_txx
#define __itkFFTRealToComplexConjugateImageFilter_txx
#include "itkFFTRealToComplexConjugateImageFilter.h"
#include "itkMetaDataObject.h"
#include "itkVnlFFTRealToComplexConjugateImageFilter.h"
#include "itkFFTWRealToComplexConjugateImageFilter.h"

namespace itk
{
template < class TPixel , unsigned int Dimension >
typename FFTRealToComplexConjugateImageFilter < TPixel , Dimension >::Pointer
FFTRealToComplexConjugateImageFilter < TPixel , Dimension >
::New(void)
{ 
  Pointer smartPtr = ::itk::ObjectFactory<Self>::Create();

#ifdef USE_FFTWD
  if(smartPtr.IsNull())
    {
    if (typeid(TPixel) == typeid(double))
      {
      smartPtr = dynamic_cast<Self *>(
        FFTWRealToComplexConjugateImageFilter< double, Dimension >
          ::New().GetPointer() );
      }
    }
#endif
#ifdef USE_FFTWF
  if(smartPtr.IsNull())
    {
    if (typeid(TPixel) == typeid(float))
      {
      smartPtr = dynamic_cast<Self *>(
        FFTWRealToComplexConjugateImageFilter< float, Dimension >
          ::New().GetPointer());
      }
    }
#endif

  if(smartPtr.IsNull())
    {
    smartPtr = VnlFFTRealToComplexConjugateImageFilter< TPixel, Dimension >
                  ::New().GetPointer();
    }

    return smartPtr;
}

template < class TPixel , unsigned int Dimension >
::itk::LightObject::Pointer
FFTRealToComplexConjugateImageFilter < TPixel , Dimension >
::CreateAnother(void) const
{
  ::itk::LightObject::Pointer smartPtr;
  smartPtr = Self::New().GetPointer();
  return smartPtr;
}

template < class TPixel , unsigned int Dimension >
void
FFTRealToComplexConjugateImageFilter < TPixel , Dimension >
::GenerateOutputInformation()
{
  // call the superclass' implementation of this method
  Superclass::GenerateOutputInformation();
  //
  // If this implementation returns a full result
  // instead of a 'half-complex' matrix, then none of this
  // is necessary
  if(this->FullMatrix())
    return;

  // get pointers to the input and output
  typename TInputImageType::ConstPointer  inputPtr  = this->GetInput();
  typename TOutputImageType::Pointer      outputPtr = this->GetOutput();

  if ( !inputPtr || !outputPtr )
    {
    return;
    }
  
  // 
  // This is all based on the same function in itk::ShrinkImageFilter
  // ShrinkImageFilter also modifies the image spacing, but spacing
  // has no meaning in the result of an FFT.
  unsigned int i;
  const typename TInputImageType::SizeType&   inputSize
    = inputPtr->GetLargestPossibleRegion().GetSize();
  const typename TInputImageType::IndexType&  inputStartIndex
    = inputPtr->GetLargestPossibleRegion().GetIndex();
  
  typename TOutputImageType::SizeType     outputSize;
  typename TOutputImageType::IndexType    outputStartIndex;
  
  //
  // in 4.3.4 of the FFTW documentation, they indicate the size of
  // of a real-to-complex FFT is N * N ... + (N /2+1)
  //                              1   2        d
  // complex numbers.
  // static_cast prob. not necessary but want to make sure integer
  // division is used.
  outputSize[0] = static_cast<unsigned int>(inputSize[0])/2 + 1;
  outputStartIndex[0] = inputStartIndex[0];

  for (i = 1; i < TOutputImageType::ImageDimension; i++)
    {
    outputSize[i] = inputSize[i];
    outputStartIndex[i] = inputStartIndex[i];
    }
  //
  // the halving of the input size hides the actual size of the input.
  // to get the same size image out of the IFFT, need to send it as 
  // Metadata.
  typedef typename TOutputImageType::SizeType::SizeValueType SizeScalarType;
  itk::MetaDataDictionary &OutputDic=outputPtr->GetMetaDataDictionary();
  itk::EncapsulateMetaData<SizeScalarType>(OutputDic,
                                       std::string("FFT_Actual_RealImage_Size"),
                                                     inputSize[0]);
  typename TOutputImageType::RegionType outputLargestPossibleRegion;
  outputLargestPossibleRegion.SetSize( outputSize );
  outputLargestPossibleRegion.SetIndex( outputStartIndex );
  
  outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
}

template < class TPixel , unsigned int Dimension >
void
FFTRealToComplexConjugateImageFilter < TPixel , Dimension >
::GenerateInputRequestedRegion()
{
  // call the superclass' implementation of this method
  Superclass::GenerateInputRequestedRegion();
  
  // get pointers to the inputs
  typename TInputImageType::Pointer input  = 
    const_cast<TInputImageType *> (this->GetInput());
  
  if ( !input )
    {
    return;
    }
  
  input->SetRequestedRegionToLargestPossibleRegion();
}

 
template < class TPixel , unsigned int Dimension >
void
FFTRealToComplexConjugateImageFilter < TPixel , Dimension >
::EnlargeOutputRequestedRegion(DataObject *output)
{
  Superclass::EnlargeOutputRequestedRegion(output);
  output->SetRequestedRegionToLargestPossibleRegion();
}

}
#endif


More information about the Insight-users mailing list