Calibration Library 1.0.0
A C++ library for camera calibration and vision-related geometric transformations
Loading...
Searching...
No Matches
se3_utils.h
Go to the documentation of this file.
1#pragma once
2
3#include <Eigen/Core>
4#include <Eigen/Geometry>
5#include <array>
6#include <vector>
7
8namespace calib {
9
10inline Eigen::Matrix3d project_to_so3(const Eigen::Matrix3d& rmtx) {
11 Eigen::JacobiSVD<Eigen::Matrix3d> svd(rmtx, Eigen::ComputeFullU | Eigen::ComputeFullV);
12 const Eigen::Matrix3d& umtx = svd.matrixU();
13 Eigen::Matrix3d vmtx = svd.matrixV();
14 Eigen::Matrix3d sigma = Eigen::Matrix3d::Identity();
15 if ((umtx * vmtx.transpose()).determinant() < 0.0) {
16 sigma(2, 2) = -1.0;
17 }
18 return umtx * sigma * vmtx.transpose();
19}
20
21inline Eigen::Matrix3d skew(const Eigen::Vector3d& vec) {
22 Eigen::Matrix3d skew_mtx;
23 skew_mtx << 0, -vec.z(), vec.y(), vec.z(), 0, -vec.x(), -vec.y(), vec.x(), 0;
24 return skew_mtx;
25}
26
27inline Eigen::Vector3d log_so3(const Eigen::Matrix3d& rot_in) {
28 const Eigen::Matrix3d rotation = project_to_so3(rot_in);
29 double cos_theta = (rotation.trace() - 1.0) * 0.5;
30 cos_theta = std::min(1.0, std::max(-1.0, cos_theta));
31 double theta = std::acos(cos_theta);
32 if (theta < 1e-12) {
33 return Eigen::Vector3d::Zero();
34 }
35 Eigen::Vector3d wvec;
36 wvec << rotation(2, 1) - rotation(1, 2), rotation(0, 2) - rotation(2, 0),
37 rotation(1, 0) - rotation(0, 1);
38 wvec *= 0.5 / std::sin(theta);
39 return wvec * theta;
40}
41
42inline Eigen::Matrix3d exp_so3(const Eigen::Vector3d& wvec) {
43 double theta = wvec.norm();
44 if (theta < 1e-12) {
45 return Eigen::Matrix3d::Identity();
46 }
47 Eigen::Vector3d avec = wvec / theta;
48 Eigen::Matrix3d askew = skew(avec);
49 return Eigen::Matrix3d::Identity() + std::sin(theta) * askew +
50 (1.0 - std::cos(theta)) * (askew * askew);
51}
52
53inline Eigen::VectorXd solve_llsq(const Eigen::MatrixXd& amtx, const Eigen::VectorXd& bvec) {
54 return amtx.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(bvec);
55}
56
57template <class Mat, class Vec>
58inline Eigen::VectorXd ridge_llsq(const Mat& amtx, const Vec& bvec, double lambda = 1e-10) {
59 const int ncols = static_cast<int>(amtx.cols());
60 return (amtx.transpose() * amtx + lambda * Eigen::MatrixXd::Identity(ncols, ncols))
61 .ldlt()
62 .solve(amtx.transpose() * bvec);
63}
64
65inline std::array<double, 6> pose_to_array(const Eigen::Isometry3d& pose) {
66 Eigen::AngleAxisd axisangle(pose.linear());
67 return {axisangle.axis().x() * axisangle.angle(),
68 axisangle.axis().y() * axisangle.angle(),
69 axisangle.axis().z() * axisangle.angle(),
70 pose.translation().x(),
71 pose.translation().y(),
72 pose.translation().z()};
73}
74
75inline Eigen::Isometry3d average_isometries(const std::vector<Eigen::Isometry3d>& poses) {
76 if (poses.empty()) {
77 return Eigen::Isometry3d::Identity();
78 }
79 Eigen::Vector3d translation = Eigen::Vector3d::Zero();
80 Eigen::Quaterniond q_sum(0, 0, 0, 0);
81 for (const auto& p : poses) {
82 translation += p.translation();
83 Eigen::Quaterniond q(p.linear());
84 if (q_sum.coeffs().dot(q.coeffs()) < 0.0) {
85 q.coeffs() *= -1.0;
86 }
87 q_sum.coeffs() += q.coeffs();
88 }
89 translation /= static_cast<double>(poses.size());
90 q_sum.normalize();
91 Eigen::Isometry3d avg = Eigen::Isometry3d::Identity();
92 avg.linear() = q_sum.toRotationMatrix();
93 avg.translation() = translation;
94 return avg;
95}
96
97} // namespace calib
Linear multi-camera extrinsics initialisation (DLT)
Eigen::Isometry3d average_isometries(const std::vector< Eigen::Isometry3d > &poses)
Definition se3_utils.h:75
Eigen::VectorXd solve_llsq(const Eigen::MatrixXd &amtx, const Eigen::VectorXd &bvec)
Definition se3_utils.h:53
Eigen::Vector3d log_so3(const Eigen::Matrix3d &rot_in)
Definition se3_utils.h:27
std::array< double, 6 > pose_to_array(const Eigen::Isometry3d &pose)
Definition se3_utils.h:65
Eigen::Matrix3d skew(const Eigen::Vector3d &vec)
Definition se3_utils.h:21
Eigen::VectorXd ridge_llsq(const Mat &amtx, const Vec &bvec, double lambda=1e-10)
Definition se3_utils.h:58
Eigen::Matrix3d exp_so3(const Eigen::Vector3d &wvec)
Definition se3_utils.h:42
Eigen::Matrix3d project_to_so3(const Eigen::Matrix3d &rmtx)
Definition se3_utils.h:10