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