[Insight-users] VectorImage Registration Metric

Karthik Krishnan karthik.krishnan at kitware.com
Wed Jul 2 16:47:14 EDT 2008


Kevin H. Hobbs wrote:
> Hi Luis,
>
> I just got a chance to return to my project that requires me to register
> two channel images.
>
> I'm continuing the thread :
>
> http://www.itk.org/pipermail/insight-users/2008-May/025666.html
>
> You wrote a class to facilitate this, and posted it in the NAMIC
> sandbox :
>
> http://www.na-mic.org/svn/NAMICSandBox/trunk/VectorImageRegistrationMethod/
>
> Thank you very much for this class!
>
> My choice to use an itk::VectorImage was based in part on memory usage.
> The images are large (about 1GB for two channels) even with a pixel type
> of unsigned char. As I understand it an image of vectors stores at least
> a pointer at each position in the image. That sounds like it would use
> all of my 4GB of RAM without ever loading any data.
>
> However, the documentation for itk::VectorImage says that they are used
> the same way.
>
> I pared my program down just to the minimum to show the compile problem
> I'm getting and attached it.
>
> The program compiles fine when I use an image of vectors in the template
> for the metric like so :
>
> typedef itk::Vector< PixelType, 2 >   V_PixelType;
>   typedef itk::Image< V_PixelType, Dimension >  V_ImageType;
>
> typedef itk::VectorMeanSquaresImageToImageMetric
>     < V_ImageType, V_ImageType > MetricType;
>
> But when I try to compile the program as it is in the attachment with:
>
> typedef itk::VectorImage< PixelType, Dimension >  ImageType;
>
> typedef itk::VectorMeanSquaresImageToImageMetric
>     < ImageType, ImageType > MetricType;
>
> I get the following output:
>
> /home/kevin/kitware/Insight/Code/Common/itkVectorInterpolateImageFunction.h: In instantiation of ‘itk::VectorInterpolateImageFunction<itk::VectorImage<unsigned char, 3u>, double>’:
> /home/kevin/Documents/VectorImageRegistrationMethod/Source/itkVectorImageToImageMetric.h:110:   instantiated from ‘itk::VectorImageToImageMetric<itk::VectorImage<unsigned char, 3u>, itk::VectorImage<unsigned char, 3u> >’
> /home/kevin/Documents/VectorImageRegistrationMethod/Source/itkVectorMeanSquaresImageToImageMetric.h:50:   instantiated from ‘itk::VectorMeanSquaresImageToImageMetric<itk::VectorImage<unsigned char, 3u>, itk::VectorImage<unsigned char, 3u> >’
> /home/kevin/Documents/stg_anatomy/align_rot_vect.cxx:25:   instantiated from here
> /home/kevin/kitware/Insight/Code/Common/itkVectorInterpolateImageFunction.h:65: error: ‘Dimension’ is not a member of ‘itk::VariableLengthVector<unsigned char>’
> /home/kevin/kitware/Insight/Code/Common/itkImageConstIteratorWithIndex.h: In member function ‘const typename TImage::PixelType& itk::ImageConstIteratorWithIndex<TImage>::Value() const [with TImage = itk::VectorImage<unsigned char, 3u>]’:
> /home/kevin/Documents/VectorImageRegistrationMethod/Source/itkVectorMeanSquaresImageToImageMetric.txx:203:   instantiated from ‘void itk::VectorMeanSquaresImageToImageMetric<TFixedImage, TMovingImage>::GetDerivative(const typename itk::VectorImageToImageMetric<TFixedImage, TMovingImage>::TransformParametersType&, typename itk::VectorImageToImageMetric<TFixedImage, TMovingImage>::DerivativeType&) const [with TFixedImage = itk::VectorImage<unsigned char, 3u>, TMovingImage = itk::VectorImage<unsigned char, 3u>]’
> /home/kevin/Documents/stg_anatomy/align_rot_vect.cxx:27:   instantiated from here
> /home/kevin/kitware/Insight/Code/Common/itkImageConstIteratorWithIndex.h:241: warning: returning reference to temporary
>
> Were these not meant to go together, 
No they are not, in their current state, although the fix is fairly easy.

