12 #include <mrpt/config.h> 18 #include <mrpt/config.h> 20 #if MRPT_HAS_OPENCV && MRPT_OPENCV_VERSION_NUM < 0x240 21 #undef MRPT_HAS_OPENCV 22 #define MRPT_HAS_OPENCV 0 29 #include <Eigen/Dense> 31 #include <mrpt/otherlibs/do_opencv_includes.h> 33 #include <opencv2/core/eigen.hpp> 46 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
47 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
48 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
49 Eigen::Ref<Eigen::MatrixXd> pose_mat)
53 #if MRPT_HAS_OPENCV == 1 56 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
59 if (img_pts.rows() != obj_pts.rows() ||
60 img_pts.cols() != obj_pts.cols())
62 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
65 if (obj_pts.rows() < obj_pts.cols())
67 cam_in_eig = cam_intrinsic.transpose();
68 img_pts_eig = img_pts.transpose().block(0, 0,
n, 2);
69 obj_pts_eig = obj_pts.transpose();
73 cam_in_eig = cam_intrinsic;
74 img_pts_eig = img_pts.block(0, 0,
n, 2);
75 obj_pts_eig = obj_pts;
79 Eigen::Matrix3d R_eig;
80 Eigen::MatrixXd t_eig;
83 cv::Mat cam_in_cv(3, 3, CV_32F), img_pts_cv(2,
n, CV_32F),
84 obj_pts_cv(3,
n, CV_32F), R_cv(3, 3, CV_32F), t_cv(3, 1, CV_32F);
86 cv::eigen2cv(cam_in_eig, cam_in_cv);
87 cv::eigen2cv(img_pts_eig, img_pts_cv);
88 cv::eigen2cv(obj_pts_eig, obj_pts_cv);
93 cv::cv2eigen(R_cv, R_eig);
94 cv::cv2eigen(t_cv, t_eig);
96 Eigen::Quaterniond
q(R_eig);
98 pose_mat << t_eig,
q.vec();
111 std::cout <<
"Please install OpenCV for DLS-PnP" << std::endl;
114 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 115 "of obj_pts and img_pts" 120 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 129 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
130 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
131 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
132 Eigen::Ref<Eigen::MatrixXd> pose_mat)
136 #if MRPT_HAS_OPENCV == 1 139 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
142 if (img_pts.rows() != obj_pts.rows() ||
143 img_pts.cols() != obj_pts.cols())
145 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
148 if (obj_pts.rows() < obj_pts.cols())
150 cam_in_eig = cam_intrinsic.transpose();
151 img_pts_eig = img_pts.transpose().block(0, 0,
n, 2);
152 obj_pts_eig = obj_pts.transpose();
156 cam_in_eig = cam_intrinsic;
157 img_pts_eig = img_pts.block(0, 0,
n, 2);
158 obj_pts_eig = obj_pts;
162 Eigen::Matrix3d R_eig;
163 Eigen::MatrixXd t_eig;
166 cv::Mat cam_in_cv(3, 3, CV_32F), img_pts_cv(2,
n, CV_32F),
167 obj_pts_cv(3,
n, CV_32F), R_cv, t_cv;
169 cv::eigen2cv(cam_in_eig, cam_in_cv);
170 cv::eigen2cv(img_pts_eig, img_pts_cv);
171 cv::eigen2cv(obj_pts_eig, obj_pts_cv);
176 cv::cv2eigen(R_cv, R_eig);
177 cv::cv2eigen(t_cv, t_eig);
179 Eigen::Quaterniond
q(R_eig);
181 pose_mat << t_eig,
q.vec();
194 std::cout <<
"Please install OpenCV for DLS-PnP" << std::endl;
197 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 198 "of obj_pts and img_pts" 203 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 212 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
213 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
214 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
215 Eigen::Ref<Eigen::MatrixXd> pose_mat)
219 #if MRPT_HAS_OPENCV == 1 222 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
225 if (img_pts.rows() != obj_pts.rows() ||
226 img_pts.cols() != obj_pts.cols())
228 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
231 if (obj_pts.rows() < obj_pts.cols())
233 cam_in_eig = cam_intrinsic.transpose();
234 img_pts_eig = img_pts.transpose().block(0, 0,
n, 2);
235 obj_pts_eig = obj_pts.transpose();
239 cam_in_eig = cam_intrinsic;
240 img_pts_eig = img_pts.block(0, 0,
n, 2);
241 obj_pts_eig = obj_pts;
245 Eigen::Matrix3d R_eig;
246 Eigen::MatrixXd t_eig;
249 cv::Mat cam_in_cv(3, 3, CV_32F), img_pts_cv(2,
n, CV_32F),
250 obj_pts_cv(3,
n, CV_32F), R_cv, t_cv;
252 cv::eigen2cv(cam_in_eig, cam_in_cv);
253 cv::eigen2cv(img_pts_eig, img_pts_cv);
254 cv::eigen2cv(obj_pts_eig, obj_pts_cv);
259 cv::cv2eigen(R_cv, R_eig);
260 cv::cv2eigen(t_cv, t_eig);
262 Eigen::Quaterniond
q(R_eig);
264 pose_mat << t_eig,
q.vec();
276 std::cout <<
"Please install OpenCV for DLS-PnP" << std::endl;
279 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 280 "of obj_pts and img_pts" 285 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 294 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
295 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
296 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
297 Eigen::Ref<Eigen::MatrixXd> pose_mat)
302 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
305 if (img_pts.rows() != obj_pts.rows() ||
306 img_pts.cols() != obj_pts.cols())
308 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
311 if (obj_pts.rows() < obj_pts.cols())
313 cam_in_eig = cam_intrinsic.transpose();
314 img_pts_eig = img_pts.transpose().block(0, 0,
n, 2);
315 obj_pts_eig = obj_pts.transpose();
319 cam_in_eig = cam_intrinsic;
320 img_pts_eig = img_pts.block(0, 0,
n, 2);
321 obj_pts_eig = obj_pts;
330 bool ret =
p.solve(
R,
t, obj_pts_eig, img_pts_eig);
332 Eigen::Quaterniond
q(
R);
334 pose_mat <<
t,
q.vec();
343 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 344 "of obj_pts and img_pts" 349 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 358 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
359 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
360 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
361 Eigen::Ref<Eigen::MatrixXd> pose_mat)
366 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
369 if (img_pts.rows() != obj_pts.rows() ||
370 img_pts.cols() != obj_pts.cols())
372 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
375 if (obj_pts.rows() < obj_pts.cols())
377 cam_in_eig = cam_intrinsic.transpose();
378 img_pts_eig = img_pts.transpose();
379 obj_pts_eig = obj_pts.transpose();
383 cam_in_eig = cam_intrinsic;
384 img_pts_eig = img_pts;
385 obj_pts_eig = obj_pts;
394 bool ret =
r.compute_pose(
R,
t);
396 Eigen::Quaterniond
q(
R);
398 pose_mat <<
t,
q.vec();
407 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 408 "of obj_pts and img_pts" 413 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 422 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
423 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
424 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
425 Eigen::Ref<Eigen::MatrixXd> pose_mat)
430 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
433 if (img_pts.rows() != obj_pts.rows() ||
434 img_pts.cols() != obj_pts.cols())
436 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
439 if (obj_pts.rows() < obj_pts.cols())
441 cam_in_eig = cam_intrinsic.transpose();
442 img_pts_eig = img_pts.transpose();
443 obj_pts_eig = obj_pts.transpose();
447 cam_in_eig = cam_intrinsic;
448 img_pts_eig = img_pts;
449 obj_pts_eig = obj_pts;
459 bool ret =
p.compute_pose(
R,
t,
n);
461 Eigen::Quaterniond
q(
R);
463 pose_mat <<
t,
q.vec();
472 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 473 "of obj_pts and img_pts" 478 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 487 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
488 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
489 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
490 Eigen::Ref<Eigen::MatrixXd> pose_mat)
495 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
498 if (img_pts.rows() != obj_pts.rows() ||
499 img_pts.cols() != obj_pts.cols())
501 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
504 if (obj_pts.rows() < obj_pts.cols())
506 cam_in_eig = cam_intrinsic.transpose();
507 img_pts_eig = img_pts.transpose().block(0, 0,
n, 2);
508 obj_pts_eig = obj_pts.transpose();
512 cam_in_eig = cam_intrinsic;
513 img_pts_eig = img_pts.block(0, 0,
n, 2);
514 obj_pts_eig = obj_pts;
524 bool ret =
p.compute_pose(
R,
t);
526 Eigen::Quaterniond
q(
R);
528 pose_mat <<
t,
q.vec();
537 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 538 "of obj_pts and img_pts" 543 <<
"Camera intrinsic matrix does not have 3x3 dimensions " 552 const Eigen::Ref<Eigen::MatrixXd> obj_pts,
553 const Eigen::Ref<Eigen::MatrixXd> img_pts,
int n,
554 const Eigen::Ref<Eigen::MatrixXd> cam_intrinsic,
555 Eigen::Ref<Eigen::MatrixXd> pose_mat)
560 Eigen::MatrixXd cam_in_eig, img_pts_eig, obj_pts_eig;
563 if (img_pts.rows() != obj_pts.rows() ||
564 img_pts.cols() != obj_pts.cols())
566 else if (cam_intrinsic.rows() != 3 || cam_intrinsic.cols() != 3)
569 if (obj_pts.rows() < obj_pts.cols())
571 cam_in_eig = cam_intrinsic.transpose();
572 img_pts_eig = img_pts.transpose();
573 obj_pts_eig = obj_pts.transpose();
577 cam_in_eig = cam_intrinsic;
578 img_pts_eig = img_pts;
579 obj_pts_eig = obj_pts;
591 Eigen::Quaterniond
q(
R);
593 pose_mat <<
t,
q.vec();
602 std::cout <<
"2d/3d correspondences mismatch\n Check dimension " 603 "of obj_pts and img_pts" 608 <<
"Camera intrinsic matrix does not have 3x3 dimensions " Unified PnP - Eigen Wrapper for OpenCV function.
bool compute_pose(cv::Mat &R, cv::Mat &t)
OpenCV function for computing pose.
PnP Algorithms toolkit for MRPT.
void compute_pose(cv::Mat &R, cv::Mat &t)
OpenCV wrapper to compute pose.
GLdouble GLdouble GLdouble GLdouble q
bool upnp(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Unified-PnP (UPnP) : Algorithm to compute pose from unknown camera intrinsic matrix ...
double compute_pose(cv::Mat &R, cv::Mat &t)
Function to compute pose.
Robust - PnP class definition for computing pose.
Lu Hage Mjolsness - Iterative PnP Algorithm (Eigen Implementation.
bool ppnp(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Procrustes-PnP(PPnP) Algorithm : Iterative SVD based algorithm
bool rpnp(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Robust (R-PnP)- A closed form solution with intermediate P3P computations
bool epnp(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Efficient-PnP (EPnP) - Algorithm takes 4 control points based on n points and uses the control point...
Efficient PnP - Eigen Wrapper for OpenCV calib3d implementation.
bool lhm(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Lu-Hager-Mjolsness(LHM)-PnP algorithm : Iterative algorithm to reduce object space error ...
bool compute_pose(Eigen::Ref< Eigen::Matrix3d > R_, Eigen::Ref< Eigen::Vector3d > t_)
Function to compute pose using LHM PnP algorithm.
GLdouble GLdouble GLdouble r
bool p3p(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
P3P - A closed form solution for n=3, 2D-3D correspondences
Pose from Orthogonality and Scaling (POSIT) - Eigen Implementation.
Direct Least Squares (DLS) - Eigen wrapper for OpenCV Implementation.
bool dls(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Direct Least Squares (DLS) - PnP : Algorithm formulates position as a function of rotation...
bool posit(const Eigen::Ref< Eigen::MatrixXd > obj_pts, const Eigen::Ref< Eigen::MatrixXd > img_pts, int n, const Eigen::Ref< Eigen::MatrixXd > cam_intrinsic, Eigen::Ref< Eigen::MatrixXd > pose_mat)
Pose from Orthogoanlity and Scaling :Iterative (POSIT) - A Geometric algorithm to compute scale and ...
P3P Pose estimation Algorithm - Eigen Implementation.