CSplineInterpolateImageFunction.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_CSplineInterpolateImageFunction_HXX
21 #define MIRTK_CSplineInterpolateImageFunction_HXX
22 
23 #include "mirtk/CSplineInterpolateImageFunction.h"
24 
25 #include "mirtk/Math.h"
26 #include "mirtk/VoxelCast.h"
27 #include "mirtk/InterpolateImageFunction.hxx"
28 
29 
30 namespace mirtk {
31 
32 
33 // =============================================================================
34 // Cubic spline function
35 // =============================================================================
36 
37 // -----------------------------------------------------------------------------
38 template <class TImage>
39 inline typename GenericCSplineInterpolateImageFunction<TImage>::Real
41 {
42  const Real xi = abs(x);
43  const Real xii = xi * xi;
44  const Real xiii = xii * xi;
45  if (xi < 1) return xiii - 2 * xii + 1;
46  else if (xi < 2) return -xiii + 5 * xii - 8 * xi + 4;
47  return 0;
48 }
49 
50 // =============================================================================
51 // Construction/Destruction
52 // =============================================================================
53 
54 // -----------------------------------------------------------------------------
55 template <class TImage>
58 {
59 }
60 
61 // -----------------------------------------------------------------------------
62 template <class TImage>
65 {
66 }
67 
68 // -----------------------------------------------------------------------------
69 template <class TImage>
71 {
72  // Initialize base class
73  Superclass::Initialize(coeff);
74 
75  // Domain on which the C-spline interpolation is defined
76  switch (this->NumberOfDimensions()) {
77  case 4:
78  this->_t1 = 1;
79  this->_t2 = this->Input()->T() - 3;
80  case 3:
81  this->_z1 = 1;
82  this->_z2 = this->Input()->Z() - 3;
83  default:
84  this->_y1 = 1;
85  this->_y2 = this->Input()->Y() - 3;
86  this->_x1 = 1;
87  this->_x2 = this->Input()->X() - 3;
88  }
89 }
90 
91 // =============================================================================
92 // Domain checks
93 // =============================================================================
94 
95 // -----------------------------------------------------------------------------
96 template <class TImage>
98 ::BoundingInterval(double x, int &i, int &I) const
99 {
100  i = ifloor(x) - 1, I = i + 3;
101 }
102 
103 // =============================================================================
104 // Evaluation
105 // =============================================================================
106 
107 // -----------------------------------------------------------------------------
108 template <class TImage>
109 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
111 ::Get2D(double x, double y, double z, double t) const
112 {
113  int i = ifloor(x);
114  int j = ifloor(y);
115  int k = iround(z);
116  int l = iround(t);
117 
118  if (k < 0 || k >= this->Input()->Z() ||
119  l < 0 || l >= this->Input()->T()) {
120  return voxel_cast<VoxelType>(this->DefaultValue());
121  }
122 
123  const int i1 = i - 1;
124  const int j1 = j - 1;
125  const int i2 = i + 2;
126  const int j2 = j + 2;
127 
128  RealType val = voxel_cast<RealType>(0);
129  Real nrm(0), wy, w;
130 
131  for (j = j1; j <= j2; ++j) {
132  if (0 <= j && j < this->Input()->Y()) {
133  wy = CSpline(Real(y - j));
134  for (i = i1; i <= i2; ++i) {
135  if (0 <= i && i < this->Input()->X()) {
136  w = CSpline(Real(x - i)) * wy;
137  val += w * voxel_cast<RealType>(this->Input()->Get(i, j, k, l));
138  nrm += w;
139  }
140  }
141  }
142  }
143 
144  if (nrm > 1e-3) val /= nrm;
145  else val = voxel_cast<RealType>(this->DefaultValue());
146 
147  return voxel_cast<VoxelType>(val);
148 }
149 
150 // -----------------------------------------------------------------------------
151 template <class TImage>
152 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
154 ::GetWithPadding2D(double x, double y, double z, double t) const
155 {
156  int i = ifloor(x);
157  int j = ifloor(y);
158  int k = iround(z);
159  int l = iround(t);
160 
161  if (k < 0 || k >= this->Input()->Z() ||
162  l < 0 || l >= this->Input()->T()) {
163  return voxel_cast<VoxelType>(this->DefaultValue());
164  }
165 
166  const int i1 = i - 1;
167  const int j1 = j - 1;
168  const int i2 = i + 2;
169  const int j2 = j + 2;
170 
171  RealType val = voxel_cast<RealType>(0);
172  Real fgw(0), bgw(0), wy, w;
173 
174  for (j = j1; j <= j2; ++j) {
175  wy = CSpline(Real(y - j));
176  for (i = i1; i <= i2; ++i) {
177  w = CSpline(Real(x - i)) * wy;
178  if (this->Input()->IsInsideForeground(i, j, k, l)) {
179  val += w * voxel_cast<RealType>(this->Input()->Get(i, j, k, l));
180  fgw += w;
181  } else {
182  bgw += w;
183  }
184  }
185  }
186 
187  if (bgw > fgw || AreEqual(bgw, fgw, 1e-3)) {
188  return voxel_cast<VoxelType>(this->DefaultValue());
189  }
190  return voxel_cast<VoxelType>(val / fgw);
191 }
192 
193 // -----------------------------------------------------------------------------
194 template <class TImage> template <class TOtherImage>
195 inline typename TOtherImage::VoxelType
197 ::Get2D(const TOtherImage *input, double x, double y, double z, double t) const
198 {
199  typedef typename TOtherImage::VoxelType VoxelType;
200  typedef typename TOtherImage::RealType RealType;
201 
202  int i = ifloor(x);
203  int j = ifloor(y);
204  int k = iround(z);
205  int l = iround(t);
206 
207  const int i1 = i - 1;
208  const int j1 = j - 1;
209  const int i2 = i + 2;
210  const int j2 = j + 2;
211 
212  RealType val = voxel_cast<RealType>(0);
213  Real nrm(0), wy, w;
214 
215  for (j = j1; j <= j2; ++j) {
216  wy = CSpline(Real(y - j));
217  for (i = i1; i <= i2; ++i) {
218  w = CSpline(Real(x - i)) * wy;
219  val += w * voxel_cast<RealType>(input->Get(i, j, k, l));
220  nrm += w;
221  }
222  }
223 
224  if (nrm > 1e-3) val /= nrm;
225  else val = voxel_cast<RealType>(this->DefaultValue());
226 
227  return voxel_cast<VoxelType>(val);
228 }
229 
230 // -----------------------------------------------------------------------------
231 template <class TImage> template <class TOtherImage>
232 inline typename TOtherImage::VoxelType
234 ::GetWithPadding2D(const TOtherImage *input, double x, double y, double z, double t) const
235 {
236  typedef typename TOtherImage::VoxelType VoxelType;
237  typedef typename TOtherImage::RealType RealType;
238 
239  int i = ifloor(x);
240  int j = ifloor(y);
241  int k = iround(z);
242  int l = iround(t);
243 
244  const int i1 = i - 1;
245  const int j1 = j - 1;
246  const int i2 = i + 2;
247  const int j2 = j + 2;
248 
249  RealType val = voxel_cast<RealType>(0);
250  Real fgw(0), bgw(0), wy, w;
251 
252  for (j = j1; j <= j2; ++j) {
253  wy = CSpline(Real(y - j));
254  for (i = i1; i <= i2; ++i) {
255  w = CSpline(Real(x - i)) * wy;
256  if (input->IsForeground(i, j, k, l)) {
257  val += w * voxel_cast<RealType>(input->Get(i, j, k, l));
258  fgw += w;
259  } else {
260  bgw += w;
261  }
262  }
263  }
264 
265  if (bgw > fgw || AreEqual(bgw, fgw, 1e-3)) {
266  return voxel_cast<VoxelType>(this->DefaultValue());
267  }
268  return voxel_cast<VoxelType>(val / fgw);
269 }
270 
271 // -----------------------------------------------------------------------------
272 template <class TImage>
273 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
275 ::Get3D(double x, double y, double z, double t) const
276 {
277  int i = ifloor(x);
278  int j = ifloor(y);
279  int k = ifloor(z);
280  int l = iround(t);
281 
282  if (l < 0 || l >= this->Input()->T()) {
283  return voxel_cast<VoxelType>(this->DefaultValue());
284  }
285 
286  const int i1 = i - 1;
287  const int j1 = j - 1;
288  const int k1 = k - 1;
289  const int i2 = i + 2;
290  const int j2 = j + 2;
291  const int k2 = k + 2;
292 
293  RealType val = voxel_cast<RealType>(0);
294  Real nrm(0), wz, wyz, w;
295 
296  for (k = k1; k <= k2; ++k) {
297  if (0 <= k && k < this->Input()->Z()) {
298  wz = CSpline(Real(z - k));
299  for (j = j1; j <= j2; ++j) {
300  if (0 <= j && j < this->Input()->Y()) {
301  wyz = CSpline(Real(y - j)) * wz;
302  for (i = i1; i <= i2; ++i) {
303  if (0 <= i && i < this->Input()->X()) {
304  w = CSpline(Real(x - i)) * wyz;
305  val += w * voxel_cast<RealType>(this->Input()->Get(i, j, k, l));
306  nrm += w;
307  }
308  }
309  }
310  }
311  }
312  }
313 
314  if (nrm > 1e-3) val /= nrm;
315  else val = voxel_cast<RealType>(this->DefaultValue());
316 
317  return voxel_cast<VoxelType>(val);
318 }
319 
320 // -----------------------------------------------------------------------------
321 template <class TImage>
322 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
324 ::GetWithPadding3D(double x, double y, double z, double t) const
325 {
326  int i = ifloor(x);
327  int j = ifloor(y);
328  int k = ifloor(z);
329  int l = iround(t);
330 
331  if (l < 0 || l >= this->Input()->T()) {
332  return voxel_cast<VoxelType>(this->DefaultValue());
333  }
334 
335  const int i1 = i - 1;
336  const int j1 = j - 1;
337  const int k1 = k - 1;
338  const int i2 = i + 2;
339  const int j2 = j + 2;
340  const int k2 = k + 2;
341 
342  RealType val = voxel_cast<RealType>(0);
343  Real fgw(0), bgw(0), wz, wyz, w;
344 
345  for (k = k1; k <= k2; ++k) {
346  wz = CSpline(Real(z - k));
347  for (j = j1; j <= j2; ++j) {
348  wyz = CSpline(Real(y - j)) * wz;
349  for (i = i1; i <= i2; ++i) {
350  w = CSpline(Real(x - i)) * wyz;
351  if (this->Input()->IsInsideForeground(i, j, k, l)) {
352  val += w * voxel_cast<RealType>(this->Input()->Get(i, j, k, l));
353  fgw += w;
354  } else {
355  bgw += w;
356  }
357  }
358  }
359  }
360 
361  if (bgw > fgw || AreEqual(bgw, fgw, 1e-3)) {
362  return voxel_cast<VoxelType>(this->DefaultValue());
363  }
364  return voxel_cast<VoxelType>(val / fgw);
365 }
366 
367 // -----------------------------------------------------------------------------
368 template <class TImage> template <class TOtherImage>
369 inline typename TOtherImage::VoxelType
371 ::Get3D(const TOtherImage *input, double x, double y, double z, double t) const
372 {
373  typedef typename TOtherImage::VoxelType VoxelType;
374  typedef typename TOtherImage::RealType RealType;
375 
376  int i = ifloor(x);
377  int j = ifloor(y);
378  int k = ifloor(z);
379  int l = iround(t);
380 
381  const int i1 = i - 1;
382  const int j1 = j - 1;
383  const int k1 = k - 1;
384  const int i2 = i + 2;
385  const int j2 = j + 2;
386  const int k2 = k + 2;
387 
388  RealType val = voxel_cast<RealType>(0);
389  Real nrm(0), wz, wyz, w;
390 
391  for (k = k1; k <= k2; ++k) {
392  wz = CSpline(Real(z - k));
393  for (j = j1; j <= j2; ++j) {
394  wyz = CSpline(Real(y - j)) * wz;
395  for (i = i1; i < i2; ++i) {
396  w = CSpline(Real(x - i)) * wyz;
397  val += w * voxel_cast<RealType>(input->Get(i, j, k, l));
398  nrm += w;
399  }
400  }
401  }
402 
403  if (nrm > 1e-3) val /= nrm;
404  else val = voxel_cast<RealType>(this->DefaultValue());
405 
406  return voxel_cast<VoxelType>(val);
407 }
408 
409 // -----------------------------------------------------------------------------
410 template <class TImage> template <class TOtherImage>
411 inline typename TOtherImage::VoxelType
413 ::GetWithPadding3D(const TOtherImage *input, double x, double y, double z, double t) const
414 {
415  typedef typename TOtherImage::VoxelType VoxelType;
416  typedef typename TOtherImage::RealType RealType;
417 
418  int i = ifloor(x);
419  int j = ifloor(y);
420  int k = ifloor(z);
421  int l = iround(t);
422 
423  const int i1 = i - 1;
424  const int j1 = j - 1;
425  const int k1 = k - 1;
426  const int i2 = i + 2;
427  const int j2 = j + 2;
428  const int k2 = k + 2;
429 
430  RealType val = voxel_cast<RealType>(0);
431  Real fgw(0), bgw(0), wz, wyz, w;
432 
433  for (k = k1; k <= k2; ++k) {
434  wz = CSpline(Real(z - k));
435  for (j = j1; j <= j2; ++j) {
436  wyz = CSpline(Real(y - j)) * wz;
437  for (i = i1; i < i2; ++i) {
438  w = CSpline(Real(x - i)) * wyz;
439  if (input->IsForeground(i, j, k, l)) {
440  val += w * voxel_cast<RealType>(input->Get(i, j, k, l));
441  fgw += w;
442  } else {
443  bgw += w;
444  }
445  }
446  }
447  }
448 
449  if (bgw > fgw || AreEqual(bgw, fgw, 1e-3)) {
450  return voxel_cast<VoxelType>(this->DefaultValue());
451  }
452  return voxel_cast<VoxelType>(val / fgw);
453 }
454 
455 // -----------------------------------------------------------------------------
456 template <class TImage>
457 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
459 ::Get4D(double x, double y, double z, double t) const
460 {
461  int i = ifloor(x);
462  int j = ifloor(y);
463  int k = ifloor(z);
464  int l = ifloor(t);
465 
466  const int i1 = i - 1;
467  const int j1 = j - 1;
468  const int k1 = k - 1;
469  const int l1 = l - 1;
470  const int i2 = i + 2;
471  const int j2 = j + 2;
472  const int k2 = k + 2;
473  const int l2 = l + 2;
474 
475  RealType val = voxel_cast<RealType>(0);
476  Real nrm(0), wt, wzt, wyzt, w;
477 
478  for (l = l1; l <= l2; ++l) {
479  if (0 <= l && l < this->Input()->T()) {
480  wt = CSpline(Real(t - l));
481  for (k = k1; k <= k2; ++k) {
482  if (0 <= k && k < this->Input()->Z()) {
483  wzt = CSpline(Real(z - k)) * wt;
484  for (j = j1; j <= j2; ++j) {
485  if (0 <= j && j < this->Input()->Y()) {
486  wyzt = CSpline(Real(y - j)) * wzt;
487  for (i = i1; i <= i2; ++i) {
488  if (0 <= i && i < this->Input()->X()) {
489  w = CSpline(Real(x - i)) * wyzt;
490  val += w * voxel_cast<RealType>(this->Input()->Get(i, j, k, l));
491  nrm += w;
492  }
493  }
494  }
495  }
496  }
497  }
498  }
499  }
500 
501  if (nrm > 1e-3) val /= nrm;
502  else val = voxel_cast<RealType>(this->DefaultValue());
503 
504  return voxel_cast<VoxelType>(val);
505 }
506 
507 // -----------------------------------------------------------------------------
508 template <class TImage>
509 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
511 ::GetWithPadding4D(double x, double y, double z, double t) const
512 {
513  int i = ifloor(x);
514  int j = ifloor(y);
515  int k = ifloor(z);
516  int l = ifloor(t);
517 
518  const int i1 = i - 1;
519  const int j1 = j - 1;
520  const int k1 = k - 1;
521  const int l1 = l - 1;
522  const int i2 = i + 2;
523  const int j2 = j + 2;
524  const int k2 = k + 2;
525  const int l2 = l + 2;
526 
527  RealType val = voxel_cast<RealType>(0);
528  Real fgw(0), bgw(0), wt, wzt, wyzt, w;
529 
530  for (l = l1; l <= l2; ++l) {
531  wt = CSpline(Real(t - l));
532  for (k = k1; k <= k2; ++k) {
533  wzt = CSpline(Real(z - k)) * wt;
534  for (j = j1; j <= j2; ++j) {
535  wyzt = CSpline(Real(y - j)) * wzt;
536  for (i = i1; i <= i2; ++i) {
537  w = CSpline(Real(x - i)) * wyzt;
538  if (this->Input()->IsInsideForeground(i, j, k, l)) {
539  val += w * voxel_cast<RealType>(this->Input()->Get(i, j, k, l));
540  fgw += w;
541  } else {
542  bgw += w;
543  }
544  }
545  }
546  }
547  }
548 
549  if (bgw > fgw || AreEqual(bgw, fgw, 1e-3)) {
550  return voxel_cast<VoxelType>(this->DefaultValue());
551  }
552  return voxel_cast<VoxelType>(val / fgw);
553 }
554 
555 // -----------------------------------------------------------------------------
556 template <class TImage> template <class TOtherImage>
557 inline typename TOtherImage::VoxelType
559 ::Get4D(const TOtherImage *input, double x, double y, double z, double t) const
560 {
561  typedef typename TOtherImage::VoxelType VoxelType;
562  typedef typename TOtherImage::RealType RealType;
563 
564  int i = ifloor(x);
565  int j = ifloor(y);
566  int k = ifloor(z);
567  int l = ifloor(t);
568 
569  const int i1 = i - 1;
570  const int j1 = j - 1;
571  const int k1 = k - 1;
572  const int l1 = l - 1;
573  const int i2 = i + 2;
574  const int j2 = j + 2;
575  const int k2 = k + 2;
576  const int l2 = l + 2;
577 
578  RealType val = voxel_cast<RealType>(0);
579  Real nrm(0), wt, wzt, wyzt, w;
580 
581  for (l = l1; l <= l2; ++l) {
582  wt = CSpline(Real(t - l));
583  for (k = k1; k <= k2; ++k) {
584  wzt = CSpline(Real(z - k)) * wt;
585  for (j = j1; j <= j2; ++j) {
586  wyzt = CSpline(Real(y - j)) * wzt;
587  for (i = i1; i <= i2; ++i) {
588  w = CSpline(Real(x - i)) * wyzt;
589  val += w * voxel_cast<RealType>(input->Get(i, j, k, l));
590  nrm += w;
591  }
592  }
593  }
594  }
595 
596  if (nrm > 1e-3) val /= nrm;
597  else val = voxel_cast<RealType>(this->DefaultValue());
598 
599  return voxel_cast<VoxelType>(val);
600 }
601 
602 // -----------------------------------------------------------------------------
603 template <class TImage> template <class TOtherImage>
604 inline typename TOtherImage::VoxelType
606 ::GetWithPadding4D(const TOtherImage *input, double x, double y, double z, double t) const
607 {
608  typedef typename TOtherImage::VoxelType VoxelType;
609  typedef typename TOtherImage::RealType RealType;
610 
611  int i = ifloor(x);
612  int j = ifloor(y);
613  int k = ifloor(z);
614  int l = ifloor(t);
615 
616  const int i1 = i - 1;
617  const int j1 = j - 1;
618  const int k1 = k - 1;
619  const int l1 = l - 1;
620  const int i2 = i + 2;
621  const int j2 = j + 2;
622  const int k2 = k + 2;
623  const int l2 = l + 2;
624 
625  RealType val = voxel_cast<RealType>(0);
626  Real fgw(0), bgw(0), wt, wzt, wyzt, w;
627 
628  for (l = l1; l <= l2; ++l) {
629  wt = CSpline(Real(t - l));
630  for (k = k1; k <= k2; ++k) {
631  wzt = CSpline(Real(z - k)) * wt;
632  for (j = j1; j <= j2; ++j) {
633  wyzt = CSpline(Real(y - j)) * wzt;
634  for (i = i1; i <= i2; ++i) {
635  w = CSpline(Real(x - i)) * wyzt;
636  if (input->IsForeground(i, j, k, l)) {
637  val += w * voxel_cast<RealType>(input->Get(i, j, k, l));
638  fgw += w;
639  } else {
640  bgw += w;
641  }
642  }
643  }
644  }
645  }
646 
647  if (bgw > fgw || AreEqual(bgw, fgw, 1e-3)) {
648  return voxel_cast<VoxelType>(this->DefaultValue());
649  }
650  return voxel_cast<VoxelType>(val / fgw);
651 }
652 
653 // -----------------------------------------------------------------------------
654 template <class TImage>
655 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
657 ::Get(double x, double y, double z, double t) const
658 {
659  switch (this->NumberOfDimensions()) {
660  case 3: return Get3D(x, y, z, t);
661  case 2: return Get2D(x, y, z, t);
662  default: return Get4D(x, y, z, t);
663  }
664 }
665 
666 // -----------------------------------------------------------------------------
667 template <class TImage>
668 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
670 ::GetWithPadding(double x, double y, double z, double t) const
671 {
672  switch (this->NumberOfDimensions()) {
673  case 3: return GetWithPadding3D(x, y, z, t);
674  case 2: return GetWithPadding2D(x, y, z, t);
675  default: return GetWithPadding4D(x, y, z, t);
676  }
677 }
678 
679 // -----------------------------------------------------------------------------
680 template <class TImage> template <class TOtherImage>
681 inline typename TOtherImage::VoxelType
683 ::Get(const TOtherImage *input, double x, double y, double z, double t) const
684 {
685  switch (this->NumberOfDimensions()) {
686  case 3: return Get3D(input, x, y, z, t);
687  case 2: return Get2D(input, x, y, z, t);
688  default: return Get4D(input, x, y, z, t);
689  }
690 }
691 
692 // -----------------------------------------------------------------------------
693 template <class TImage> template <class TOtherImage>
694 inline typename TOtherImage::VoxelType
696 ::GetWithPadding(const TOtherImage *input, double x, double y, double z, double t) const
697 {
698  switch (this->NumberOfDimensions()) {
699  case 3: return GetWithPadding3D(input, x, y, z, t);
700  case 2: return GetWithPadding2D(input, x, y, z, t);
701  default: return GetWithPadding4D(input, x, y, z, t);
702  }
703 }
704 
705 // -----------------------------------------------------------------------------
706 template <class TImage>
707 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
709 ::GetInside(double x, double y, double z, double t) const
710 {
711  return Get(this->Input(), x, y, z, t);
712 }
713 
714 // -----------------------------------------------------------------------------
715 template <class TImage>
716 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
718 ::GetOutside(double x, double y, double z, double t) const
719 {
720  if (this->Extrapolator()) {
721  return Get(this->Extrapolator(), x, y, z, t);
722  } else {
723  return Get(x, y, z, t);
724  }
725 }
726 
727 // -----------------------------------------------------------------------------
728 template <class TImage>
729 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
731 ::GetWithPaddingInside(double x, double y, double z, double t) const
732 {
733  return GetWithPadding(this->Input(), x, y, z, t);
734 }
735 
736 // -----------------------------------------------------------------------------
737 template <class TImage>
738 inline typename GenericCSplineInterpolateImageFunction<TImage>::VoxelType
740 ::GetWithPaddingOutside(double x, double y, double z, double t) const
741 {
742  if (this->Extrapolator()) {
743  return GetWithPadding(this->Extrapolator(), x, y, z, t);
744  } else {
745  return GetWithPadding(x, y, z, t);
746  }
747 }
748 
749 
750 } // namespace mirtk
751 
752 #endif // MIRTK_CSplineInterpolateImageFunction_HXX
virtual VoxelType GetWithPaddingInside(double, double, double=0, double=0) const
VoxelType GetWithPadding4D(double, double, double=0, double=0) const
virtual VoxelType GetInside(double, double, double=0, double=0) const
string Get(const ParameterList &params, string name)
Get parameter value from parameters list.
Definition: Object.h:202
VoxelType Get4D(double, double, double=0, double=0) const
VoxelType Get2D(double, double, double=0, double=0) const
virtual VoxelType GetWithPadding(double, double, double=0, double=0) const
VoxelType Get3D(double, double, double=0, double=0) const
MIRTKCU_API int ifloor(T x)
Round floating-point value to next smaller integer and cast to int.
Definition: Math.h:154
Definition: IOConfig.h:41
virtual VoxelType GetOutside(double, double, double=0, double=0) const
Evaluate generic image at an arbitrary location (in pixels)
MIRTKCU_API bool AreEqual(double a, double b, double tol=1e-12)
Determine equality of two floating point numbers.
Definition: Math.h:115
VoxelType GetWithPadding3D(double, double, double=0, double=0) const
MIRTKCU_API int iround(T x)
Round floating-point value and cast to int.
Definition: Math.h:170
VoxelType Get(double, double, double=0, double=0) const
virtual void BoundingInterval(double, int &, int &) const
virtual VoxelType GetWithPaddingOutside(double, double, double=0, double=0) const
VoxelType GetWithPadding2D(double, double, double=0, double=0) const