40 if (view.size() < 4) {
41 return Eigen::Isometry3d::Identity();
46 obs.image_uv = camera.template apply_intrinsics<double>(obs.image_uv);
51 std::vector<Eigen::Vector2d>& out) -> Eigen::Matrix3d {
52 out.resize(pts.size());
53 const Eigen::Vector2d centroid =
54 std::accumulate(pts.begin(), pts.end(), Eigen::Vector2d{0, 0}) /
55 std::max<size_t>(1, pts.size());
56 const double mean_dist = std::accumulate(pts.begin(), pts.end(), 0.0,
57 [¢roid](
double sum,
const Eigen::Vector2d& p) {
58 return sum + (p - centroid).norm();
60 static_cast<double>(std::max<size_t>(1, pts.size()));
61 const double sigma = (mean_dist > 0) ? std::sqrt(2.0) / mean_dist : 1.0;
63 Eigen::Matrix3d transform = Eigen::Matrix3d::Identity();
64 transform(0, 0) = sigma;
65 transform(1, 1) = sigma;
66 transform(0, 2) = -sigma * centroid.x();
67 transform(1, 2) = -sigma * centroid.y();
69 std::transform(pts.begin(), pts.end(), out.begin(),
70 [&transform](
const Eigen::Vector2d& pt) -> Eigen::Vector2d {
71 Eigen::Vector3d hp(pt.x(), pt.y(), 1.0);
72 Eigen::Vector3d hn = transform * hp;
73 return hn.hnormalized();
78 std::vector<Eigen::Vector2d> src_xy;
79 std::vector<Eigen::Vector2d> dst_uv;
80 src_xy.reserve(view.size());
81 dst_uv.reserve(view.size());
82 for (
const auto& obs : view) {
87 std::vector<Eigen::Vector2d> src_n, dst_n;
91 const auto npts =
static_cast<Eigen::Index
>(src_n.size());
92 Eigen::MatrixXd A(2 * npts, 9);
93 for (Eigen::Index i = 0; i < npts; ++i) {
94 const double x = src_n[i].x();
95 const double y = src_n[i].y();
96 const double u = dst_n[i].x();
97 const double v = dst_n[i].y();
98 A.row(2 * i) << -x, -y, -1, 0, 0, 0, u * x, u * y, u;
99 A.row(2 * i + 1) << 0, 0, 0, -x, -y, -1, v * x, v * y, v;
101 Eigen::JacobiSVD<Eigen::MatrixXd> svd(A, Eigen::ComputeFullV);
102 Eigen::VectorXd h = svd.matrixV().col(8);
103 Eigen::Matrix3d Hnorm;
104 Hnorm << h(0), h(1), h(2), h(3), h(4), h(5), h(6), h(7), h(8);
105 Eigen::Matrix3d hmtx = Tdst.inverse() * Hnorm * Tsrc;
106 if (std::abs(hmtx(2, 2)) > 1e-15) {