| 534 | } |
| 535 | |
| 536 | int solve_scale_shift_pose_shared_focal(const Eigen::Matrix3x4d &x_homo, const Eigen::Matrix3x4d &y_homo, |
| 537 | const Eigen::Vector4d &depth_x, const Eigen::Vector4d &depth_y, |
| 538 | std::vector<PoseScaleOffsetSharedFocal> *output, bool scale_on_x) { |
| 539 | std::vector<Eigen::Vector<double, 5>> solutions; |
| 540 | if (scale_on_x) |
| 541 | solutions = solve_scale_and_shift_shared_focal(y_homo, x_homo, depth_y, depth_x); |
| 542 | else |
| 543 | solutions = solve_scale_and_shift_shared_focal(x_homo, y_homo, depth_x, depth_y); |
| 544 | output->clear(); |
| 545 | |
| 546 | int sol_count = 0; |
| 547 | for (auto &sol : solutions) { |
| 548 | Eigen::Vector4d d1, d2; |
| 549 | if (scale_on_x) { |
| 550 | d1 = depth_x.array() * sol(2) + sol(3); |
| 551 | d2 = depth_y.array() + sol(1); |
| 552 | } else { |
| 553 | d1 = depth_x.array() + sol(1); |
| 554 | d2 = depth_y.array() * sol(2) + sol(3); |
| 555 | } |
| 556 | if (d1.minCoeff() <= 0 || d2.minCoeff() <= 0) |
| 557 | continue; |
| 558 | |
| 559 | double focal = sol(4); |
| 560 | Eigen::Matrix3x4d xu = x_homo; |
| 561 | Eigen::Matrix3x4d yu = y_homo; |
| 562 | xu.block<2, 4>(0, 0) /= focal; |
| 563 | yu.block<2, 4>(0, 0) /= focal; |
| 564 | |
| 565 | Eigen::Matrix3x4d X = xu.array().rowwise() * d1.transpose().array(); |
| 566 | Eigen::Matrix3x4d Y = yu.array().rowwise() * d2.transpose().array(); |
| 567 | |
| 568 | Eigen::Vector3d centroid_X = X.rowwise().mean(); |
| 569 | Eigen::Vector3d centroid_Y = Y.rowwise().mean(); |
| 570 | |
| 571 | Eigen::MatrixXd X_centered = X.colwise() - centroid_X; |
| 572 | Eigen::MatrixXd Y_centered = Y.colwise() - centroid_Y; |
| 573 | |
| 574 | Eigen::Matrix3d S = Y_centered * X_centered.transpose(); |
| 575 | |
| 576 | Eigen::JacobiSVD<Eigen::MatrixXd> svd(S, Eigen::ComputeFullU | Eigen::ComputeFullV); |
| 577 | Eigen::Matrix3d U = svd.matrixU(); |
| 578 | Eigen::Matrix3d V = svd.matrixV(); |
| 579 | |
| 580 | if (U.determinant() * V.determinant() < 0) { |
| 581 | U.col(2) *= -1; |
| 582 | } |
| 583 | Eigen::Matrix3d R = U * V.transpose(); |
| 584 | Eigen::Vector3d t = centroid_Y - R * centroid_X; |
| 585 | |
| 586 | double b2 = sol(1), a1 = sol(2), b1 = sol(3), f = sol(4); |
| 587 | if (!scale_on_x) |
| 588 | std::swap(b1, b2); |
| 589 | output->push_back(PoseScaleOffsetSharedFocal(R, t, a1, b1, b2, f)); |
| 590 | sol_count++; |
| 591 | } |
| 592 | return sol_count; |
| 593 | } |
no test coverage detected