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_hxx
19 #define itkNeighborhoodOperator_hxx
20
21 #include "itkNeighborhoodOperator.h"
22 #include "itkIntTypes.h"
23
24 namespace itk
25 {
26 template< typename TPixel, unsigned int VDimension, typename TAllocator >
27 void
28 NeighborhoodOperator< TPixel, VDimension, TAllocator >
ScaleCoefficients(PixelRealType s)29 ::ScaleCoefficients(PixelRealType s)
30 {
31 for ( unsigned i = 0; i < this->Size(); i++ )
32 {
33 this->operator[](i) = static_cast< TPixel >( this->operator[](i) * s );
34 }
35 }
36
37 template< typename TPixel, unsigned int VDimension, typename TAllocator >
38 void
39 NeighborhoodOperator< TPixel, VDimension, TAllocator >
FlipAxes()40 ::FlipAxes()
41 {
42 // To flip the operator across all of its axes, all we have to do is reverse
43 // the order of all coefficients.
44 const unsigned size = this->Size();
45 PixelType temp;
46
47 for ( unsigned i = 0; i < size / 2; ++i )
48 {
49 unsigned swap_with = size - 1 - i;
50 temp = this->operator[](i);
51
52 this->operator[](i) = this->operator[](swap_with);
53
54 this->operator[](swap_with) = temp;
55 }
56 }
57
58 template< typename TPixel, unsigned int VDimension, typename TAllocator >
59 void
60 NeighborhoodOperator< TPixel, VDimension, TAllocator >
CreateDirectional()61 ::CreateDirectional()
62 {
63 SizeValueType k[VDimension];
64 CoefficientVector coefficients;
65
66 coefficients = this->GenerateCoefficients();
67 for ( unsigned int i = 0; i < VDimension; ++i )
68 {
69 if ( i == this->GetDirection() )
70 {
71 k[i] = static_cast< SizeValueType >( coefficients.size() ) >> 1;
72 }
73 else
74 {
75 k[i] = 0;
76 }
77 }
78 this->SetRadius(k);
79 this->Fill(coefficients);
80 }
81
82 template< typename TPixel, unsigned int VDimension, typename TAllocator >
83 void
84 NeighborhoodOperator< TPixel, VDimension, TAllocator >
CreateToRadius(const SizeType & sz)85 ::CreateToRadius(const SizeType & sz)
86 {
87 CoefficientVector coefficients;
88
89 coefficients = this->GenerateCoefficients();
90 this->SetRadius(sz);
91 this->Fill(coefficients);
92 }
93
94 template< typename TPixel, unsigned int VDimension, typename TAllocator >
95 void
96 NeighborhoodOperator< TPixel, VDimension, TAllocator >
CreateToRadius(const SizeValueType sz)97 ::CreateToRadius(const SizeValueType sz)
98 {
99 SizeType k;
100
101 for ( unsigned int i = 0; i < VDimension; i++ )
102 {
103 k[i] = sz;
104 }
105 this->CreateToRadius(k);
106 }
107
108 template< typename TPixel, unsigned int VDimension, typename TAllocator >
109 void
110 NeighborhoodOperator< TPixel, VDimension, TAllocator >
FillCenteredDirectional(const CoefficientVector & coeff)111 ::FillCenteredDirectional(const CoefficientVector & coeff)
112 {
113 // Initialize all coefficients to zero
114 this->InitializeToZero();
115
116 // Collect slice information
117 unsigned long start=0;
118 const unsigned long stride = this->GetStride(m_Direction);
119 const unsigned long size = this->GetSize(m_Direction);
120 for ( unsigned int i = 0; i < VDimension; ++i )
121 {
122 if ( i != m_Direction )
123 {
124 start += this->GetStride(i) * ( this->GetSize(i) >> 1 );
125 }
126 }
127
128 // Compare the neighborhood size with the coefficient array size..
129 const int sizediff = ( (int)size - (int)coeff.size() ) >> 1;
130
131 // Create a slice iterator centered in the neighborhood.
132 std::slice * temp_slice;
133 typename CoefficientVector::const_iterator it;
134 if ( sizediff >= 0 )
135 {
136 temp_slice = new std::slice(start + sizediff * stride, coeff.size(),
137 stride);
138 it = coeff.begin();
139 }
140 else
141 {
142 temp_slice = new std::slice(start, size, stride);
143 it = coeff.begin() - sizediff;
144 }
145
146 SliceIteratorType data(this, *temp_slice);
147 delete temp_slice;
148
149 // Copy the coefficients into the neighborhood, truncating them if there
150 // are too many.
151 for ( data = data.Begin(); data < data.End(); ++data, ++it )
152 {
153 *data = static_cast< TPixel >( *it );
154 }
155 }
156 } // namespace itk
157
158 #endif
159