| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef DATA_INTERFACE_GPU_H |
| | #define DATA_INTERFACE_GPU_H |
| |
|
| | #include <math.h> |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | namespace pba { |
| |
|
| | |
| | #define CameraT CameraT_ |
| | #define Point3D Point3D_ |
| | template <class FT> |
| |
|
| | struct CameraT_ { |
| | typedef FT float_t; |
| | |
| | float_t f; |
| | float_t t[3]; |
| | float_t m[3][3]; |
| | float_t radial; |
| | int distortion_type; |
| | float_t constant_camera; |
| |
|
| | |
| | CameraT_() { |
| | radial = 0; |
| | distortion_type = 0; |
| | constant_camera = 0; |
| | } |
| |
|
| | |
| | template <class CameraX> |
| | void SetCameraT(const CameraX& cam) { |
| | f = (float_t)cam.f; |
| | t[0] = (float_t)cam.t[0]; |
| | t[1] = (float_t)cam.t[1]; |
| | t[2] = (float_t)cam.t[2]; |
| | for (int i = 0; i < 3; ++i) |
| | for (int j = 0; j < 3; ++j) m[i][j] = (float_t)cam.m[i][j]; |
| | radial = (float_t)cam.radial; |
| | distortion_type = cam.distortion_type; |
| | constant_camera = cam.constant_camera; |
| | } |
| |
|
| | |
| | void SetConstantCamera() { constant_camera = 1.0f; } |
| | void SetVariableCamera() { constant_camera = 0.0f; } |
| | void SetFixedIntrinsic() { constant_camera = 2.0f; } |
| | |
| |
|
| | |
| | template <class Float> |
| | void SetFocalLength(Float F) { |
| | f = (float_t)F; |
| | } |
| | float_t GetFocalLength() const { return f; } |
| |
|
| | template <class Float> |
| | void SetMeasurementDistortion(Float r) { |
| | radial = (float_t)r; |
| | distortion_type = -1; |
| | } |
| | float_t GetMeasurementDistortion() const { |
| | return distortion_type == -1 ? radial : 0; |
| | } |
| |
|
| | |
| | template <class Float> |
| | void SetNormalizedMeasurementDistortion(Float r) { |
| | SetMeasurementDistortion(r / (f * f)); |
| | } |
| | float_t GetNormalizedMeasurementDistortion() const { |
| | return GetMeasurementDistortion() * (f * f); |
| | } |
| |
|
| | |
| | template <class Float> |
| | void SetProjectionDistortion(Float r) { |
| | radial = float_t(r); |
| | distortion_type = 1; |
| | } |
| | template <class Float> |
| | void SetProjectionDistortion(const Float* r) { |
| | SetProjectionDistortion(r[0]); |
| | } |
| | float_t GetProjectionDistortion() const { |
| | return distortion_type == 1 ? radial : 0; |
| | } |
| |
|
| | template <class Float> |
| | void SetRodriguesRotation(const Float r[3]) { |
| | double a = sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); |
| | double ct = a == 0.0 ? 0.5 : (1.0 - cos(a)) / a / a; |
| | double st = a == 0.0 ? 1 : sin(a) / a; |
| | m[0][0] = float_t(1.0 - (r[1] * r[1] + r[2] * r[2]) * ct); |
| | m[0][1] = float_t(r[0] * r[1] * ct - r[2] * st); |
| | m[0][2] = float_t(r[2] * r[0] * ct + r[1] * st); |
| | m[1][0] = float_t(r[0] * r[1] * ct + r[2] * st); |
| | m[1][1] = float_t(1.0 - (r[2] * r[2] + r[0] * r[0]) * ct); |
| | m[1][2] = float_t(r[1] * r[2] * ct - r[0] * st); |
| | m[2][0] = float_t(r[2] * r[0] * ct - r[1] * st); |
| | m[2][1] = float_t(r[1] * r[2] * ct + r[0] * st); |
| | m[2][2] = float_t(1.0 - (r[0] * r[0] + r[1] * r[1]) * ct); |
| | } |
| | template <class Float> |
| | void GetRodriguesRotation(Float r[3]) const { |
| | double a = (m[0][0] + m[1][1] + m[2][2] - 1.0) / 2.0; |
| | const double epsilon = 0.01; |
| | if (fabs(m[0][1] - m[1][0]) < epsilon && |
| | fabs(m[1][2] - m[2][1]) < epsilon && |
| | fabs(m[0][2] - m[2][0]) < epsilon) { |
| | if (fabs(m[0][1] + m[1][0]) < 0.1 && fabs(m[1][2] + m[2][1]) < 0.1 && |
| | fabs(m[0][2] + m[2][0]) < 0.1 && a > 0.9) { |
| | r[0] = 0; |
| | r[1] = 0; |
| | r[2] = 0; |
| | } else { |
| | const Float ha = Float(sqrt(0.5) * 3.14159265358979323846); |
| | double xx = (m[0][0] + 1.0) / 2.0; |
| | double yy = (m[1][1] + 1.0) / 2.0; |
| | double zz = (m[2][2] + 1.0) / 2.0; |
| | double xy = (m[0][1] + m[1][0]) / 4.0; |
| | double xz = (m[0][2] + m[2][0]) / 4.0; |
| | double yz = (m[1][2] + m[2][1]) / 4.0; |
| |
|
| | if ((xx > yy) && (xx > zz)) { |
| | if (xx < epsilon) { |
| | r[0] = 0; |
| | r[1] = r[2] = ha; |
| | } else { |
| | double t = sqrt(xx); |
| | r[0] = Float(t * 3.14159265358979323846); |
| | r[1] = Float(xy / t * 3.14159265358979323846); |
| | r[2] = Float(xz / t * 3.14159265358979323846); |
| | } |
| | } else if (yy > zz) { |
| | if (yy < epsilon) { |
| | r[0] = r[2] = ha; |
| | r[1] = 0; |
| | } else { |
| | double t = sqrt(yy); |
| | r[0] = Float(xy / t * 3.14159265358979323846); |
| | r[1] = Float(t * 3.14159265358979323846); |
| | r[2] = Float(yz / t * 3.14159265358979323846); |
| | } |
| | } else { |
| | if (zz < epsilon) { |
| | r[0] = r[1] = ha; |
| | r[2] = 0; |
| | } else { |
| | double t = sqrt(zz); |
| | r[0] = Float(xz / t * 3.14159265358979323846); |
| | r[1] = Float(yz / t * 3.14159265358979323846); |
| | r[2] = Float(t * 3.14159265358979323846); |
| | } |
| | } |
| | } |
| | } else { |
| | a = acos(a); |
| | double b = 0.5 * a / sin(a); |
| | r[0] = Float(b * (m[2][1] - m[1][2])); |
| | r[1] = Float(b * (m[0][2] - m[2][0])); |
| | r[2] = Float(b * (m[1][0] - m[0][1])); |
| | } |
| | } |
| | |
| | template <class Float> |
| | void SetQuaternionRotation(const Float q[4]) { |
| | double qq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); |
| | double qw, qx, qy, qz; |
| | if (qq > 0) { |
| | qw = q[0] / qq; |
| | qx = q[1] / qq; |
| | qy = q[2] / qq; |
| | qz = q[3] / qq; |
| | } else { |
| | qw = 1; |
| | qx = qy = qz = 0; |
| | } |
| | m[0][0] = float_t(qw * qw + qx * qx - qz * qz - qy * qy); |
| | m[0][1] = float_t(2 * qx * qy - 2 * qz * qw); |
| | m[0][2] = float_t(2 * qy * qw + 2 * qz * qx); |
| | m[1][0] = float_t(2 * qx * qy + 2 * qw * qz); |
| | m[1][1] = float_t(qy * qy + qw * qw - qz * qz - qx * qx); |
| | m[1][2] = float_t(2 * qz * qy - 2 * qx * qw); |
| | m[2][0] = float_t(2 * qx * qz - 2 * qy * qw); |
| | m[2][1] = float_t(2 * qy * qz + 2 * qw * qx); |
| | m[2][2] = float_t(qz * qz + qw * qw - qy * qy - qx * qx); |
| | } |
| | template <class Float> |
| | void GetQuaternionRotation(Float q[4]) const { |
| | q[0] = 1 + m[0][0] + m[1][1] + m[2][2]; |
| | if (q[0] > 0.000000001) { |
| | q[0] = sqrt(q[0]) / 2.0; |
| | q[1] = (m[2][1] - m[1][2]) / (4.0 * q[0]); |
| | q[2] = (m[0][2] - m[2][0]) / (4.0 * q[0]); |
| | q[3] = (m[1][0] - m[0][1]) / (4.0 * q[0]); |
| | } else { |
| | double s; |
| | if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) { |
| | s = 2.0 * sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]); |
| | q[1] = 0.25 * s; |
| | q[2] = (m[0][1] + m[1][0]) / s; |
| | q[3] = (m[0][2] + m[2][0]) / s; |
| | q[0] = (m[1][2] - m[2][1]) / s; |
| | } else if (m[1][1] > m[2][2]) { |
| | s = 2.0 * sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]); |
| | q[1] = (m[0][1] + m[1][0]) / s; |
| | q[2] = 0.25 * s; |
| | q[3] = (m[1][2] + m[2][1]) / s; |
| | q[0] = (m[0][2] - m[2][0]) / s; |
| | } else { |
| | s = 2.0 * sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]); |
| | q[1] = (m[0][2] + m[2][0]) / s; |
| | q[2] = (m[1][2] + m[2][1]) / s; |
| | q[3] = 0.25f * s; |
| | q[0] = (m[0][1] - m[1][0]) / s; |
| | } |
| | } |
| | } |
| | |
| | template <class Float> |
| | void SetMatrixRotation(const Float* r) { |
| | int k = 0; |
| | for (int i = 0; i < 3; ++i) { |
| | for (int j = 0; j < 3; ++j) { |
| | m[i][j] = float_t(r[k++]); |
| | } |
| | } |
| | } |
| | template <class Float> |
| | void GetMatrixRotation(Float* r) const { |
| | int k = 0; |
| | for (int i = 0; i < 3; ++i) { |
| | for (int j = 0; j < 3; ++j) { |
| | r[k++] = Float(m[i][j]); |
| | } |
| | } |
| | } |
| | float GetRotationMatrixDeterminant() const { |
| | return m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + |
| | m[0][2] * m[1][0] * m[2][1] - m[0][2] * m[1][1] * m[2][0] - |
| | m[0][1] * m[1][0] * m[2][2] - m[0][0] * m[1][2] * m[2][1]; |
| | } |
| | |
| | template <class Float> |
| | void SetTranslation(const Float T[3]) { |
| | t[0] = (float_t)T[0]; |
| | t[1] = (float_t)T[1]; |
| | t[2] = (float_t)T[2]; |
| | } |
| | template <class Float> |
| | void GetTranslation(Float T[3]) const { |
| | T[0] = (Float)t[0]; |
| | T[1] = (Float)t[1]; |
| | T[2] = (Float)t[2]; |
| | } |
| | |
| | template <class Float> |
| | void SetCameraCenterAfterRotation(const Float c[3]) { |
| | |
| | for (int j = 0; j < 3; ++j) |
| | t[j] = -float_t(m[j][0] * c[0] + m[j][1] * c[1] + m[j][2] * c[2]); |
| | } |
| | template <class Float> |
| | void GetCameraCenter(Float c[3]) { |
| | |
| | for (int j = 0; j < 3; ++j) |
| | c[j] = -float_t(m[0][j] * t[0] + m[1][j] * t[1] + m[2][j] * t[2]); |
| | } |
| | |
| | template <class Float> |
| | void SetInvertedRT(const Float e[3], const Float T[3]) { |
| | SetRodriguesRotation(e); |
| | for (int i = 3; i < 9; ++i) m[0][i] = -m[0][i]; |
| | SetTranslation(T); |
| | t[1] = -t[1]; |
| | t[2] = -t[2]; |
| | } |
| |
|
| | template <class Float> |
| | void GetInvertedRT(Float e[3], Float T[3]) const { |
| | CameraT ci; |
| | ci.SetMatrixRotation(m[0]); |
| | for (int i = 3; i < 9; ++i) ci.m[0][i] = -ci.m[0][i]; |
| | |
| | |
| | ci.GetRodriguesRotation(e); |
| | GetTranslation(T); |
| | T[1] = -T[1]; |
| | T[2] = -T[2]; |
| | } |
| | template <class Float> |
| | void SetInvertedR9T(const Float e[9], const Float T[3]) { |
| | |
| | |
| | m[0][0] = e[0]; |
| | m[0][1] = e[1]; |
| | m[0][2] = e[2]; |
| | m[1][0] = -e[3]; |
| | m[1][1] = -e[4]; |
| | m[1][2] = -e[5]; |
| | m[2][0] = -e[6]; |
| | m[2][1] = -e[7]; |
| | m[2][2] = -e[8]; |
| | t[0] = T[0]; |
| | t[1] = -T[1]; |
| | t[2] = -T[2]; |
| | } |
| | template <class Float> |
| | void GetInvertedR9T(Float e[9], Float T[3]) const { |
| | e[0] = m[0][0]; |
| | e[1] = m[0][1]; |
| | e[2] = m[0][2]; |
| | e[3] = -m[1][0]; |
| | e[4] = -m[1][1]; |
| | e[5] = -m[1][2]; |
| | e[6] = -m[2][0]; |
| | e[7] = -m[2][1]; |
| | e[8] = -m[2][2]; |
| | T[0] = t[0]; |
| | T[1] = -t[1]; |
| | T[2] = -t[2]; |
| | } |
| | }; |
| |
|
| | template <class FT> |
| | struct Point3D { |
| | typedef FT float_t; |
| | float_t xyz[3]; |
| | float_t reserved; |
| | |
| | template <class Float> |
| | void SetPoint(Float x, Float y, Float z) { |
| | xyz[0] = (float_t)x; |
| | xyz[1] = (float_t)y; |
| | xyz[2] = (float_t)z; |
| | reserved = 0; |
| | } |
| | template <class Float> |
| | void SetPoint(const Float* p) { |
| | xyz[0] = (float_t)p[0]; |
| | xyz[1] = (float_t)p[1]; |
| | xyz[2] = (float_t)p[2]; |
| | reserved = 0; |
| | } |
| | template <class Float> |
| | void GetPoint(Float* p) const { |
| | p[0] = (Float)xyz[0]; |
| | p[1] = (Float)xyz[1]; |
| | p[2] = (Float)xyz[2]; |
| | } |
| | template <class Float> |
| | void GetPoint(Float& x, Float& y, Float& z) const { |
| | x = (Float)xyz[0]; |
| | y = (Float)xyz[1]; |
| | z = (Float)xyz[2]; |
| | } |
| | }; |
| |
|
| | #undef CameraT |
| | #undef Point3D |
| |
|
| | typedef CameraT_<float> CameraT; |
| | typedef Point3D_<float> Point3D; |
| |
|
| | struct Point2D { |
| | float x, y; |
| | |
| | Point2D() {} |
| | template <class Float> |
| | Point2D(Float X, Float Y) { |
| | SetPoint2D(X, Y); |
| | } |
| | template <class Float> |
| | void SetPoint2D(Float X, Float Y) { |
| | x = (float)X; |
| | y = (float)Y; |
| | } |
| | template <class Float> |
| | void GetPoint2D(Float& X, Float& Y) const { |
| | X = (Float)x; |
| | Y = (Float)y; |
| | } |
| | }; |
| |
|
| | } |
| |
|
| | #endif |
| |
|