Calibration Library 1.0.0
A C++ library for camera calibration and vision-related geometric transformations
Loading...
Searching...
No Matches
posefromhomography.cpp
Go to the documentation of this file.
2
3// std
5
6#include <cmath>
7#include <iostream>
8#include <limits>
9
10namespace calib {
11
12auto pose_from_homography(const CameraMatrix& kmtx, const Eigen::Matrix3d& hmtx)
15
16 // Basic checks
17 if (!std::isfinite(kmtx.fx) || !std::isfinite(kmtx.fy) || kmtx.cx <= 0 || kmtx.cy <= 0) {
18 std::cerr << "Invalid camera matrix K:\n" << matrix(kmtx) << "\n";
19 out.message = "Invalid camera matrix K";
20 return out;
21 }
22 if (!std::isfinite(hmtx(2, 2))) {
23 out.message = "Invalid homography H.";
24 return out;
25 }
26
27 // 1) Remove intrinsics
28 const Eigen::Matrix3d hnorm = matrix(kmtx).inverse() * hmtx;
29
30 // 2) Compute scale from first two columns
31 const double n1 = hnorm.col(0).norm();
32 const double n2 = hnorm.col(1).norm();
33
34 constexpr double eps = 1e-15;
35 if (!(n1 > eps) || !(n2 > eps)) {
36 out.message = "Degenerate H: zero column norm.";
37 return out;
38 }
39
40 const double scale = 1.0 / ((n1 + n2) * 0.5); // mean-based scale is numerically stable
41 out.scale = scale;
42 out.cond_check = (n1 > n2) ? (n1 / n2) : (n2 / n1);
43
44 // 3) Raw r1,r2,t (before orthonormalization)
45 Eigen::Matrix3d rotation;
46 rotation.col(0) = scale * hnorm.col(0);
47 rotation.col(1) = scale * hnorm.col(1);
48 rotation.col(2) = rotation.col(0).cross(rotation.col(1));
49 rotation = project_to_so3(rotation);
50
51 Eigen::Vector3d translation = scale * hnorm.col(2);
52
53 // 4) Build preliminary rotation with r3 = r1 x r2
54
55 // 6) Prefer a solution with the target plane in front of the camera (t_z > 0)
56 // For points near the plane origin (X≈Y≈0), Zc ≈ t_z.
57 if (translation.z() <= 0) {
58 rotation = -rotation;
59 translation = -translation;
60 }
61
62 out.success = true;
63 out.c_se3_t.linear() = rotation;
64 out.c_se3_t.translation() = translation;
65 out.message = "OK";
66 return out;
67}
68
69auto homography_consistency_fro(const CameraMatrix& kmtx, const Eigen::Isometry3d& c_se3_t,
70 const Eigen::Matrix3d& hmtx) -> double {
71 Eigen::Matrix3d hrt = Eigen::Matrix3d::Zero();
72 hrt.col(0) = c_se3_t.linear().col(0);
73 hrt.col(1) = c_se3_t.linear().col(1);
74 hrt.col(2) = c_se3_t.translation();
75 const Eigen::Matrix3d hmtx_hat = matrix(kmtx) * hrt;
76
77 const double num = (hmtx_hat - hmtx).norm();
78 const double den = hmtx.norm();
79 return (den > 0) ? (num / den) : std::numeric_limits<double>::infinity();
80}
81
82} // namespace calib
Linear multi-camera extrinsics initialisation (DLT)
auto pose_from_homography(const CameraMatrix &kmtx, const Eigen::Matrix3d &hmtx) -> PoseFromHResult
Estimates the camera pose from a homography matrix.
auto homography_consistency_fro(const CameraMatrix &kmtx, const Eigen::Isometry3d &c_se3_t, const Eigen::Matrix3d &hmtx) -> double
A quick consistency check.
Eigen::Matrix3d project_to_so3(const Eigen::Matrix3d &rmtx)
Definition se3_utils.h:10
auto matrix(const CameraMatrixT< Scalar > &cam) -> Eigen::Matrix< Scalar, 3, 3 >
Recover target->camera pose (R,t) from camera matrix K and planar homography H.
Eigen::Isometry3d c_se3_t