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 itkSobelOperator_h 19 #define itkSobelOperator_h 20 21 #include "itkNeighborhoodOperator.h" 22 23 namespace itk 24 { 25 /** 26 * \class SobelOperator 27 * 28 * \brief A NeighborhoodOperator for performing a directional Sobel 29 * edge-detection operation at a pixel location. 30 * 31 * SobelOperator is a directional NeighborhoodOperator that should be 32 * applied a NeighborhoodIterator using the NeighborhoodInnerProduct 33 * method. To create the operator: 34 * 35 * 1) Set the direction by calling \code SetDirection \endcode 36 * 2) call 37 \code 38 itk::Size<2> radius; 39 radius.Fill(1); 40 sobelOperator.CreateToRadius(radius); 41 \endcode 42 * 3) You may optionally scale the coefficients of this operator using the 43 * \code ScaleCoefficients \endcode method. This is useful if you 44 * want to take the spacing of the image into account when computing 45 * the edge strength. Apply the scaling only after calling to 46 * \code CreateToRadius \endcode. 47 * 48 * The Sobel Operator in vertical direction for 2 dimensions is 49 * \verbatim 50 * -1 -2 -1 51 * 0 0 0 52 * 1 2 1 53 * 54 * \endverbatim 55 * The Sobel Operator in horizonal direction is for 2 dimensions is 56 * \verbatim 57 * -1 0 1 58 * -2 0 2 59 * -1 0 1 60 * \endverbatim 61 * 62 * The current implementation of the Sobel operator is for 2 and 3 dimensions only. 63 * The ND version is planned for future releases. 64 * 65 * The extension to 3D is from the publication 66 * "Irwin Sobel. An Isotropic 3x3x3 Volume Gradient Operator. 67 * Technical report, Hewlett-Packard Laboratories, April 1995." 68 * 69 * The Sobel operator in 3D has the kernel 70 * 71 * \verbatim 72 * -1 -3 -1 0 0 0 1 3 1 73 * -3 -6 -3 0 0 0 3 6 3 74 * -1 -3 -1 0 0 0 1 3 1 75 * 76 * x-1 x x+1 77 * \endverbatim 78 * 79 * The \c x kernel is just rotated as required to obtain the kernel in the 80 * \c y and \c z directions. 81 * 82 * \sa NeighborhoodOperator 83 * \sa Neighborhood 84 * \sa ForwardDifferenceOperator 85 * \sa BackwardDifferenceOperator 86 * 87 * \ingroup Operators 88 * \ingroup ITKCommon 89 * 90 * \wiki 91 * \wikiexample{Operators/SobelOperator,Create the Sobel kernel} 92 * \endwiki 93 */ 94 template< typename TPixel, unsigned int VDimension = 2, 95 typename TAllocator = NeighborhoodAllocator< TPixel > > 96 class ITK_TEMPLATE_EXPORT SobelOperator: 97 public NeighborhoodOperator< TPixel, VDimension, TAllocator > 98 { 99 public: 100 /** Standard type alias */ 101 using Self = SobelOperator; 102 using Superclass = NeighborhoodOperator< TPixel, VDimension, TAllocator >; 103 104 itkTypeMacro(SobelOperator, NeighborhoodOperator); 105 106 SobelOperator() = default; SobelOperator(const Self & other)107 SobelOperator(const Self & other): 108 NeighborhoodOperator< TPixel, VDimension, TAllocator >(other) 109 {} 110 111 /** Creates the operator with length only in the specified direction. For 112 * the Sobel operator, this 113 * The radius of the operator will be 0 except along the axis on which 114 * the operator will work. 115 * \sa CreateToRadius \sa FillCenteredDirectional \sa SetDirection() \sa GetDirection() */ CreateDirectional()116 void CreateDirectional() override 117 { 118 this->CreateToRadius(1); 119 } 120 121 /** Creates the operator with a specified radius ("square", same length 122 * on each side). The spatial location of the coefficients within the 123 * operator is defined by the subclass implementation of the Fill method. 124 * \sa CreateDirectional \sa Fill */ 125 // virtual void CreateToRadius(const unsigned long); 126 /** 127 * Assignment operator 128 */ 129 Self & operator=(const Self & other) 130 { 131 Superclass::operator=(other); 132 return *this; 133 } 134 135 /** 136 * Prints some debugging information 137 */ PrintSelf(std::ostream & os,Indent i)138 void PrintSelf(std::ostream & os, Indent i) const override 139 { 140 os << i << "SobelOperator { this=" << this << "}" << std::endl; 141 Superclass::PrintSelf( os, i.GetNextIndent() ); 142 } 143 144 protected: 145 /** 146 * Typedef support for coefficient vector type. Necessary to 147 * work around compiler bug on VC++. 148 */ 149 using CoefficientVector = typename Superclass::CoefficientVector; 150 using PixelType = typename Superclass::PixelType; 151 152 /** 153 * Calculates operator coefficients. 154 */ 155 CoefficientVector GenerateCoefficients() override; 156 157 /** 158 * Arranges coefficients spatially in the memory buffer. 159 */ 160 void Fill(const CoefficientVector & c) override; 161 }; 162 } // namespace itk 163 164 #ifndef ITK_MANUAL_INSTANTIATION 165 #include "itkSobelOperator.hxx" 166 #endif 167 168 #endif 169