TransformationUtils.h
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_TransformationUtils_H
21 #define MIRTK_TransformationUtils_H
22 
23 #include "mirtk/Transformation.h"
24 #include "mirtk/GenericImage.h"
25 #include "mirtk/Parallel.h"
26 
27 
28 namespace mirtk {
29 namespace TransformationUtils {
30 
31 
32 // -----------------------------------------------------------------------------
33 /// Parallel helper for Transformation::Approximate implementations
35 {
36  const Transformation *_Transformation;
37  const double *_x, *_y, *_z, *_t;
38  double *_dx, *_dy, *_dz;
39 
40 public:
41 
42  SubDisplacements(const Transformation *transformation,
43  const double *x, const double *y, const double *z, const double *t,
44  double *dx, double *dy, double *dz)
45  :
46  _Transformation(transformation), _x(x), _y(y), _z(z), _t(t), _dx(dx), _dy(dy), _dz(dz)
47  {}
48 
49  void operator()(const blocked_range<int> &re) const
50  {
51  const double *x = _x + re.begin();
52  const double *y = _y + re.begin();
53  const double *z = _z + re.begin();
54  const double *t = _t + re.begin();
55  double *dx = _dx + re.begin();
56  double *dy = _dy + re.begin();
57  double *dz = _dz + re.begin();
58 
59  double tx, ty, tz;
60  for (int idx = re.begin(); idx < re.end(); ++idx, ++x, ++y, ++z, ++t, ++dx, ++dy, ++dz) {
61  tx = *x, ty = *y, tz = *z;
62  _Transformation->Displacement(tx, ty, tz, *t);
63  *dx -= tx, *dy -= ty, *dz -= tz;
64  }
65  }
66 };
67 
68 // -----------------------------------------------------------------------------
69 /// Body of Transformation::Transform(int, double *, double *, double *, ...)
71 {
72  const Transformation *_Transformation;
73  double *_x, *_y, *_z, _t0, _t1;
74  const double *_t;
75 
76 public:
77 
78  TransformPoints(const Transformation *transformation, double *x, double *y, double *z, double t, double t0)
79  :
80  _Transformation(transformation),
81  _x(x), _y(y), _z(z), _t0(t0), _t1(t), _t(NULL)
82  {}
83 
84  TransformPoints(const Transformation *transformation, double *x, double *y, double *z, const double *t, double t0)
85  :
86  _Transformation(transformation),
87  _x(x), _y(y), _z(z), _t0(t0), _t1(.0), _t(t)
88  {}
89 
90  void operator ()(const blocked_range<int> &idx) const
91  {
92  double *x = _x + idx.begin();
93  double *y = _y + idx.begin();
94  double *z = _z + idx.begin();
95  for (int i = idx.begin(); i != idx.end(); ++i, ++x, ++y, ++z) {
96  _Transformation->Transform(*x, *y, *z, (_t ? _t[i] : _t1), _t0);
97  }
98  }
99 };
100 
101 // -----------------------------------------------------------------------------
102 /// Body of Transformation::Transform(WorldCoordsImage &)
104 {
105  const Transformation *_Transformation;
106  WorldCoordsImage *_Coords;
107  const int _NumberOfPoints;
108  double _t, _t0;
109 
110 public:
111 
112  TransformWorldCoords(const Transformation *t, WorldCoordsImage &coords, double t0)
113  :
114  _Transformation(t),
115  _Coords(&coords),
116  _NumberOfPoints(coords.NumberOfSpatialVoxels()),
117  _t(coords.GetTOrigin()), _t0(t0)
118  {}
119 
120  void operator ()(const blocked_range<int> &idx) const
121  {
122  WorldCoordsImage::VoxelType *wx, *wy, *wz;
123  wx = _Coords->Data() + idx.begin();
124  wy = wx + _NumberOfPoints;
125  wz = wy + _NumberOfPoints;
126  for (int i = idx.begin(); i != idx.end(); ++i, ++wx, ++wy, ++wz) {
127  _Transformation->Transform(*wx, *wy, *wz, _t, _t0);
128  }
129  }
130 };
131 
132 
133 } } // namespace mirtk::TransformationUtils
134 
135 #endif // MIRTK_TransformationUtils_H
VoxelType * Data(int=0)
Get raw pointer to contiguous image data.
Definition: GenericImage.h:740
One-dimensional range.
Definition: Parallel.h:155
Body of Transformation::Transform(int, double *, double *, double *, ...)
Definition: IOConfig.h:41
double GetTOrigin() const
Get temporal origin.
Definition: BaseImage.h:1082
virtual void Displacement(double &, double &, double &, double=0, double=NaN) const
Calculates the displacement of a single point.
Parallel helper for Transformation::Approximate implementations.
virtual void Transform(double &, double &, double &, double=0, double=NaN) const =0
Transforms a single point.
int NumberOfSpatialVoxels() const
Returns the total number of spatial voxels.
Definition: BaseImage.h:868
double VoxelType
Voxel type.
Definition: GenericImage.h:52
Body of Transformation::Transform(WorldCoordsImage &)