Calibration Library 1.0.0
A C++ library for camera calibration and vision-related geometric transformations
Loading...
Searching...
No Matches
planarpose_linear.cpp
Go to the documentation of this file.
2
3// std
4#include <algorithm>
5#include <array>
6#include <iostream>
7#include <numeric>
8
9// Eigen
10#include <Eigen/Dense>
11#include <Eigen/Geometry>
12
14
15namespace calib {
16
17Eigen::Isometry3d pose_from_homography_normalized(const Eigen::Matrix3d& hmtx) {
18 Eigen::Vector3d hcol1 = hmtx.col(0);
19 Eigen::Vector3d hcol2 = hmtx.col(1);
20 Eigen::Vector3d hcol3 = hmtx.col(2);
21
22 double s = std::sqrt(hcol1.norm() * hcol2.norm());
23 if (s < 1e-12) {
24 s = 1.0;
25 }
26 Eigen::Vector3d rcol1 = hcol1 / s;
27 Eigen::Vector3d rcol2 = hcol2 / s;
28 Eigen::Vector3d rcol3 = rcol1.cross(rcol2);
29
30 Eigen::Matrix3d r_init;
31 r_init.col(0) = rcol1;
32 r_init.col(1) = rcol2;
33 r_init.col(2) = rcol3;
34
35 Eigen::JacobiSVD<Eigen::Matrix3d> svd(r_init, Eigen::ComputeFullU | Eigen::ComputeFullV);
36 Eigen::Matrix3d rotation = svd.matrixU() * svd.matrixV().transpose();
37 if (rotation.determinant() < 0) {
38 Eigen::Matrix3d vmtx = svd.matrixV();
39 vmtx.col(2) *= -1.0;
40 rotation = svd.matrixU() * vmtx.transpose();
41 }
42 Eigen::Vector3d translation = hcol3 / s;
43 if (rotation(2, 2) < 0) {
44 rotation = -rotation;
45 translation = -translation;
46 }
47
48 Eigen::Isometry3d pose = Eigen::Isometry3d::Identity();
49 pose.linear() = rotation;
50 pose.translation() = translation;
51 return pose;
52}
53
54auto estimate_planar_pose(PlanarView view, const CameraMatrix& intrinsics) -> Eigen::Isometry3d {
55 if (view.size() < 4) {
56 return Eigen::Isometry3d::Identity();
57 }
58
59 std::for_each(view.begin(), view.end(), [&intrinsics](PlanarObservation& obs) {
60 obs.image_uv = normalize(intrinsics, obs.image_uv);
61 });
62
63 std::vector<int> sample(view.size());
64 std::iota(sample.begin(), sample.end(), 0);
65 auto h_opt = HomographyEstimator::fit(view, sample);
66 if (!h_opt.has_value()) {
67 std::cerr << "Failed to estimate homography using DLT" << std::endl;
68 return Eigen::Isometry3d::Identity();
69 }
70
71 Eigen::Matrix3d hmtx = h_opt.value();
72 if (std::abs(hmtx(2, 2)) > 1e-15) {
73 hmtx /= hmtx(2, 2);
74 }
76}
77
78} // namespace calib
Linear multi-camera extrinsics initialisation (DLT)
auto estimate_planar_pose(PlanarView view, const CameraMatrix &intrinsics) -> Eigen::Isometry3d
std::vector< PlanarObservation > PlanarView
Definition planarpose.h:26
auto pose_from_homography_normalized(const Eigen::Matrix3d &hmtx) -> Eigen::Isometry3d
static auto fit(const std::vector< Datum > &data, std::span< const int > sample) -> std::optional< Model >