ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
DataInterface.h
Go to the documentation of this file.
1 // File: DataInterface.h
3 // Author: Changchang Wu (ccwu@cs.washington.edu)
4 // Description : data interface, the data format been uploaded to GPU
5 //
6 // Copyright (c) 2011 Changchang Wu (ccwu@cs.washington.edu)
7 // and the University of Washington at Seattle
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public
11 // License as published by the Free Software Foundation; either
12 // Version 3 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // General Public License for more details.
18 //
20 
21 #ifndef DATA_INTERFACE_GPU_H
22 #define DATA_INTERFACE_GPU_H
23 
24 #include <math.h>
25 
26 // ----------------------------WARNING------------------------------
27 // -----------------------------------------------------------------
28 // ROTATION CONVERSION:
29 // The internal rotation representation is 3x3 float matrix. Reading
30 // back the rotations as quaternion or Rodrigues's representation will
31 // cause inaccuracy, IF you have wrongly reconstructed cameras with
32 // a very very large focal length (typically also very far away).
33 // In this case, any small change in the rotation matrix, will cause
34 // a large reprojection error.
35 //
36 // ---------------------------------------------------------------------
37 // RADIAL distortion is NOT enabled by default, use parameter "-md", -pd"
38 // or set ConfigBA::__use_radial_distortion to 1 or -1 to enable it.
39 // ---------------------------------------------------------------------------
40 
41 namespace pba {
42 
43 // transfer data type with 4-float alignment
44 #define CameraT CameraT_
45 #define Point3D Point3D_
46 template <class FT>
47 
48 struct CameraT_ {
49  typedef FT float_t;
51  float_t f; // single focal length, K = [f, 0, 0; 0 f 0; 0 0 1]
52  float_t t[3]; // T in P = K[R T], T = - RC
53  float_t m[3][3]; // R in P = K[R T].
54  float_t radial; // WARNING: BE careful with the radial distortion model.
57 
60  radial = 0;
61  distortion_type = 0;
62  constant_camera = 0;
63  }
64 
66  template <class CameraX>
67  void SetCameraT(const CameraX& cam) {
68  f = (float_t)cam.f;
69  t[0] = (float_t)cam.t[0];
70  t[1] = (float_t)cam.t[1];
71  t[2] = (float_t)cam.t[2];
72  for (int i = 0; i < 3; ++i)
73  for (int j = 0; j < 3; ++j) m[i][j] = (float_t)cam.m[i][j];
74  radial = (float_t)cam.radial;
75  distortion_type = cam.distortion_type;
76  constant_camera = cam.constant_camera;
77  }
78 
83  // void SetFixedExtrinsic() {constant_camera = 3.0f;}
84 
86  template <class Float>
87  void SetFocalLength(Float F) {
88  f = (float_t)F;
89  }
90  float_t GetFocalLength() const { return f; }
91 
92  template <class Float>
93  void SetMeasurementDistortion(Float r) {
94  radial = (float_t)r;
95  distortion_type = -1;
96  }
98  return distortion_type == -1 ? radial : 0;
99  }
100 
101  // normalize radial distortion that applies to angle will be (radial * f * f);
102  template <class Float>
104  SetMeasurementDistortion(r / (f * f));
105  }
107  return GetMeasurementDistortion() * (f * f);
108  }
109 
110  // use projection distortion
111  template <class Float>
112  void SetProjectionDistortion(Float r) {
113  radial = float_t(r);
114  distortion_type = 1;
115  }
116  template <class Float>
117  void SetProjectionDistortion(const Float* r) {
119  }
121  return distortion_type == 1 ? radial : 0;
122  }
123 
124  template <class Float>
125  void SetRodriguesRotation(const Float r[3]) {
126  double a = sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
127  double ct = a == 0.0 ? 0.5 : (1.0 - cos(a)) / a / a;
128  double st = a == 0.0 ? 1 : sin(a) / a;
129  m[0][0] = float_t(1.0 - (r[1] * r[1] + r[2] * r[2]) * ct);
130  m[0][1] = float_t(r[0] * r[1] * ct - r[2] * st);
131  m[0][2] = float_t(r[2] * r[0] * ct + r[1] * st);
132  m[1][0] = float_t(r[0] * r[1] * ct + r[2] * st);
133  m[1][1] = float_t(1.0 - (r[2] * r[2] + r[0] * r[0]) * ct);
134  m[1][2] = float_t(r[1] * r[2] * ct - r[0] * st);
135  m[2][0] = float_t(r[2] * r[0] * ct - r[1] * st);
136  m[2][1] = float_t(r[1] * r[2] * ct + r[0] * st);
137  m[2][2] = float_t(1.0 - (r[0] * r[0] + r[1] * r[1]) * ct);
138  }
139  template <class Float>
140  void GetRodriguesRotation(Float r[3]) const {
141  double a = (m[0][0] + m[1][1] + m[2][2] - 1.0) / 2.0;
142  const double epsilon = 0.01;
143  if (fabs(m[0][1] - m[1][0]) < epsilon &&
144  fabs(m[1][2] - m[2][1]) < epsilon &&
145  fabs(m[0][2] - m[2][0]) < epsilon) {
146  if (fabs(m[0][1] + m[1][0]) < 0.1 && fabs(m[1][2] + m[2][1]) < 0.1 &&
147  fabs(m[0][2] + m[2][0]) < 0.1 && a > 0.9) {
148  r[0] = 0;
149  r[1] = 0;
150  r[2] = 0;
151  } else {
152  const Float ha = Float(sqrt(0.5) * 3.14159265358979323846);
153  double xx = (m[0][0] + 1.0) / 2.0;
154  double yy = (m[1][1] + 1.0) / 2.0;
155  double zz = (m[2][2] + 1.0) / 2.0;
156  double xy = (m[0][1] + m[1][0]) / 4.0;
157  double xz = (m[0][2] + m[2][0]) / 4.0;
158  double yz = (m[1][2] + m[2][1]) / 4.0;
159 
160  if ((xx > yy) && (xx > zz)) {
161  if (xx < epsilon) {
162  r[0] = 0;
163  r[1] = r[2] = ha;
164  } else {
165  double t = sqrt(xx);
166  r[0] = Float(t * 3.14159265358979323846);
167  r[1] = Float(xy / t * 3.14159265358979323846);
168  r[2] = Float(xz / t * 3.14159265358979323846);
169  }
170  } else if (yy > zz) {
171  if (yy < epsilon) {
172  r[0] = r[2] = ha;
173  r[1] = 0;
174  } else {
175  double t = sqrt(yy);
176  r[0] = Float(xy / t * 3.14159265358979323846);
177  r[1] = Float(t * 3.14159265358979323846);
178  r[2] = Float(yz / t * 3.14159265358979323846);
179  }
180  } else {
181  if (zz < epsilon) {
182  r[0] = r[1] = ha;
183  r[2] = 0;
184  } else {
185  double t = sqrt(zz);
186  r[0] = Float(xz / t * 3.14159265358979323846);
187  r[1] = Float(yz / t * 3.14159265358979323846);
188  r[2] = Float(t * 3.14159265358979323846);
189  }
190  }
191  }
192  } else {
193  a = acos(a);
194  double b = 0.5 * a / sin(a);
195  r[0] = Float(b * (m[2][1] - m[1][2]));
196  r[1] = Float(b * (m[0][2] - m[2][0]));
197  r[2] = Float(b * (m[1][0] - m[0][1]));
198  }
199  }
201  template <class Float>
202  void SetQuaternionRotation(const Float q[4]) {
203  double qq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
204  double qw, qx, qy, qz;
205  if (qq > 0) {
206  qw = q[0] / qq;
207  qx = q[1] / qq;
208  qy = q[2] / qq;
209  qz = q[3] / qq;
210  } else {
211  qw = 1;
212  qx = qy = qz = 0;
213  }
214  m[0][0] = float_t(qw * qw + qx * qx - qz * qz - qy * qy);
215  m[0][1] = float_t(2 * qx * qy - 2 * qz * qw);
216  m[0][2] = float_t(2 * qy * qw + 2 * qz * qx);
217  m[1][0] = float_t(2 * qx * qy + 2 * qw * qz);
218  m[1][1] = float_t(qy * qy + qw * qw - qz * qz - qx * qx);
219  m[1][2] = float_t(2 * qz * qy - 2 * qx * qw);
220  m[2][0] = float_t(2 * qx * qz - 2 * qy * qw);
221  m[2][1] = float_t(2 * qy * qz + 2 * qw * qx);
222  m[2][2] = float_t(qz * qz + qw * qw - qy * qy - qx * qx);
223  }
224  template <class Float>
225  void GetQuaternionRotation(Float q[4]) const {
226  q[0] = 1 + m[0][0] + m[1][1] + m[2][2];
227  if (q[0] > 0.000000001) {
228  q[0] = sqrt(q[0]) / 2.0;
229  q[1] = (m[2][1] - m[1][2]) / (4.0 * q[0]);
230  q[2] = (m[0][2] - m[2][0]) / (4.0 * q[0]);
231  q[3] = (m[1][0] - m[0][1]) / (4.0 * q[0]);
232  } else {
233  double s;
234  if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) {
235  s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]);
236  q[1] = 0.25 * s;
237  q[2] = (m[0][1] + m[1][0]) / s;
238  q[3] = (m[0][2] + m[2][0]) / s;
239  q[0] = (m[1][2] - m[2][1]) / s;
240  } else if (m[1][1] > m[2][2]) {
241  s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]);
242  q[1] = (m[0][1] + m[1][0]) / s;
243  q[2] = 0.25 * s;
244  q[3] = (m[1][2] + m[2][1]) / s;
245  q[0] = (m[0][2] - m[2][0]) / s;
246  } else {
247  s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]);
248  q[1] = (m[0][2] + m[2][0]) / s;
249  q[2] = (m[1][2] + m[2][1]) / s;
250  q[3] = 0.25f * s;
251  q[0] = (m[0][1] - m[1][0]) / s;
252  }
253  }
254  }
256  template <class Float>
257  void SetMatrixRotation(const Float* r) {
258  int k = 0;
259  for (int i = 0; i < 3; ++i) {
260  for (int j = 0; j < 3; ++j) {
261  m[i][j] = float_t(r[k++]);
262  }
263  }
264  }
265  template <class Float>
266  void GetMatrixRotation(Float* r) const {
267  int k = 0;
268  for (int i = 0; i < 3; ++i) {
269  for (int j = 0; j < 3; ++j) {
270  r[k++] = Float(m[i][j]);
271  }
272  }
273  }
275  return m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] +
276  m[0][2] * m[1][0] * m[2][1] - m[0][2] * m[1][1] * m[2][0] -
277  m[0][1] * m[1][0] * m[2][2] - m[0][0] * m[1][2] * m[2][1];
278  }
280  template <class Float>
281  void SetTranslation(const Float T[3]) {
282  t[0] = (float_t)T[0];
283  t[1] = (float_t)T[1];
284  t[2] = (float_t)T[2];
285  }
286  template <class Float>
287  void GetTranslation(Float T[3]) const {
288  T[0] = (Float)t[0];
289  T[1] = (Float)t[1];
290  T[2] = (Float)t[2];
291  }
293  template <class Float>
294  void SetCameraCenterAfterRotation(const Float c[3]) {
295  // t = - R * C
296  for (int j = 0; j < 3; ++j)
297  t[j] = -float_t(m[j][0] * c[0] + m[j][1] * c[1] + m[j][2] * c[2]);
298  }
299  template <class Float>
300  void GetCameraCenter(Float c[3]) {
301  // C = - R' * t
302  for (int j = 0; j < 3; ++j)
303  c[j] = -float_t(m[0][j] * t[0] + m[1][j] * t[1] + m[2][j] * t[2]);
304  }
306  template <class Float>
307  void SetInvertedRT(const Float e[3], const Float T[3]) {
309  for (int i = 3; i < 9; ++i) m[0][i] = -m[0][i];
310  SetTranslation(T);
311  t[1] = -t[1];
312  t[2] = -t[2];
313  }
314 
315  template <class Float>
316  void GetInvertedRT(Float e[3], Float T[3]) const {
317  CameraT ci;
318  ci.SetMatrixRotation(m[0]);
319  for (int i = 3; i < 9; ++i) ci.m[0][i] = -ci.m[0][i];
320  // for(int i = 1; i < 3; ++i) for(int j = 0; j < 3; ++j) ci.m[i][j] = -
321  // ci.m[i][j];
322  ci.GetRodriguesRotation(e);
323  GetTranslation(T);
324  T[1] = -T[1];
325  T[2] = -T[2];
326  }
327  template <class Float>
328  void SetInvertedR9T(const Float e[9], const Float T[3]) {
329  // for(int i = 0; i < 9; ++i) m[0][i] = (i < 3 ? e[i] : - e[i]);
330  // SetTranslation(T); t[1] = - t[1]; t[2] = -t[2];
331  m[0][0] = e[0];
332  m[0][1] = e[1];
333  m[0][2] = e[2];
334  m[1][0] = -e[3];
335  m[1][1] = -e[4];
336  m[1][2] = -e[5];
337  m[2][0] = -e[6];
338  m[2][1] = -e[7];
339  m[2][2] = -e[8];
340  t[0] = T[0];
341  t[1] = -T[1];
342  t[2] = -T[2];
343  }
344  template <class Float>
345  void GetInvertedR9T(Float e[9], Float T[3]) const {
346  e[0] = m[0][0];
347  e[1] = m[0][1];
348  e[2] = m[0][2];
349  e[3] = -m[1][0];
350  e[4] = -m[1][1];
351  e[5] = -m[1][2];
352  e[6] = -m[2][0];
353  e[7] = -m[2][1];
354  e[8] = -m[2][2];
355  T[0] = t[0];
356  T[1] = -t[1];
357  T[2] = -t[2];
358  }
359 };
360 
361 template <class FT>
362 struct Point3D {
363  typedef FT float_t;
364  float_t xyz[3]; // 3D point location
365  float_t reserved; // alignment
367  template <class Float>
368  void SetPoint(Float x, Float y, Float z) {
369  xyz[0] = (float_t)x;
370  xyz[1] = (float_t)y;
371  xyz[2] = (float_t)z;
372  reserved = 0;
373  }
374  template <class Float>
375  void SetPoint(const Float* p) {
376  xyz[0] = (float_t)p[0];
377  xyz[1] = (float_t)p[1];
378  xyz[2] = (float_t)p[2];
379  reserved = 0;
380  }
381  template <class Float>
382  void GetPoint(Float* p) const {
383  p[0] = (Float)xyz[0];
384  p[1] = (Float)xyz[1];
385  p[2] = (Float)xyz[2];
386  }
387  template <class Float>
388  void GetPoint(Float& x, Float& y, Float& z) const {
389  x = (Float)xyz[0];
390  y = (Float)xyz[1];
391  z = (Float)xyz[2];
392  }
393 };
394 
395 #undef CameraT
396 #undef Point3D
397 
400 
401 struct Point2D {
402  float x, y;
404  Point2D() {}
405  template <class Float>
406  Point2D(Float X, Float Y) {
407  SetPoint2D(X, Y);
408  }
409  template <class Float>
410  void SetPoint2D(Float X, Float Y) {
411  x = (float)X;
412  y = (float)Y;
413  }
414  template <class Float>
415  void GetPoint2D(Float& X, Float& Y) const {
416  X = (Float)x;
417  Y = (Float)y;
418  }
419 };
420 
421 } // namespace pba
422 
423 #endif
void * X
Definition: SmallVector.cpp:45
__host__ __device__ float2 fabs(float2 v)
Definition: cutil_math.h:1254
Definition: ConfigBA.cpp:44
CameraT_< float > CameraT
Point3D_< float > Point3D
void GetInvertedRT(Float e[3], Float T[3]) const
void GetQuaternionRotation(Float q[4]) const
float_t constant_camera
Definition: DataInterface.h:56
float_t GetMeasurementDistortion() const
Definition: DataInterface.h:97
void GetRodriguesRotation(Float r[3]) const
void GetInvertedR9T(Float e[9], Float T[3]) const
void SetTranslation(const Float T[3])
float_t m[3][3]
Definition: DataInterface.h:53
void GetTranslation(Float T[3]) const
void SetMatrixRotation(const Float *r)
void SetMeasurementDistortion(Float r)
Definition: DataInterface.h:93
void SetProjectionDistortion(const Float *r)
void SetProjectionDistortion(Float r)
float_t GetFocalLength() const
Definition: DataInterface.h:90
float_t t[3]
Definition: DataInterface.h:52
float_t GetNormalizedMeasurementDistortion() const
void SetInvertedR9T(const Float e[9], const Float T[3])
void SetCameraCenterAfterRotation(const Float c[3])
void SetFixedIntrinsic()
Definition: DataInterface.h:82
void SetQuaternionRotation(const Float q[4])
void SetConstantCamera()
Definition: DataInterface.h:80
void SetInvertedRT(const Float e[3], const Float T[3])
void SetCameraT(const CameraX &cam)
Definition: DataInterface.h:67
void SetFocalLength(Float F)
Definition: DataInterface.h:87
void SetRodriguesRotation(const Float r[3])
void SetVariableCamera()
Definition: DataInterface.h:81
float_t GetProjectionDistortion() const
void GetCameraCenter(Float c[3])
float GetRotationMatrixDeterminant() const
void GetMatrixRotation(Float *r) const
float_t radial
Definition: DataInterface.h:54
void SetNormalizedMeasurementDistortion(Float r)
Point2D(Float X, Float Y)
void GetPoint2D(Float &X, Float &Y) const
void SetPoint2D(Float X, Float Y)
void GetPoint(Float *p) const
void SetPoint(Float x, Float y, Float z)
void SetPoint(const Float *p)
void GetPoint(Float &x, Float &y, Float &z) const
float_t xyz[3]
float_t reserved