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";
22 if (!std::isfinite(hmtx(2, 2))) {
23 out.
message =
"Invalid homography H.";
28 const Eigen::Matrix3d hnorm =
matrix(kmtx).inverse() * hmtx;
31 const double n1 = hnorm.col(0).norm();
32 const double n2 = hnorm.col(1).norm();
34 constexpr double eps = 1e-15;
35 if (!(n1 > eps) || !(n2 > eps)) {
36 out.
message =
"Degenerate H: zero column norm.";
40 const double scale = 1.0 / ((n1 + n2) * 0.5);
42 out.
cond_check = (n1 > n2) ? (n1 / n2) : (n2 / n1);
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));
51 Eigen::Vector3d translation = scale * hnorm.col(2);
57 if (translation.z() <= 0) {
59 translation = -translation;
63 out.
c_se3_t.linear() = rotation;
64 out.
c_se3_t.translation() = translation;
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;
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();