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