The interpolator used (itk::VectorInterpolateImageFunction) is not 
designed to work with itk::VectorImage, because of certain assumptions 
it makes.

The fix is to replace this interpolator with your own interpolator that 
is designed to work with itk::VectorImage. The following might.. (not 
compiled..)

template <
class TInputImage,
class TCoordRep = float,
class TPixelType = ITK_TYPENAME TInputImage::PixelType
 >
class ITK_EXPORT VectorImageInterpolateImageFunction :
  public ImageFunction<
    TInputImage,
    VariableLengthVector< ITK_TYPENAME NumericTraits<typename 
TPixelType::ValueType>::RealType >,
    TCoordRep >
{
     /** Dimension underlying input image. */
  itkStaticConstMacro(ImageDimension, unsigned int,
                      TInputImage::ImageDimension);

  /** Standard class typedefs. */
  typedef VectorImageInterpolateImageFunction Self;
  typedef ImageFunction<TInputImage,
    VariableLengthVector<double >, TCoordRep > Superclass;
  typedef SmartPointer<Self> Pointer;
  typedef SmartPointer<const Self>  ConstPointer;
 
  /** Run-time type information (and related methods). */
  itkTypeMacro(VectorImageInterpolateImageFunction, ImageFunction);

  /** InputImageType typedef support. */
  typedef typename Superclass::InputImageType InputImageType;
  typedef typename InputImageType::PixelType  PixelType;
  typedef typename PixelType::ValueType       ValueType;
  typedef typename NumericTraits<ValueType>::RealType  RealType;
   

  /** Point typedef support. */
  typedef typename Superclass::PointType PointType;

  /** Index typedef support. */
  typedef typename Superclass::IndexType IndexType;

  /** ContinuousIndex typedef support. */
  typedef typename Superclass::ContinuousIndexType ContinuousIndexType;

  /** Output type is FixedArray<RealType,Dimension>. */
  typedef typename Superclass::OutputType OutputType;

  /** CoordRep typedef support. */
  typedef TCoordRep CoordRepType;

  /** Returns the interpolated image intensity at a
   * specified point position. No bounds checking is done.
   * The point is assume to lie within the image buffer.
   * ImageFunction::IsInsideBuffer() can be used to check bounds before
   * calling the method. */
  virtual OutputType Evaluate( const PointType& point ) const
    {
    ContinuousIndexType index;
    this->GetInputImage()->TransformPhysicalPointToContinuousIndex( 
point, index );
    return ( this->EvaluateAtContinuousIndex( index ) );
    }

  /** Interpolate the image at a continuous index position
   *
   * Returns the interpolated image intensity at a
   * specified index position. No bounds checking is done.
   * The point is assume to lie within the image buffer.
   *
   * Subclasses must override this method.
   *
   * ImageFunction::IsInsideBuffer() can be used to check bounds before
   * calling the method. */
  virtual OutputType EvaluateAtContinuousIndex(
    const ContinuousIndexType & index ) const = 0;

  /** Interpolate the image at an index position.
   * Simply returns the image value at the
   * specified index position. No bounds checking is done.
   * The point is assume to lie within the image buffer.
   *
   * ImageFunction::IsInsideBuffer() can be used to check bounds before
   * calling the method. */
  virtual OutputType EvaluateAtIndex( const IndexType & index ) const
    {
    PixelType input = this->GetInputImage()->GetPixel( index );
    OutputType output(input.GetSize());
    for( unsigned int k = 0; k < input.GetSize(); k++ )
      {
      output[k] = static_cast<double>( input[k] );
      }
    return ( output );
    }

protected:
  VectorImageInterpolateImageFunction() {}
  ~VectorImageInterpolateImageFunction() {}
  void PrintSelf(std::ostream& os, Indent indent) const
    { Superclass::PrintSelf( os, indent ); }

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

};


Try it out and please let us know.....

Also swap out the typedef for the interpolator in 
itk::VectorImageToImageMetric with this new interpolator.
> or did I do something stupid?
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users

-- 
--
Karthik Krishnan
R & D Engineer,
Kitware Inc,
Ph: +1 518 3713971 x119
Fax: +1 518 3714573



More information about the Insight-users mailing list