From 087f62eeb0d3ac16f53195d9520dadce293f856b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Sol=C3=A0?= <jsola@iri.upc.edu> Date: Fri, 18 Jan 2019 22:53:43 +0100 Subject: [PATCH] Rationalize the usage of the intrinsic params with matrix K --- .../processor_tracker_landmark_apriltag.cpp | 51 +++++++++---------- .../processor_tracker_landmark_apriltag.h | 12 +++-- ...st_processor_tracker_landmark_apriltag.cpp | 3 +- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/processors/processor_tracker_landmark_apriltag.cpp b/src/processors/processor_tracker_landmark_apriltag.cpp index 83289659a..6cc3fd332 100644 --- a/src/processors/processor_tracker_landmark_apriltag.cpp +++ b/src/processors/processor_tracker_landmark_apriltag.cpp @@ -37,6 +37,7 @@ ProcessorTrackerLandmarkApriltag::ProcessorTrackerLandmarkApriltag( ProcessorPar std_z_ (_params_tracker_landmark_apriltag->std_z_ ), std_rpy_(_params_tracker_landmark_apriltag->std_rpy_), std_pix_(_params_tracker_landmark_apriltag->std_pix_), + cv_K_(3,3), min_time_vote_(_params_tracker_landmark_apriltag->min_time_vote), min_features_for_keyframe_(_params_tracker_landmark_apriltag->min_features_for_keyframe) { @@ -125,7 +126,6 @@ void ProcessorTrackerLandmarkApriltag::preProcess() // run Apriltag detector zarray_t *detections = apriltag_detector_detect(&detector_, &im); - std::vector<Scalar> k_vec = {cx_, cy_, fx_, fy_}; // loop all detections for (int i = 0; i < zarray_size(detections); i++) { @@ -142,10 +142,10 @@ void ProcessorTrackerLandmarkApriltag::preProcess() // IPPE (Infinitesimal Plane-based Pose Estimation) ////////////////// // - Eigen::Affine3ds M_ippe2; + Eigen::Affine3ds M_ippe1, M_ippe2, M_april, M_PnP; Scalar rep_error1; Scalar rep_error2; - ippe_pose_estimation(det, k_vec, tag_width, c_M_t, rep_error1, M_ippe2, rep_error2); + ippe_pose_estimation(det, cv_K_, tag_width, M_ippe1, rep_error1, M_ippe2, rep_error2); // If not so sure about whether we have the right solution or not, do not create a feature // TODO: use parameters @@ -157,7 +157,7 @@ void ProcessorTrackerLandmarkApriltag::preProcess() // Slower than UMICH (iterative algorithm LM) but yield more precise results // Does not solve the ambiguity on the rotation however ////////////////// -// c_M_t = opencv_pose_estimation(det, k_vec, tag_width); + M_PnP = opencv_pose_estimation(det, cv_K_, tag_width); ////////////////// ////////////////// @@ -165,7 +165,7 @@ void ProcessorTrackerLandmarkApriltag::preProcess() // Implementation found in the original Apriltag c implementation. // Analytical formula but high reprojection error for large angles ////////////////// -// c_M_t = umich_pose_estimation(det, k_vec, tag_width); + // M_april = umich_pose_estimation(det, cv_K_, tag_width); ////////////////// // set the measured pose vector @@ -175,7 +175,7 @@ void ProcessorTrackerLandmarkApriltag::preProcess() // compute the covariance Eigen::Matrix6s cov = getVarVec().asDiagonal() ; // fixed dummy covariance -// Eigen::Matrix6s info = computeInformation(translation, c_M_t.linear(), k_vec, tag_width, std_pix_); // Lie jacobians covariance +// Eigen::Matrix6s info = computeInformation(translation, c_M_t.linear(), K_, tag_width, std_pix_); // Lie jacobians covariance if (is_ambiguous){ WOLF_INFO("Ambiguity on estimated rotation is likely"); @@ -192,7 +192,7 @@ void ProcessorTrackerLandmarkApriltag::preProcess() // To compare with apriltag implementation // Returned translation is in tag units: needs to be multiplied by tag_width/2 -Eigen::Affine3ds ProcessorTrackerLandmarkApriltag::opencv_pose_estimation(apriltag_detection_t *det, std::vector<double> kvec, double tag_width){ +Eigen::Affine3ds ProcessorTrackerLandmarkApriltag::opencv_pose_estimation(apriltag_detection_t *det, cv::Mat_<Scalar> K, double tag_width){ // get corners from det std::vector<cv::Point2d> corners_pix(4); for (int i = 0; i < 4; i++) @@ -214,9 +214,6 @@ Eigen::Affine3ds ProcessorTrackerLandmarkApriltag::opencv_pose_estimation(aprilt // Solve for pose // The estimated r and t brings points from tag frame to camera frame cv::Mat rvec, tvec; - cv::Mat K = (cv::Mat_<Scalar>(3,3) << kvec[2], 0, kvec[0], - 0, kvec[3], kvec[1], - 0, 0, 1); cv::Mat dist_coeffs = cv::Mat::zeros(4,1,cv::DataType<Scalar>::type); // Assuming corrected images cv::solvePnP(obj_pts, corners_pix, K, dist_coeffs, rvec, tvec); @@ -233,13 +230,13 @@ Eigen::Affine3ds ProcessorTrackerLandmarkApriltag::opencv_pose_estimation(aprilt return M; } -Eigen::Affine3d ProcessorTrackerLandmarkApriltag::umich_pose_estimation(apriltag_detection_t *det, std::vector<double> kvec, double tag_width){ +Eigen::Affine3d ProcessorTrackerLandmarkApriltag::umich_pose_estimation(apriltag_detection_t *det, cv::Mat_<Scalar> K, double tag_width){ // To put in the usual camera frame with Z looking in front (RDF) Eigen::Affine3d c_M_ac; c_M_ac.matrix() = (Eigen::Vector4d() << 1, -1, -1, 1).finished().asDiagonal(); Eigen::Affine3d M_april_raw; - matd_t *pose_matrix = homography_to_pose(det->H, -kvec[2], kvec[3], kvec[0], kvec[1]); // !! fx Negative sign advised by apriltag library commentary + matd_t *pose_matrix = homography_to_pose(det->H, -K(0,0), K(1,1), K(0,2), K(1,2)); // !! fx Negative sign advised by apriltag library commentary // write it in Eigen form Eigen::Affine3d ac_M_t; for(int r=0; r<4; r++) @@ -254,16 +251,13 @@ Eigen::Affine3d ProcessorTrackerLandmarkApriltag::umich_pose_estimation(apriltag return c_M_t; } -void ProcessorTrackerLandmarkApriltag::ippe_pose_estimation(apriltag_detection_t *det, std::vector<double> kvec, double tag_width, +void ProcessorTrackerLandmarkApriltag::ippe_pose_estimation(apriltag_detection_t *det, cv::Mat_<Scalar> K, double tag_width, Eigen::Affine3d &M1, double &rep_error1, Eigen::Affine3d &M2, double &rep_error2){ // camera coefficients - cv::Mat K = (cv::Mat_<Scalar>(3,3) << kvec[2], 0, kvec[0], - 0, kvec[3], kvec[1], - 0, 0, 1); cv::Mat dist_coeffs = cv::Mat::zeros(4,1,cv::DataType<Scalar>::type); // Assuming corrected images // get corners from det @@ -463,14 +457,8 @@ Eigen::Vector6s ProcessorTrackerLandmarkApriltag::getVarVec() return var_vec; } -Eigen::Matrix6s ProcessorTrackerLandmarkApriltag::computeInformation(Eigen::Vector3s const &t, Eigen::Matrix3s const &R, std::vector<Scalar> const &k_vec, Scalar const &tag_width, double const &sig_q) +Eigen::Matrix6s ProcessorTrackerLandmarkApriltag::computeInformation(Eigen::Vector3s const &t, Eigen::Matrix3s const &R, Eigen::Matrix3s const &K, Scalar const &tag_width, double const &sig_q) { - // Create cam intrisic matrix - Eigen::Matrix3s K; - K << k_vec[2], 0, k_vec[0], - 0, k_vec[3], k_vec[1], - 0, 0, 1; - // Same order as the 2D corners (anti clockwise, looking at the tag). // Looking at the tag, the reference frame is // X = Right, Y = Down, Z = Inside the plane @@ -537,11 +525,18 @@ FeatureBaseList ProcessorTrackerLandmarkApriltag::getLastDetections() const void ProcessorTrackerLandmarkApriltag::configure(SensorBasePtr _sensor) { // get camera intrinsic parameters - Eigen::Vector4s camera_intrinsics(_sensor->getIntrinsicPtr()->getState()); //[cx cy fx fy] - cx_ = camera_intrinsics(0); - cy_ = camera_intrinsics(1); - fx_ = camera_intrinsics(2); - fy_ = camera_intrinsics(3); + Eigen::Vector4s k(_sensor->getIntrinsicPtr()->getState()); //[cx cy fx fy] + + // Intrinsic matrices for opencv and eigen: + + cv_K_ << k(2), 0, k(0), + 0, k(3), k(1), + 0, 0, 1; + + K_ << k(2), 0, k(0), + 0, k(3), k(1), + 0, 0, 1; + } void ProcessorTrackerLandmarkApriltag::advanceDerived() diff --git a/src/processors/processor_tracker_landmark_apriltag.h b/src/processors/processor_tracker_landmark_apriltag.h index 71269b9c0..a8ea31bcf 100644 --- a/src/processors/processor_tracker_landmark_apriltag.h +++ b/src/processors/processor_tracker_landmark_apriltag.h @@ -115,14 +115,14 @@ class ProcessorTrackerLandmarkApriltag : public ProcessorTrackerLandmark Eigen::Vector6s getVarVec(); FeatureBaseList getIncomingDetections() const; FeatureBaseList getLastDetections() const; - Eigen::Affine3d opencv_pose_estimation(apriltag_detection_t *det, std::vector<double> kvec, double tag_width); - Eigen::Affine3d umich_pose_estimation(apriltag_detection_t *det, std::vector<double> kvec, double tag_width); - void ippe_pose_estimation(apriltag_detection_t *det, std::vector<double> kvec, double tag_width, + Eigen::Affine3d opencv_pose_estimation(apriltag_detection_t *det, cv::Mat_<Scalar>, double tag_width); + Eigen::Affine3d umich_pose_estimation(apriltag_detection_t *det, cv::Mat_<Scalar>, double tag_width); + void ippe_pose_estimation(apriltag_detection_t *det, cv::Mat_<Scalar>, double tag_width, Eigen::Affine3d &M1, double &rep_error1, Eigen::Affine3d &M2, double &rep_error2); - Eigen::Matrix6s computeInformation(Eigen::Vector3s const &t, Eigen::Matrix3s const &R, std::vector<double> const &k_vec, double const &tag_width, double const &sig_q); + Eigen::Matrix6s computeInformation(Eigen::Vector3s const &t, Eigen::Matrix3s const &R, Eigen::Matrix3s const &K, double const &tag_width, double const &sig_q); void pinholeHomogeneous(Eigen::Matrix3s const & K, Eigen::Vector3s const & t, Eigen::Matrix3s const & R, Eigen::Vector3s const & p, Eigen::Vector3s &h, Eigen::Matrix3s &J_h_T, Eigen::Matrix3s &J_h_R); @@ -143,7 +143,9 @@ class ProcessorTrackerLandmarkApriltag : public ProcessorTrackerLandmark Scalar std_xy_, std_z_, std_rpy_; ///< dummy std values for covariance computation Scalar std_pix_; ///< pixel error to be propagated to a camera to tag transformation covariance // Eigen::Affine3ds c_M_ac_; ///< aprilCamera-to-camera transform not used with solvePnP - double cx_, cy_, fx_, fy_; +// double cx_, cy_, fx_, fy_; + Matrix3s K_; + cv::Mat_<Scalar> cv_K_; protected: FeatureBaseList detections_incoming_; ///< detected tags in wolf form, incoming image diff --git a/src/test/gtest_processor_tracker_landmark_apriltag.cpp b/src/test/gtest_processor_tracker_landmark_apriltag.cpp index ee5280782..90c2943e4 100644 --- a/src/test/gtest_processor_tracker_landmark_apriltag.cpp +++ b/src/test/gtest_processor_tracker_landmark_apriltag.cpp @@ -372,8 +372,7 @@ TEST_F(ProcessorTrackerLandmarkApriltag_class, computeInformation) ASSERT_MATRIX_APPROX(J_h_R2, J_h_R2_matlab, 1e-3); Scalar sig_q = 2; - std::vector<Scalar> k_vec = {cx, cy, fx, fy}; - Eigen::Matrix6s transformation_info = prc_apr->computeInformation(t, v2R(v), k_vec, tag_width, sig_q); + Eigen::Matrix6s transformation_info = prc_apr->computeInformation(t, v2R(v), K, tag_width, sig_q); // From Matlab // Eigen::Matrix6s transformation_cov_matlab; -- GitLab