From 9fba952b51e79c537c63219fd7897930708cc638 Mon Sep 17 00:00:00 2001 From: ydepledt <yanndepledt360@gmail.com> Date: Wed, 15 Jun 2022 18:05:59 +0200 Subject: [PATCH] Add test for matching functions --- .../processor_tracker_landmark_object.h | 5 +- .../processor_tracker_landmark_object.cpp | 57 +++++++-- ...test_processor_tracker_landmark_object.cpp | 118 ++++++++++++++++++ 3 files changed, 168 insertions(+), 12 deletions(-) diff --git a/include/objectslam/processor/processor_tracker_landmark_object.h b/include/objectslam/processor/processor_tracker_landmark_object.h index fff207e..c03add8 100644 --- a/include/objectslam/processor/processor_tracker_landmark_object.h +++ b/include/objectslam/processor/processor_tracker_landmark_object.h @@ -144,9 +144,9 @@ class ProcessorTrackerLandmarkObject : public ProcessorTrackerLandmark FeatureBasePtrList& _features_out_last, FeatureBasePtrList& _features_out_incoming); - std::vector<int> matchingRANSAC(std::vector<std::tuple<int, int, Eigen::Isometry3d, Eigen::Isometry3d> > last_incoming); + static std::pair<std::vector<int>, Eigen::Isometry3d> matchingRANSAC(std::vector<std::tuple<int, int, Eigen::Isometry3d, Eigen::Isometry3d> > last_incoming); - bool isInliers(Eigen::Isometry3d cl_M_ol, Eigen::Isometry3d ci_M_oi, Eigen::Isometry3d cl_M_ci); + static bool isInliers(Eigen::Isometry3d cl_M_ol, Eigen::Isometry3d ci_M_oi, Eigen::Isometry3d cl_M_ci); /** \brief Vote for KeyFrame generation @@ -220,4 +220,5 @@ class ProcessorTrackerLandmarkObject : public ProcessorTrackerLandmark } // namespace wolf + #endif /* _PROCESSOR_TRACKER_LANDMARK_OBJECT_H_ */ diff --git a/src/processor/processor_tracker_landmark_object.cpp b/src/processor/processor_tracker_landmark_object.cpp index 93b2411..043357c 100644 --- a/src/processor/processor_tracker_landmark_object.cpp +++ b/src/processor/processor_tracker_landmark_object.cpp @@ -1,3 +1,6 @@ +#include <iostream> +#include <ostream> + #include "core/math/rotations.h" #include <core/factor/factor_distance_3d.h> #include "core/factor/factor_relative_pose_3d_with_extrinsics.h" @@ -439,9 +442,10 @@ unsigned int ProcessorTrackerLandmarkObject::multiviewTypeMatching(const Capture int index_min_incoming = -1; double min_e_pos = 100; + int index_incoming = 0; + for (auto feat_incoming : detections_incoming_) { - int index_incoming = 0; std::string object_type_incoming = std::static_pointer_cast<FeatureObject>(feat_incoming)->getObjectType(); @@ -467,20 +471,23 @@ unsigned int ProcessorTrackerLandmarkObject::multiviewTypeMatching(const Capture last_incoming.push_back(tuple_last_incom); } + index_incoming++; } std::cout << index_min_incoming; + index_last++; } return 1; } -std::vector<int> ProcessorTrackerLandmarkObject::matchingRANSAC(std::vector<std::tuple<int, int, Eigen::Isometry3d, Eigen::Isometry3d> > last_incoming) +std::pair<std::vector<int>, Eigen::Isometry3d> ProcessorTrackerLandmarkObject::matchingRANSAC(std::vector<std::tuple<int, int, Eigen::Isometry3d, Eigen::Isometry3d> > last_incoming) { // Vector that will contains index of outliers for each iteration std::vector<std::vector<int> > index_outliers; int i = 0; int best_score = 0; + Eigen::Isometry3d best_cl_M_ci = Eigen::Isometry3d::Identity();; int index_best_score = -1; @@ -506,13 +513,12 @@ std::vector<int> ProcessorTrackerLandmarkObject::matchingRANSAC(std::vector<std: int index_feat_last = std::get<0>(last_incoming_tuple); int index_feat_last_other = std::get<0>(last_incoming_tuple_other); - //Check if there is a match and if if (index_feat_incoming != -1 && index_feat_last != index_feat_last_other) { Eigen::Isometry3d cl_M_ol = std::get<2>(last_incoming_tuple_other); Eigen::Isometry3d ci_M_oi = std::get<3>(last_incoming_tuple_other); - if(isInliers(cl_M_ol, cl_M_ci, ci_M_oi)) + if(isInliers(cl_M_ol, ci_M_oi, cl_M_ci)) { score++; } @@ -527,6 +533,7 @@ std::vector<int> ProcessorTrackerLandmarkObject::matchingRANSAC(std::vector<std: { best_score = score; index_best_score = i; + best_cl_M_ci = cl_M_ci; } } @@ -537,16 +544,33 @@ std::vector<int> ProcessorTrackerLandmarkObject::matchingRANSAC(std::vector<std: } if (index_best_score != -1) - return index_outliers[index_best_score]; + { + std::pair<std::vector<int>, Eigen::Isometry3d> p{index_outliers[index_best_score], best_cl_M_ci}; + return p; + } - return index_outliers[0]; + + std::vector<int> v; + std::pair<std::vector<int>, Eigen::Isometry3d> p{v, best_cl_M_ci}; + + return p; } -bool ProcessorTrackerLandmarkObject::isInliers(Eigen::Isometry3d cl_M_ol, Eigen::Isometry3d ci_M_oi, Eigen::Isometry3d cl_M_ci) +std::ostream &operator<<(std::ostream &flux, Quaterniond quat) { - double e_pos_th = 0.5; - double e_rot_th = 0.5; + flux << quat.x() << " "; + flux << quat.y() << " "; + flux << quat.z() << " "; + flux << quat.w() << " "; + return flux; +} + +bool ProcessorTrackerLandmarkObject::isInliers(Eigen::Isometry3d cl_M_ol, Eigen::Isometry3d ci_M_oi, Eigen::Isometry3d cl_M_ci) +{ + //Thresholds + double e_pos_th = 1; + double e_rot_th = 1; Eigen::Isometry3d ol_M_cl = cl_M_ol.inverse(); Eigen::Isometry3d ol_M_oi = ol_M_cl * cl_M_ci * ci_M_oi; @@ -562,8 +586,10 @@ bool ProcessorTrackerLandmarkObject::isInliers(Eigen::Isometry3d cl_M_ol, Eigen: quat_feat_identity.coeffs() = R2q(wRf_i).coeffs().transpose(); Vector3d pos_feat_identity = identity.translation(); + std::cout << "\n\n\n\n\n" << quat_feat << " " << quat_feat_identity << std::endl; + std::cout << pos_feat << "\n" << pos_feat_identity << "\n\n\n\n\n" << std::endl; - // Error computation + // Error between identity and ol_M_oi double e_pos = (pos_feat_identity - pos_feat).norm(); double e_rot = log_q(quat_feat_identity.conjugate() * quat_feat).norm(); @@ -595,6 +621,17 @@ void ProcessorTrackerLandmarkObject::resetDerived() detections_last_ = std::move(detections_incoming_); } +// ostream& operator<<(ostream &flux, Quaterniond quat) +// { +// for (int i = 0; i < quat.size(); i++) +// { +// flux << quat[i]; +// flux << " "; +// } + +// return flux; +// } + } // namespace wolf diff --git a/test/gtest_processor_tracker_landmark_object.cpp b/test/gtest_processor_tracker_landmark_object.cpp index 80727dc..0da8745 100644 --- a/test/gtest_processor_tracker_landmark_object.cpp +++ b/test/gtest_processor_tracker_landmark_object.cpp @@ -10,6 +10,7 @@ #include "objectslam/feature/feature_object.h" #include "objectslam/landmark/landmark_object.h" #include "objectslam/internal/config.h" +#include "objectslam/capture/capture_object.h" using namespace Eigen; using namespace wolf; @@ -311,6 +312,123 @@ TEST_F(ProcessorTrackerLandmarkObject_class, emplaceFactor) ASSERT_TRUE(ctr->getType() == "FactorRelativePose3dWithExtrinsics"); } +TEST_F(ProcessorTrackerLandmarkObject_class, matchingRANSAC) +{ + std::vector<std::tuple<int, int, Eigen::Isometry3d, Eigen::Isometry3d> > last_incoming; + + Vector7d pose_cam_last; + Vector7d pose_cam_incoming; + Vector7d pose_object_1; + Vector7d pose_object_2; + Vector7d pose_object_3; + + pose_cam_last << 4.1,3.5,0, 0.8,2.7,1.3,1; + pose_cam_incoming << 5.2,4.8,0.5,0.4, 2.0,2.1,1.2; + pose_object_1 << 3.2,2.1,4.3,5.5, 3.3,2.4,1; + pose_object_2 << 2.2,1.1,3.3,4.5, 2.3,1.4,0.8; + pose_object_3 << 1.2,0.1,3.7,4.5, 2.4,1.4,0.5; + + pose_cam_last.tail<4>() = pose_cam_last.tail<4>().normalized(); + pose_cam_incoming.tail<4>() = pose_cam_incoming.tail<4>().normalized(); + pose_object_1.tail<4>() = pose_object_1.tail<4>().normalized(); + pose_object_2.tail<4>() = pose_object_2.tail<4>().normalized(); + pose_object_3.tail<4>() = pose_object_2.tail<4>().normalized(); + + + Eigen::Isometry3d w_M_cl = posevec_to_isometry(pose_cam_last); + Eigen::Isometry3d w_M_ci = posevec_to_isometry(pose_cam_incoming); + + Eigen::Isometry3d w_M_o1 = posevec_to_isometry(pose_object_1); + Eigen::Isometry3d w_M_o2 = posevec_to_isometry(pose_object_2); + Eigen::Isometry3d w_M_o3 = posevec_to_isometry(pose_object_3); + + + Eigen::Isometry3d cl_M_o1 = w_M_cl.inverse() * w_M_o1; + Eigen::Isometry3d cl_M_o2 = w_M_cl.inverse() * w_M_o2; + Eigen::Isometry3d cl_M_o3 = w_M_o3; + + Eigen::Isometry3d ci_M_o1 = w_M_ci.inverse() * w_M_o1; + Eigen::Isometry3d ci_M_o2 = w_M_ci.inverse() * w_M_o2; + Eigen::Isometry3d ci_M_o3 = w_M_o3; + + Eigen::Isometry3d cl_M_ci = w_M_cl.inverse() * w_M_ci; + + auto tuple_o1 = std::make_tuple(0, 0, cl_M_o1, ci_M_o1); + auto tuple_o2 = std::make_tuple(1, 1, cl_M_o2, ci_M_o2); + auto tuple_o3 = std::make_tuple(2, 2, cl_M_o3, ci_M_o3); + + last_incoming.push_back(tuple_o1); + last_incoming.push_back(tuple_o2); + last_incoming.push_back(tuple_o3); + + auto outliers = ProcessorTrackerLandmarkObject::matchingRANSAC(last_incoming); + + Quaterniond quat_cam; + Eigen::Matrix3d wRf = cl_M_ci.linear(); + quat_cam.coeffs() = R2q(wRf).coeffs().transpose(); + Vector3d pos_cam = cl_M_ci.translation(); + + Quaterniond quat_cam_RANSAC; + Eigen::Matrix3d wRf_R = outliers.second.linear(); + quat_cam_RANSAC.coeffs() = R2q(wRf_R).coeffs().transpose(); + Vector3d pos_cam_RANSAC = outliers.second.translation(); + + std::cout << "\n\n\n\n\n" << outliers.first.size() << "\n\n\n\n"; + + std::cout << "\n\n\n\n\n\n\n\n" << pos_cam << "\n" << pos_cam_RANSAC << "\n\n"; + + for (int i = 0; i < pos_cam.size(); i++) + { + ASSERT_TRUE(abs(pos_cam[i] - pos_cam_RANSAC[i]) < 0.001); + } + + ASSERT_TRUE(outliers.first.size() == 1); + ASSERT_TRUE(outliers.first[0] == 2); +} + +TEST(ProcessorTrackerLandmarkObject, isInliers) +{ + Vector7d pose_cam_last; + Vector7d pose_cam_incoming; + Vector7d pose_object_1; + Vector7d pose_object_2; + + pose_cam_last << 4.1,3.5,0, 0.8,2.7,1.3,1; + pose_cam_incoming << 5.2,4.8,0.5,0.4, 2.0,2.1,1.2; + pose_object_1 << 3.2,2.1,4.3,5.5, 3.3,2.4,1; + pose_object_2 << 2.2,1.1,3.3,4.5, 2.3,1.4,0.8; + + pose_cam_last.tail<4>() = pose_cam_last.tail<4>().normalized(); + pose_cam_incoming.tail<4>() = pose_cam_incoming.tail<4>().normalized(); + pose_object_1.tail<4>() = pose_object_1.tail<4>().normalized(); + pose_object_2.tail<4>() = pose_object_2.tail<4>().normalized(); + + Eigen::Isometry3d w_M_cl = posevec_to_isometry(pose_cam_last); + Eigen::Isometry3d w_M_ci = posevec_to_isometry(pose_cam_incoming); + + Eigen::Isometry3d w_M_o1 = posevec_to_isometry(pose_object_1); + Eigen::Isometry3d w_M_o2 = posevec_to_isometry(pose_object_2); + Eigen::Isometry3d w_M_o3 = Eigen::Isometry3d::Identity(); + + + Eigen::Isometry3d cl_M_ci = w_M_cl.inverse() * w_M_ci; + + + Eigen::Isometry3d cl_M_o1 = w_M_cl.inverse() * w_M_o1; + Eigen::Isometry3d cl_M_o2 = w_M_cl.inverse() * w_M_o2; + Eigen::Isometry3d cl_M_o3 = w_M_cl.inverse() * w_M_o3; + Eigen::Isometry3d ci_M_o1 = w_M_ci.inverse() * w_M_o1; + Eigen::Isometry3d ci_M_o2 = w_M_ci.inverse() * w_M_o2; + Eigen::Isometry3d ci_M_o3 = w_M_ci.inverse() * w_M_o3; + + ASSERT_TRUE(ProcessorTrackerLandmarkObject::isInliers(cl_M_o1, ci_M_o1, cl_M_ci)); + ASSERT_TRUE(ProcessorTrackerLandmarkObject::isInliers(cl_M_o2, ci_M_o2, cl_M_ci)); + ASSERT_TRUE(ProcessorTrackerLandmarkObject::isInliers(cl_M_o3, ci_M_o3, cl_M_ci)); + ASSERT_TRUE(!(ProcessorTrackerLandmarkObject::isInliers(cl_M_o1, ci_M_o2, cl_M_ci))); + ASSERT_TRUE(!(ProcessorTrackerLandmarkObject::isInliers(cl_M_o2, ci_M_o1, cl_M_ci))); +} + + int main(int argc, char **argv) { -- GitLab