LinearImageGradientFunction.hxx
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 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_LinearImageGradientFunction_HXX
21 #define MIRTK_LinearImageGradientFunction_HXX
22 
23 #include "mirtk/Math.h"
24 #include "mirtk/LinearImageGradientFunction.h"
25 #include "mirtk/ImageGradientFunction.hxx"
26 #include "mirtk/LinearInterpolateImageFunction.hxx"
27 
28 
29 namespace mirtk {
30 
31 
32 // =============================================================================
33 // Construction/Destruction
34 // =============================================================================
35 
36 // -----------------------------------------------------------------------------
37 template <class TImage>
40 {
41 }
42 
43 // -----------------------------------------------------------------------------
44 template <class TImage>
47 {
48 }
49 
50 // -----------------------------------------------------------------------------
51 template <class TImage>
53 {
54  /// Initialize base class
55  Superclass::Initialize(coeff);
56 
57  // Domain on which linear interpolation is defined: [.5, x-.5)
58  switch (this->NumberOfDimensions()) {
59  case 3:
60  this->_z1 = .5;
61  this->_z2 = fdec(this->Input()->Z() - 1.5);
62  default:
63  this->_y1 = .5;
64  this->_y2 = fdec(this->Input()->Y() - 1.5);
65  this->_x1 = .5;
66  this->_x2 = fdec(this->Input()->X() - 1.5);
67  }
68 
69  // Initialize interpolator
70  _ContinuousImage.Input(this->Input());
71  _ContinuousImage.Initialize(coeff);
72 }
73 
74 // =============================================================================
75 // Domain checks
76 // =============================================================================
77 
78 // -----------------------------------------------------------------------------
79 template <class TImage>
81 ::BoundingInterval(double x, int &i, int &I) const
82 {
83  i = ifloor(x - .5), I = i + 2;
84 }
85 
86 // =============================================================================
87 // Evaluation
88 // =============================================================================
89 
90 // -----------------------------------------------------------------------------
91 template <class TImage>
94 ::GetInside2D(double x, double y, double z, double t) const
95 {
96  GradientType val;
97  val._x = _ContinuousImage.GetInside(x + .5, y, z, t) -
98  _ContinuousImage.GetInside(x - .5, y, z, t);
99  val._y = _ContinuousImage.GetInside(x, y + .5, z, t) -
100  _ContinuousImage.GetInside(x, y - .5, z, t);
101  return val;
102 }
103 
104 // -----------------------------------------------------------------------------
105 template <class TImage>
108 ::GetWithPaddingInside2D(double x, double y, double z, double t) const
109 {
110  GradientType val;
111  VoxelType a, b;
112 
113  a = _ContinuousImage.GetWithPaddingInside(x - .5, y, z, t);
114  if (a == _ContinuousImage.DefaultValue()) return this->DefaultValue();
115  b = _ContinuousImage.GetWithPaddingInside(x + .5, y, z, t);
116  if (b == _ContinuousImage.DefaultValue()) return this->DefaultValue();
117  val._x = b - a;
118 
119  a = _ContinuousImage.GetWithPaddingInside(x, y - .5, z, t);
120  if (a == _ContinuousImage.DefaultValue()) return this->DefaultValue();
121  b = _ContinuousImage.GetWithPaddingInside(x, y + .5, z, t);
122  if (b == _ContinuousImage.DefaultValue()) return this->DefaultValue();
123  val._y = b - a;
124 
125  return val;
126 }
127 
128 // -----------------------------------------------------------------------------
129 template <class TImage>
132 ::GetInside3D(double x, double y, double z, double t) const
133 {
134  GradientType val;
135  val._x = _ContinuousImage.GetInside(x + .5, y, z, t) -
136  _ContinuousImage.GetInside(x - .5, y, z, t);
137  val._y = _ContinuousImage.GetInside(x, y + .5, z, t) -
138  _ContinuousImage.GetInside(x, y - .5, z, t);
139  val._z = _ContinuousImage.GetInside(x, y, z + .5, t) -
140  _ContinuousImage.GetInside(x, y, z - .5, t);
141  return val;
142 }
143 
144 // -----------------------------------------------------------------------------
145 template <class TImage>
148 ::GetWithPaddingInside3D(double x, double y, double z, double t) const
149 {
150  GradientType val;
151  VoxelType a, b;
152 
153  a = _ContinuousImage.GetWithPaddingInside(x - .5, y, z, t);
154  if (a == _ContinuousImage.DefaultValue()) return this->DefaultValue();
155  b = _ContinuousImage.GetWithPaddingInside(x + .5, y, z, t);
156  if (b == _ContinuousImage.DefaultValue()) return this->DefaultValue();
157  val._x = b - a;
158 
159  a = _ContinuousImage.GetWithPaddingInside(x, y - .5, z, t);
160  if (a == _ContinuousImage.DefaultValue()) return this->DefaultValue();
161  b = _ContinuousImage.GetWithPaddingInside(x, y + .5, z, t);
162  if (b == _ContinuousImage.DefaultValue()) return this->DefaultValue();
163  val._y = b - a;
164 
165  a = _ContinuousImage.GetWithPaddingInside(x, y, z - .5, t);
166  if (a == _ContinuousImage.DefaultValue()) return this->DefaultValue();
167  b = _ContinuousImage.GetWithPaddingInside(x, y, z + .5, t);
168  if (b == _ContinuousImage.DefaultValue()) return this->DefaultValue();
169  val._z = b - a;
170 
171  return val;
172 }
173 
174 // -----------------------------------------------------------------------------
175 template <class TImage>
178 ::GetInside(double x, double y, double z, double t) const
179 {
180  switch (this->NumberOfDimensions()) {
181  case 2: return GetInside2D(x, y, z, t);
182  default: return GetInside3D(x, y, z, t);
183  }
184 }
185 
186 // -----------------------------------------------------------------------------
187 template <class TImage>
190 ::GetOutside(double x, double y, double z, double t) const
191 {
192  return this->DefaultValue();
193 }
194 
195 // -----------------------------------------------------------------------------
196 template <class TImage>
199 ::GetWithPaddingInside(double x, double y, double z, double t) const
200 {
201  switch (this->NumberOfDimensions()) {
202  case 2: return GetWithPaddingInside2D(x, y, z, t);
203  default: return GetWithPaddingInside3D(x, y, z, t);
204  }
205 }
206 
207 // -----------------------------------------------------------------------------
208 template <class TImage>
211 ::GetWithPaddingOutside(double x, double y, double z, double t) const
212 {
213  return this->DefaultValue();
214 }
215 
216 
217 } // namespace mirtk
218 
219 #endif // MIRTK_LinearImageGradientFunction_HXX
GradientType GetInside3D(double, double, double=0, double=0) const
Get gradient of given 3D image without handling boundary conditions.
virtual GradientType GetWithPaddingInside(double, double, double=0, double=0) const
Evaluate generic image gradient without handling boundary conditions.
MIRTKCU_API int ifloor(T x)
Round floating-point value to next smaller integer and cast to int.
Definition: Math.h:154
virtual GradientType GetInside(double, double, double=0, double=0) const
MIRTKCU_API double fdec(double f)
Definition: Math.h:188
virtual void Initialize(bool=false)
Initialize interpolation function.
Definition: IOConfig.h:41
virtual GradientType GetOutside(double, double, double=0, double=0) const
GradientType GetWithPaddingInside2D(double, double, double=0, double=0) const
T _z
The z component.
Definition: Vector3D.h:60
T _y
The y component.
Definition: Vector3D.h:59
virtual void BoundingInterval(double, int &, int &) const
virtual GradientType GetWithPaddingOutside(double, double, double=0, double=0) const
GradientType GetWithPaddingInside3D(double, double, double=0, double=0) const
T _x
The x component.
Definition: Vector3D.h:58
GradientType GetInside2D(double, double, double=0, double=0) const
Get gradient of given 2D image without handling boundary conditions.