1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkNeighborhoodOperator.h,v $
Language: C++
Date: $Date: 2007-02-07 13:58:41 $
Version: $Revision: 1.28 $
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 __itkNeighborhoodOperator_h
#define __itkNeighborhoodOperator_h
#include "itkNeighborhood.h"
#include "itkExceptionObject.h"
#include "itkNumericTraits.h"
#include <vector>
namespace itk {
/** \class NeighborhoodOperator
* \brief Virtual class that defines a common interface to all
* neighborhood operator subtypes.
*
* A NeighborhoodOperator is a set of pixel values that can be applied to a
* Neighborhood to perform a user-defined operation (i.e. convolution kernel,
* morphological structuring element). A NeighborhoodOperator is itself a
* specialized Neighborhood, with functionality to generate its coefficients
* according to user-defined parameters. Because the operator is a subclass
* of Neighborhood, it is a valid operand in any of the operations
* defined on the Neighborhood object (convolution, inner product, etc.).
*
* NeighborhoodOperator is a pure virtual object that must be
* subclassed to be used. A user's subclass must implement two methods:
*
* (1) GenerateScalarCoefficients -- the algorithm that computes the scalar
* coefficients of the operator.
*
* (2) ScalarFill -- the algorithm that places the scalar coefficients into
* the memory buffer of the operator (arranges them spatially in the
* neighborhood).
*
* NeighborhoodOperator supports the concept of a "directional operator."
* A directional operator is defined in this context to be an operator
* that is applied along a single dimension. Examples of this type of
* operator are directional derivatives and the individual, directional
* components of separable processes such as Gaussian smoothing.
*
* How a NeighborhoodOperator is applied to data is up to the user who
* defines it. One possible use of an operator would be to take its
* inner product with a neighborhood of values to produce
* a scalar result. This process effects convolution when applied to
* successive neighborhoods across a region of interest in an image.
*
* \ingroup Operators
*/
template< class TPixel, unsigned int VDimension,
class TAllocator = NeighborhoodAllocator<TPixel> >
class ITK_EXPORT NeighborhoodOperator
: public Neighborhood<TPixel, VDimension, TAllocator>
{
public:
/** Standard class typedefs. */
typedef NeighborhoodOperator Self;
typedef Neighborhood<TPixel, VDimension, TAllocator> Superclass;
/** Size object typedef support */
typedef typename Superclass::SizeType SizeType;
/** External support for pixel type */
typedef TPixel PixelType;
/** Slice iterator typedef support */
typedef SliceIterator<TPixel, Self> SliceIteratorType;
/** Constructor. */
NeighborhoodOperator()
{ m_Direction = 0; }
/** Copy constructor */
NeighborhoodOperator(const Self &orig)
: Neighborhood<TPixel, VDimension, TAllocator>(orig)
{ m_Direction = orig.m_Direction; }
/** Assignment operator. */
Self &operator=( const Self &orig )
{
Superclass::operator=(orig);
m_Direction = orig.m_Direction;
return *this;
}
/** Sets the dimensional direction of a directional operator. */
void SetDirection(const unsigned long &direction)
{ m_Direction = direction; }
/** Returns the direction (dimension number) of a directional operator. */
unsigned long GetDirection() const
{ return m_Direction; }
/** Creates the operator with length only in the specified direction.
* The radius of the operator will be 0 except along the axis on which
* the operator will work.
* \sa CreateToRadius \sa FillCenteredDirectional \sa SetDirection() \sa GetDirection() */
virtual void CreateDirectional();
/** Creates the operator with a specified radius. The spatial location of
* the coefficients within the operator is defined by the subclass
* implementation of the Fill method.
* \sa CreateDirectional \sa Fill */
virtual void CreateToRadius(const SizeType &);
/** Creates the operator with a specified radius ("square", same length
* on each side). The spatial location of the coefficients within the
* operator is defined by the subclass implementation of the Fill method.
* \sa CreateDirectional \sa Fill */
virtual void CreateToRadius(const unsigned long);
/** Reverses the direction of all axes of the operator by reversing the order
* of the coefficients. */
virtual void FlipAxes();
/** Prints some debugging information. */
virtual void PrintSelf(std::ostream& os, Indent i) const
{
os << i << "NeighborhoodOperator { this=" << this
<< " Direction = " << m_Direction << " }" << std::endl;
Superclass::PrintSelf( os, i.GetNextIndent() );
}
typedef typename NumericTraits< TPixel >::RealType PixelRealType;
/** Multiplies all of the coefficients of the kernel by a single scalar value. */
void ScaleCoefficients( PixelRealType );
protected:
/** Typedef support for coefficient vector type. Necessary
* to fix bug in the microsoft VC++ compiler. */
typedef std::vector<double> CoefficientVector;
/** A subclass-specific algorithm that computes the coefficients
* of the operator. */
virtual CoefficientVector GenerateCoefficients() = 0;
/** A subclass-specific algorithm that positions the coefficients
* spatially in the operator. */
virtual void Fill(const CoefficientVector &) = 0;
/** A pre-defined Fill function that can be called by a subclass
* Fill function to center coefficients along the axis specified
* by the SetDirection method. Useful for creating directional
* operators, or centering coefficients in an N-dimensional
* neighborhood. */
virtual void FillCenteredDirectional(const CoefficientVector &);
/** Initializes all the coefficients in the neighborhood to zero values */
void InitializeToZero()
{
for (unsigned int i = 0; i< this->Size(); ++i)
{ this->operator[](i) = NumericTraits<PixelType>::Zero; }
}
private:
/** Direction (dimension number) of the derivative. */
unsigned long m_Direction;
};
} // namespace itk
// Define instantiation macro for this template.
#define ITK_TEMPLATE_NeighborhoodOperator(_, EXPORT, x, y) namespace itk { \
_(2(class EXPORT NeighborhoodOperator< ITK_TEMPLATE_2 x >)) \
namespace Templates { typedef NeighborhoodOperator< ITK_TEMPLATE_2 x > \
NeighborhoodOperator##y; } \
}
#if ITK_TEMPLATE_EXPLICIT
# include "Templates/itkNeighborhoodOperator+-.h"
#endif
#if ITK_TEMPLATE_TXX
# include "itkNeighborhoodOperator.txx"
#endif
/*
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkNeighborhoodOperator.txx"
#endif
*/
#endif
|