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_hxx
19 #define itkSobelOperator_hxx
20
21 #include "itkSobelOperator.h"
22 #include "itkObject.h"
23
24 namespace itk
25 {
26 template< typename TPixel, unsigned int VDimension, typename TAllocator >
27 void
28 SobelOperator< TPixel, VDimension, TAllocator >
Fill(const CoefficientVector & coeff)29 ::Fill(const CoefficientVector & coeff)
30 {
31 this->InitializeToZero();
32
33 // Note that this code is only good for 2d and 3d operators. Places the
34 // coefficients in the exact center of the neighborhood
35 unsigned int i;
36 int x, y, z, pos;
37 unsigned int center = this->GetCenterNeighborhoodIndex();
38
39 if ( VDimension == 3 )
40 {
41 i = 0;
42 for ( z = -1; z <= 1; z++ )
43 {
44 for ( y = -1; y <= 1; y++ )
45 {
46 for ( x = -1; x <= 1; x++ )
47 {
48 pos = center + z *this->GetStride(2) + y *this->GetStride(1)
49 + x *this->GetStride(0);
50 this->operator[](pos) = static_cast< TPixel >( coeff[i] );
51
52 i++;
53 }
54 }
55 }
56 }
57 else if ( VDimension == 2 )
58 {
59 i = 0;
60 for ( y = -1; y <= 1; y++ )
61 {
62 for ( x = -1; x <= 1; x++ )
63 {
64 pos = center + y *this->GetStride(1) + x *this->GetStride(0);
65 this->operator[](pos) = static_cast< TPixel >( coeff[i] );
66
67 i++;
68 }
69 }
70 }
71 else
72 {
73 itkExceptionMacro(
74 <<
75 "The ND version of the Sobel operator is not yet implemented. Currently only the 2D and 3D versions are available.");
76 }
77 }
78
79 template< typename TPixel, unsigned int VDimension, typename TAllocator >
80 typename SobelOperator< TPixel, VDimension, TAllocator >
81 ::CoefficientVector
82 SobelOperator< TPixel, VDimension, TAllocator >
GenerateCoefficients()83 ::GenerateCoefficients()
84 {
85 std::vector< double > coeff;
86 if ( VDimension == 2 && this->GetDirection() == 0 )
87 {
88 coeff.push_back(-1.0); coeff.push_back(0.0); coeff.push_back(1.0);
89 coeff.push_back(-2.0); coeff.push_back(0.0); coeff.push_back(2);
90 coeff.push_back(-1.0); coeff.push_back(0.0); coeff.push_back(1.0);
91 }
92 else if ( VDimension == 2 && this->GetDirection() == 1 )
93 {
94 coeff.push_back(-1.0); coeff.push_back(-2); coeff.push_back(-1.0);
95 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
96 coeff.push_back(1.0); coeff.push_back(2); coeff.push_back(1.0);
97 }
98 else if ( VDimension == 3 && this->GetDirection() == 0 )
99 {
100 coeff.push_back(-1.0); coeff.push_back(0.0); coeff.push_back(1.0);
101 coeff.push_back(-3.0); coeff.push_back(0.0); coeff.push_back(3.0);
102 coeff.push_back(-1.0); coeff.push_back(0.0); coeff.push_back(1.0);
103
104 coeff.push_back(-3.0); coeff.push_back(0.0); coeff.push_back(3.0);
105 coeff.push_back(-6.0); coeff.push_back(0.0); coeff.push_back(6.0);
106 coeff.push_back(-3.0); coeff.push_back(0.0); coeff.push_back(3.0);
107
108 coeff.push_back(-1.0); coeff.push_back(0.0); coeff.push_back(1.0);
109 coeff.push_back(-3.0); coeff.push_back(0.0); coeff.push_back(3.0);
110 coeff.push_back(-1.0); coeff.push_back(0.0); coeff.push_back(1.0);
111 }
112 else if ( VDimension == 3 && this->GetDirection() == 1 )
113 {
114 coeff.push_back(-1.0); coeff.push_back(-3.0); coeff.push_back(-1.0);
115 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
116 coeff.push_back(1.0); coeff.push_back(3.0); coeff.push_back(1.0);
117
118 coeff.push_back(-3.0); coeff.push_back(-6.0); coeff.push_back(-3.0);
119 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
120 coeff.push_back(3.0); coeff.push_back(6.0); coeff.push_back(3.0);
121
122 coeff.push_back(-1.0); coeff.push_back(-3.0); coeff.push_back(-1.0);
123 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
124 coeff.push_back(1.0); coeff.push_back(3.0); coeff.push_back(1.0);
125 }
126 else if ( VDimension == 3 && this->GetDirection() == 2 )
127 {
128 coeff.push_back(-1.0); coeff.push_back(-3.0); coeff.push_back(-1.0);
129 coeff.push_back(-3.0); coeff.push_back(-6.0); coeff.push_back(-3.0);
130 coeff.push_back(-1.0); coeff.push_back(-3.0); coeff.push_back(-1.0);
131
132 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
133 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
134 coeff.push_back(0.0); coeff.push_back(0.0); coeff.push_back(0.0);
135
136 coeff.push_back(1.0); coeff.push_back(3.0); coeff.push_back(1.0);
137 coeff.push_back(3.0); coeff.push_back(6.0); coeff.push_back(3.0);
138 coeff.push_back(1.0); coeff.push_back(3.0); coeff.push_back(1.0);
139 }
140 else
141 {
142 itkExceptionMacro(
143 <<
144 "The ND version of the Sobel operator has not been implemented. Currently only 2D and 3D versions are available.");
145 }
146
147 return coeff;
148 }
149 } // namespace itk
150
151 #endif
152