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 itkImageKernelOperator_hxx
19 #define itkImageKernelOperator_hxx
20 
21 #include "itkImageKernelOperator.h"
22 
23 #include "itkImageRegionConstIterator.h"
24 
25 /*
26  *
27  * This code was contributed in the Insight Journal paper:
28  *
29  * "Image Kernel Convolution"
30  * by Tustison N., Gee J.
31  * https://hdl.handle.net/1926/1323
32  * http://www.insight-journal.org/browse/publication/208
33  *
34  */
35 
36 namespace itk
37 {
38 
39 template< typename TPixel, unsigned int VDimension, typename TAllocator >
40 void
41 ImageKernelOperator< TPixel, VDimension, TAllocator >
SetImageKernel(const ImageType * kernel)42 ::SetImageKernel(const ImageType *kernel)
43 {
44   m_ImageKernel = kernel;
45 }
46 
47 template< typename TPixel, unsigned int VDimension, typename TAllocator >
48 const typename ImageKernelOperator< TPixel, VDimension, TAllocator >::ImageType *
49 ImageKernelOperator< TPixel, VDimension, TAllocator >
GetImageKernel() const50 ::GetImageKernel() const
51 {
52   return m_ImageKernel;
53 }
54 
55 template< typename TPixel, unsigned int VDimension, typename TAllocator >
56 typename ImageKernelOperator< TPixel, VDimension, TAllocator >::CoefficientVector
57 ImageKernelOperator< TPixel, VDimension, TAllocator >
GenerateCoefficients()58 ::GenerateCoefficients()
59 {
60   // Check that the input image is fully buffered.
61   if ( m_ImageKernel->GetBufferedRegion() != m_ImageKernel->GetLargestPossibleRegion() )
62     {
63     itkExceptionMacro( << "ImageKernel is not fully buffered. " << std::endl
64                        << "Buffered region: " << m_ImageKernel->GetBufferedRegion()
65                        << std::endl
66                        << "Largest possible region: " << m_ImageKernel->GetLargestPossibleRegion()
67                        << std::endl
68                        << "You should call UpdateLargestPossibleRegion() on "
69                        << "the filter whose output is passed to "
70                        << "SetImageKernel()." );
71     }
72 
73   // Check that the size of the kernel is odd in all dimensions.
74   for ( unsigned int i = 0; i < VDimension; i++)
75     {
76     if ( m_ImageKernel->GetLargestPossibleRegion().GetSize()[i] % 2 == 0 )
77       {
78       itkExceptionMacro( << "ImageKernelOperator requires an input image "
79                          << "whose size is odd in all dimensions. The provided "
80                          << "image has size "
81                          << m_ImageKernel->GetLargestPossibleRegion().GetSize() );
82       }
83     }
84 
85   CoefficientVector coeff;
86 
87   ImageRegionConstIterator< ImageType > It( m_ImageKernel,
88                                             m_ImageKernel->GetLargestPossibleRegion() );
89 
90   for ( It.GoToBegin(); !It.IsAtEnd(); ++It )
91     {
92     coeff.push_back( It.Get() );
93     }
94 
95   return coeff;
96 }
97 
98 template< typename TPixel, unsigned int VDimension, typename TAllocator >
99 void
100 ImageKernelOperator< TPixel, VDimension, TAllocator >
Fill(const CoefficientVector & coeff)101 ::Fill(const CoefficientVector & coeff)
102 {
103   // Initialize all coefficients to zero
104   this->InitializeToZero();
105 
106   std::slice *temp_slice;
107   typename CoefficientVector::const_iterator it;
108 
109   temp_slice = new std::slice(0, coeff.size(), 1);
110   it = coeff.begin();
111 
112   typename Superclass::SliceIteratorType data(this, *temp_slice);
113   delete temp_slice;
114 
115   // Copy the coefficients into the neighborhood, truncating them if there
116   // are too many.
117   for ( data = data.Begin(); data < data.End(); ++data, ++it )
118     {
119     *data = static_cast< TPixel >( *it );
120     }
121 }
122 } // end namespace itk
123 
124 #endif
125