| 453 | } |
| 454 | |
| 455 | bool Initializer::ComputeEssentialMatrix( |
| 456 | const std::vector<Eigen::Vector3f>& bearings1, |
| 457 | const std::vector<Eigen::Vector3f>& bearings2, |
| 458 | Eigen::Matrix3f& E, |
| 459 | std::vector<bool>& inlier_mask |
| 460 | ) const { |
| 461 | if (bearings1.size() != bearings2.size() || bearings1.size() < 5) { |
| 462 | return false; |
| 463 | } |
| 464 | |
| 465 | const size_t num_points = bearings1.size(); |
| 466 | inlier_mask.resize(num_points, false); |
| 467 | |
| 468 | // RANSAC parameters |
| 469 | const int min_samples = 8; // Use 8-point algorithm (more stable than 5-point) |
| 470 | int best_inliers = 0; |
| 471 | Eigen::Matrix3f best_E = Eigen::Matrix3f::Identity(); |
| 472 | std::vector<bool> best_mask(num_points, false); |
| 473 | |
| 474 | // Random number generator |
| 475 | std::random_device rd; |
| 476 | std::mt19937 gen(rd()); |
| 477 | std::uniform_int_distribution<> dis(0, num_points - 1); |
| 478 | |
| 479 | // RANSAC loop |
| 480 | for (int iter = 0; iter < m_ransac_iterations; ++iter) { |
| 481 | // 1. Randomly sample 5 points |
| 482 | std::vector<int> sample_indices; |
| 483 | sample_indices.reserve(min_samples); |
| 484 | |
| 485 | while (sample_indices.size() < static_cast<size_t>(min_samples)) { |
| 486 | int idx = dis(gen); |
| 487 | // Check for duplicate |
| 488 | if (std::find(sample_indices.begin(), sample_indices.end(), idx) == sample_indices.end()) { |
| 489 | sample_indices.push_back(idx); |
| 490 | } |
| 491 | } |
| 492 | |
| 493 | // 2. Compute Essential matrix from 8 points using 8-point algorithm |
| 494 | std::vector<Eigen::Vector3f> sample_bearings1, sample_bearings2; |
| 495 | for (int idx : sample_indices) { |
| 496 | sample_bearings1.push_back(bearings1[idx]); |
| 497 | sample_bearings2.push_back(bearings2[idx]); |
| 498 | } |
| 499 | |
| 500 | // 8-point algorithm |
| 501 | Eigen::MatrixXf A(min_samples, 9); // Use 8 samples |
| 502 | for (size_t i = 0; i < sample_bearings1.size(); ++i) { |
| 503 | const auto& b1 = sample_bearings1[i]; |
| 504 | const auto& b2 = sample_bearings2[i]; |
| 505 | |
| 506 | // Essential matrix constraint: b2^T * E * b1 = 0 |
| 507 | A(i, 0) = b2.x() * b1.x(); |
| 508 | A(i, 1) = b2.x() * b1.y(); |
| 509 | A(i, 2) = b2.x() * b1.z(); |
| 510 | A(i, 3) = b2.y() * b1.x(); |
| 511 | A(i, 4) = b2.y() * b1.y(); |
| 512 | A(i, 5) = b2.y() * b1.z(); |
nothing calls this directly
no outgoing calls
no test coverage detected