[Insight-users] How to multiply a vector image by a constant

Luis Ibanez luis.ibanez at kitware.com
Thu, 22 Jan 2004 14:20:29 -0500


This is a multi-part message in MIME format.
--------------050507000903080404080204
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi Glen,

ITK currently doesn't have a simple filter for
multiplying a vector image by a constant,..
but you can fabricate one in 10 minutes from the
itkCastVectorImageFilter. Actually, here is one
filter attached that should do the job.

In general, for any pixel-wise operation you can
simply look at using the UnaryFunctorFilter and
define your own Functor as template parameter.

---

An alternative option is to use ImageAdaptors.
You will find examples of ImageAdaptors in the
SoftwareGuide

    http://www.itk.org/ItkSoftwareGuide.pdf

Chapter 12, pdf-page 521. In particular, look
at the vectorial examples in Section 12.3 and
the computation example in section 12.4.

The great advantage of image adaptors is that
you don't pay for the memory overhead of storing
a new vector image, just because you multiply the
values by a constant.

The PixelAccessor will look like:


class VectorScalePixelAccessor
{
public:
   typedef itk::Vector<float,3>   InternalType;
   typedef itk::Vector<float,3>   ExternalType;

   void operator=( const VectorPixelAccessor & vpa )
     {
       m_Factor = vpa.m_Factor;
     }
   ExternalType Get( const InternalType & input ) const
     {
       return ( input * m_Factor );
     }
   void SetFactor( double factor )
     {
       m_Factor = factor;
     }
private:
   double  m_Factor;
};



Then, as shown in the software guide you create
the ImageAdaptor by using the PixelAccessor as
template argument.


   typedef itk::ImageAdaptor<
                       VectorImageType,
                       VectorPixelAccessor
                                > ImageAdaptorType;


Then you create the accessor,
set the factor value
and pass it to the adaptor


   VectorScalePixelAccessor  accessor;
   accessor.SetFactor( 12345.0 );
   adaptor->SetPixelAccessor( accessor );


and simply plug the adaptor as input to the
next filter in the pipeline.


Note that adaptors look like images, not like
filters, so there is no need for GetOutput() when
you connect the adaptor to the next filter in the
pipeline.



Regards,


   Luis


---------------------
Glen Lehmann wrote:

> Hello,
> 
> Sorry, I couldn't find an answer for this one in the archives.
> 
> I have a VectorImageType defined as;
> 
> typedef   double  PixelType;
> typedef   itk::Vector< PixelType, 2 > VectorType;
> typedef   itk::Image< PixelType, 2 >  ImageType;
> typedef   itk::Image< VectorType, 2 >  VectorImageType;
> 
> I need to multiply my VectorImage by a constant.  If I were using 
> ImageType I chould use the ShiftScaleImageFilter and set Scale as my 
> constant.  I have tried the following with the VectorImageType;
> 
> typedef   itk::ShiftScaleImageFilter < VectorImageType, VectorImageType 
>  > ShiftScaleFilterType;
> 
> The following line causes the compilere to complain that RealType is not 
> defined;
> 
> ShiftScaleFilterType::Pointer NegativeVectorImage = 
> ShiftScaleFilterType::New();
> 
> Any suggestions as to how to multiply my VectorImageType by a constant 
> would be appreciated.
> 
> Thank you,
> Glen
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
> 
--------------------------------------------------------







--------------050507000903080404080204
Content-Type: text/plain;
 name="itkVectorScaleImageFilter.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="itkVectorScaleImageFilter.h"

/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkVectorScaleImageFilter.h,v $
  Language:  C++
  Date:      $Date: 2003/09/10 14:28:59 $
  Version:   $Revision: 1.10 $

  Copyright (c) Insight Software 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 __itkVectorScaleImageFilter_h
#define __itkVectorScaleImageFilter_h

#include "itkUnaryFunctorImageFilter.h"

namespace itk
{
  
/** \class VectorScaleImageFilter
 *
 * \brief Multiplies input vector pixels by a constant factor and produces 
 * as output an image of vector pixel type.
 *
 * The filter expect both images to have the same number of dimensions,
 * and that both the input and output have itk::Vector pixel types
 * of the same VectorDimension.
 *
 * \sa Vector
 *
 * \ingroup IntensityImageFilters  Multithreaded
 */
namespace Functor {  
  
template< class TInput, class TOutput>
class VectorScale
{
public:
  VectorScale() {}
  ~VectorScale() {}
  inline TOutput operator()( const TInput & A ) const
  {
    typedef typename TOutput::ValueType OutputValueType;

    TOutput value;
    for( unsigned int k = 0; k < TOutput::Dimension; k++ )
      { value[k] = static_cast<OutputValueType>( A[k] * m_Factor ); }
    return value;
  }
  void SetFactor( double factor )
    {
    m_Factor = factor;
    }

private:
  double m_Factor;
}; 
}

template <class TInputImage, class TOutputImage>
class ITK_EXPORT VectorScaleImageFilter :
    public
UnaryFunctorImageFilter<TInputImage,TOutputImage, 
                        Functor::VectorScale< typename TInputImage::PixelType, 
                                             typename TOutputImage::PixelType>   >
{
public:
  /** Standard class typedefs. */
  typedef VectorScaleImageFilter  Self;
  typedef UnaryFunctorImageFilter<TInputImage,TOutputImage, 
                                  Functor::VectorScale< typename TInputImage::PixelType, 
                                                       typename TOutputImage::PixelType> >  Superclass;
  typedef SmartPointer<Self>   Pointer;
  typedef SmartPointer<const Self>  ConstPointer;

  /** Method for creation through the object factory. */
  itkNewMacro(Self);

  /** factor to use for multiplying the vectors */  
  void SetFactor( double factor )
   {
   this->GetFunctor().SetFactor( factor );
   }

protected:
  VectorScaleImageFilter() {}
  virtual ~VectorScaleImageFilter() {}

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

};

} // end namespace itk


#endif

--------------050507000903080404080204--