[Insight-developers] Operators with explicitly specified coefficients

Gunnar Farnebäck gunnar at bwh.harvard.edu
Fri Jul 2 14:57:43 EDT 2004


I'm trying to implement yet another variation of the demons
registration algorithm in ITK. As part of the implementation I needed
a set of directional filters with specific coefficients
(algorithmically computed). I didn't find a simple way to create my
filters, however. The most straightforward way I could see would be to
subclass NeighborhoodOperator and implement a GenerateCoefficients()
method which computes the coefficients, but this would be rather
inconvenient since it's in my case natural to compute the coefficients
of all the filters at the same time, rather than one at a time.

Instead I wrote a subclass of NeighborhoodOperator called
DirectionalOperator, which is constructed with an explicit vector of
coefficients and a direction. I imagine I'm not the only one who may
want this functionality, so I submit it for inclusion into ITK.

However, I'm not sure I've managed to pick up all of the ITK design
ideas, so it's possible that this class doesn't really fit. If so,
please tell me if there's some better way to solve my problem (or ask
me to clarify if it's unclear what I want). In any case I expect that
there are various shortcomings in the code, so feel free to point
those out to me.

New file Insight/Code/Common/itkDirectionalOperator.h attached.

/Gunnar Farnebäck

Harvard Medical School            Brigham and Women's Hospital
Tel : (+1) 617-732-5931           Department of Radiology
Fax : (+1) 617-264-6887           Boston, MA 02115
Email: gunnar at bwh.harvard.edu     USA
-------------- next part --------------
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkDirectionalOperator.h,v $
  Language:  C++
  Date:      $Date: 2003/09/10 14:29:09 $
  Version:   $Revision: 1.22 $

  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 __itkDirectionalOperator_h
#define __itkDirectionalOperator_h

#include "itkNeighborhoodOperator.h"
namespace itk {

/**
 * \class DirectionalOperator
 * \brief A NeighborhoodOperator for one dimensional directional
 * kernels with explicitly specified coefficients.
 *
 * DirectionalOperator can be used to perform directional filtering
 * by taking its inner product with a Neighborhood
 * (NeighborhoodIterator) that is swept across an image region.
 *
 * DirectionalOperator takes two parameters:
 *
 * (1) The direction of the operator.
 *
 * (2) The coefficients of the filter.
 *
 * \sa NeighborhoodOperator
 * \sa NeighborhoodIterator
 * \sa Neighborhood
 *
 * \ingroup Operators
 */
template<class TPixel, unsigned int VDimension = 2,
         class TAllocator = NeighborhoodAllocator<TPixel> >
class ITK_EXPORT DirectionalOperator
  : public NeighborhoodOperator<TPixel, VDimension, TAllocator>
{
public:
  /** Standard class typedefs. */
  typedef DirectionalOperator Self;
  typedef NeighborhoodOperator<TPixel, VDimension, TAllocator>  Superclass;
  
  /** Constructor setting the direction of the operator. */
  DirectionalOperator(int direction)
  {
    SetDirection(direction);
  }
  
  /** Constructor setting both direction and coefficients of the operator. */
  DirectionalOperator(int direction, const std::vector<double> coeffs)
  {
    SetDirection(direction);
    m_Coeffs = coeffs;
    CreateDirectional();
  }

  /** Copy constructor. */
  DirectionalOperator(const Self &other)
    : NeighborhoodOperator<TPixel, VDimension, TAllocator>(other)
  {
    m_Coeffs = other.m_Coeffs;
    CreateDirectional();
  }

  /** Assignment operator. */
  Self &operator=(const Self &other)
  {
    Superclass::operator=(other);
    m_Coeffs = other.m_Coeffs;
    return *this;
  }
  
  /** Sets the kernel coefficients. */
  void SetCoeffs(const std::vector<double> coeffs)
  {
    m_Coeffs = coeffs;
  }

  /** Returns the kernel coefficients. */
  std::vector<double> GetCoeffs() const
  {
    return m_Coeffs;
  }
  
  /** Prints some debugging information. */
  void PrintSelf(std::ostream &os, Indent i) const
  {
    os << i << "DirectionalOperator { this=" << this
       << ", m_Coeffs =";
    for (int k = 0; k < m_Coeffs.size(); k++)
      os << " " << m_Coeffs[k];
    os << "} " << std::endl;
    Superclass::PrintSelf(os, i.GetNextIndent());
  }
  
protected:
  typedef typename Superclass::CoefficientVector CoefficientVector;

  /** Calculates operator coefficients. */
  CoefficientVector GenerateCoefficients()
  {
    return m_Coeffs;
  }

  /** Arranges coefficients spatially in the memory buffer. */
  void Fill(const CoefficientVector& coeff)
  {
    this->FillCenteredDirectional(coeff);
  }

private:
  /** Filter coefficients. */
  CoefficientVector m_Coeffs;
  
  /** For compatibility with itkWarningMacro. */
  const char *GetNameOfClass()
  {
    return "itkDirectionalOperator";
  }
  
};

} // namespace itk


#ifndef ITK_MANUAL_INSTANTIATION
#endif

#endif


More information about the Insight-developers mailing list