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