| 723 | } |
| 724 | |
| 725 | bool Initializer::TriangulateSinglePoint( |
| 726 | const Eigen::Vector3f& bearing1, |
| 727 | const Eigen::Vector3f& bearing2, |
| 728 | const Eigen::Matrix3f& R, |
| 729 | const Eigen::Vector3f& t, |
| 730 | Eigen::Vector3f& point3d |
| 731 | ) const { |
| 732 | // R: rotation from frame1 to frame2 (rot_ref_to_cur) |
| 733 | // t: translation from frame1 to frame2 (trans_ref_to_cur) |
| 734 | |
| 735 | // Transform translation to go from frame2 to frame1 |
| 736 | const Eigen::Vector3f trans_12 = -R.transpose() * t; |
| 737 | // Transform bearing2 to frame1 coordinates |
| 738 | const Eigen::Vector3f bearing2_in_frame1 = R.transpose() * bearing2; |
| 739 | |
| 740 | |
| 741 | |
| 742 | // Build the linear system: A * lambda = b |
| 743 | // Ray1: p1 = λ1 * bearing1 |
| 744 | // Ray2: p2 = λ2 * bearing2_in_frame1 + trans_12 |
| 745 | |
| 746 | Eigen::Matrix2f A; |
| 747 | A(0, 0) = bearing1.dot(bearing1); |
| 748 | A(1, 0) = bearing1.dot(bearing2_in_frame1); |
| 749 | A(0, 1) = -A(1, 0); |
| 750 | A(1, 1) = -bearing2_in_frame1.dot(bearing2_in_frame1); |
| 751 | |
| 752 | Eigen::Vector2f b; |
| 753 | b(0) = bearing1.dot(trans_12); |
| 754 | b(1) = bearing2_in_frame1.dot(trans_12); |
| 755 | |
| 756 | // Check for degenerate matrix |
| 757 | float det = A(0,0) * A(1,1) - A(0,1) * A(1,0); |
| 758 | if (std::abs(det) < 1e-10f) { |
| 759 | return false; |
| 760 | } |
| 761 | |
| 762 | // Solve for lambda |
| 763 | const Eigen::Vector2f lambda = A.inverse() * b; |
| 764 | |
| 765 | // For equirectangular cameras, skip depth positive check |
| 766 | // (depth_is_positive = false for bearing_vector initializer) |
| 767 | // Only check for finite values |
| 768 | if (!std::isfinite(lambda(0)) || !std::isfinite(lambda(1))) { |
| 769 | return false; |
| 770 | } |
| 771 | |
| 772 | // Compute 3D points on both rays |
| 773 | const Eigen::Vector3f pt_1 = lambda(0) * bearing1; |
| 774 | const Eigen::Vector3f pt_2 = lambda(1) * bearing2_in_frame1 + trans_12; |
| 775 | |
| 776 | // Return the mid-point (in frame1 coordinates) |
| 777 | point3d = (pt_1 + pt_2) / 2.0f; |
| 778 | |
| 779 | return true; |
| 780 | } |
| 781 | |
| 782 | int Initializer::TestPoseCandidate( |