1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2017 Imperial College London
5  * Copyright 2017 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_SeparableConvolution_H
21 #define MIRTK_SeparableConvolution_H
22 
23 #include "mirtk/GenericImage.h"
24 #include "mirtk/ImageToImage.h"
25 
26 
27 namespace mirtk {
28 
29 
30 /**
31  * Generic filter for convolution of an image with a separable kernel
32  */
33 template <class TVoxel, class TKernel = RealPixel>
34 class SeparableConvolution : public ImageToImage<TVoxel>
35 {
36   mirtkInPlaceImageFilterMacro(SeparableConvolution, TVoxel);
37 
38 public:
39 
40   /// Type of convolution kernel
41   typedef GenericImage<TKernel> KernelType;
42 
43 protected:
44 
45   /// Convolution kernel along x axis
46   mirtkPublicAggregateMacro(const KernelType, KernelX);
47 
48   /// Convolution kernel along y axis
49   mirtkPublicAggregateMacro(const KernelType, KernelY);
50 
51   /// Convolution kernel along z axis
52   mirtkPublicAggregateMacro(const KernelType, KernelZ);
53 
54   /// Convolution kernel along t axis
55   mirtkPublicAggregateMacro(const KernelType, KernelT);
56 
57   /// Whether to normalize kernels
58   mirtkPublicAttributeMacro(bool, Normalize);
59 
60   /// Whether to truncate convolution at background specified by image mask
61   ///
62   /// When this option is set and the image has a background mask, unmasked
63   /// values of the convolution sum (i.e., background values) are ignored.
64   mirtkPublicAttributeMacro(bool, UseBackgroundMask);
65 
66   /// Whether to truncate convolution at input background value if set
67   ///
68   /// This option is ignored when UseBackgroundMask is set and the image
69   /// has a background mask image set.
70   mirtkPublicAttributeMacro(bool, UseBackgroundValue);
71 
72   /// Whether to use padding value
73   ///
74   /// This option is ignored when UseBackgroundMask is set and the image
75   /// has a background mask image set.
76   ///
77   /// When also UseBackground is set, the padding value is used instead
78   /// when the image has a background value set. Otherwise the padding
79   /// value is used when this option is turned on.
80   mirtkPublicAttributeMacro(bool, UsePaddingValue);
81 
82   /// Padding value
83   mirtkPublicAttributeMacro(double, PaddingValue);
84 
85   /// Number of vector components of input image to convolve
86   ///
87   /// By default, when the input image as temporal voxel size 0, each
88   /// vector component stored in the temporal dimension is convolved
89   /// separately. When this attribute is set to a positive value,
90   /// only the first vector components up to the specified number
91   /// of components are being convolved, and the output image may
92   /// have less vector components stored in the temporal dimension
93   /// than the input image.
94   mirtkPublicAttributeMacro(int, Components);
95 
96 protected:
97 
98   /// Initialize filter
99   virtual void Initialize();
100 
101   /// Finalize filter
102   virtual void Finalize();
103 
104 public:
105 
106   /// Constructor
107   ///
108   /// \param[in] k Isotropic 1D convolution kernel.
109   SeparableConvolution(const KernelType *k = nullptr);
110 
111   /// Constructor
112   ///
113   /// \param[in] kx Convolution kernel along x axis.
114   /// \param[in] ky Convolution kernel along y axis.
115   /// \param[in] kz Convolution kernel along z axis.
116   /// \param[in] kt Convolution kernel along t axis.
117   SeparableConvolution(const KernelType *kx,
118                        const KernelType *ky,
119                        const KernelType *kz = nullptr,
120                        const KernelType *kt = nullptr);
121 
122   /// Destructor
123   ~SeparableConvolution();
124 
125   /// Set isotropic convolution kernel for all dimensions
126   void Kernel(const KernelType *);
127 
128   /// Check if given kernel is valid
129   bool CheckKernel(const KernelType *) const;
130 
131   /// Convolve image
132   virtual void Run();
133 
134   /// Convolve image along x only
135   virtual void RunX();
136 
137   /// Convolve image along y only
138   virtual void RunY();
139 
140   /// Convolve image along z only
141   virtual void RunZ();
142 
143   /// Convolve image along t only
144   virtual void RunT();
145 
146 };
147 
148 
149 } // namespace mirtk
150 
151 #endif // MIRTK_SeparableConvolution_H
152