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> 45 bool mrpt::vision::pnp::CPnP::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){
47 #if MRPT_HAS_OPENCV==1 50 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
53 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
55 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
58 if(obj_pts.rows() < obj_pts.cols())
60 cam_in_eig=cam_intrinsic.transpose();
61 img_pts_eig=img_pts.transpose().block(0,0,
n,2);
62 obj_pts_eig=obj_pts.transpose();
66 cam_in_eig=cam_intrinsic;
67 img_pts_eig=img_pts.block(0,0,
n,2);
72 Eigen::Matrix3d R_eig;
73 Eigen::MatrixXd t_eig;
76 cv::Mat cam_in_cv(3,3,CV_32F), img_pts_cv(2,
n,CV_32F), obj_pts_cv(3,
n,CV_32F), R_cv(3,3,CV_32F), t_cv(3,1,CV_32F);
78 cv::eigen2cv(cam_in_eig, cam_in_cv);
79 cv::eigen2cv(img_pts_eig, img_pts_cv);
80 cv::eigen2cv(obj_pts_eig, obj_pts_cv);
85 cv::cv2eigen(R_cv, R_eig);
86 cv::cv2eigen(t_cv, t_eig);
88 Eigen::Quaterniond
q(R_eig);
90 pose_mat << t_eig,
q.vec();
102 case -1: std::cout <<
"Please install OpenCV for DLS-PnP" << std::endl;
break;
103 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
104 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
110 bool mrpt::vision::pnp::CPnP::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){
112 #if MRPT_HAS_OPENCV==1 115 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
118 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
120 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
123 if(obj_pts.rows() < obj_pts.cols())
125 cam_in_eig=cam_intrinsic.transpose();
126 img_pts_eig=img_pts.transpose().block(0,0,
n,2);
127 obj_pts_eig=obj_pts.transpose();
131 cam_in_eig=cam_intrinsic;
132 img_pts_eig=img_pts.block(0,0,
n,2);
137 Eigen::Matrix3d R_eig;
138 Eigen::MatrixXd t_eig;
141 cv::Mat cam_in_cv(3,3,CV_32F), img_pts_cv(2,
n,CV_32F), obj_pts_cv(3,
n,CV_32F), R_cv, t_cv;
143 cv::eigen2cv(cam_in_eig, cam_in_cv);
144 cv::eigen2cv(img_pts_eig, img_pts_cv);
145 cv::eigen2cv(obj_pts_eig, obj_pts_cv);
150 cv::cv2eigen(R_cv, R_eig);
151 cv::cv2eigen(t_cv, t_eig);
153 Eigen::Quaterniond
q(R_eig);
155 pose_mat << t_eig,
q.vec();
166 case -1: std::cout <<
"Please install OpenCV for DLS-PnP" << std::endl;
break;
167 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
168 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
174 bool mrpt::vision::pnp::CPnP::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){
176 #if MRPT_HAS_OPENCV==1 179 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
182 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
184 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
187 if(obj_pts.rows() < obj_pts.cols())
189 cam_in_eig=cam_intrinsic.transpose();
190 img_pts_eig=img_pts.transpose().block(0,0,
n,2);
191 obj_pts_eig=obj_pts.transpose();
195 cam_in_eig=cam_intrinsic;
196 img_pts_eig=img_pts.block(0,0,
n,2);
201 Eigen::Matrix3d R_eig;
202 Eigen::MatrixXd t_eig;
205 cv::Mat cam_in_cv(3,3,CV_32F), img_pts_cv(2,
n,CV_32F), obj_pts_cv(3,
n,CV_32F), R_cv, t_cv;
207 cv::eigen2cv(cam_in_eig, cam_in_cv);
208 cv::eigen2cv(img_pts_eig, img_pts_cv);
209 cv::eigen2cv(obj_pts_eig, obj_pts_cv);
214 cv::cv2eigen(R_cv, R_eig);
215 cv::cv2eigen(t_cv, t_eig);
217 Eigen::Quaterniond
q(R_eig);
219 pose_mat << t_eig,
q.vec();
230 case -1: std::cout <<
"Please install OpenCV for DLS-PnP" << std::endl;
break;
231 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
232 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
239 bool mrpt::vision::pnp::CPnP::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){
243 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
246 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
248 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
251 if(obj_pts.rows() < obj_pts.cols())
253 cam_in_eig=cam_intrinsic.transpose();
254 img_pts_eig=img_pts.transpose().block(0,0,
n,2);
255 obj_pts_eig=obj_pts.transpose();
259 cam_in_eig=cam_intrinsic;
260 img_pts_eig=img_pts.block(0,0,
n,2);
270 bool ret =
p.solve(
R,
t, obj_pts_eig, img_pts_eig);
272 Eigen::Quaterniond
q(
R);
274 pose_mat <<
t,
q.vec();
282 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
283 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
290 bool mrpt::vision::pnp::CPnP::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){
293 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
296 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
298 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
301 if(obj_pts.rows() < obj_pts.cols())
303 cam_in_eig=cam_intrinsic.transpose();
304 img_pts_eig=img_pts.transpose();
305 obj_pts_eig=obj_pts.transpose();
309 cam_in_eig=cam_intrinsic;
320 bool ret =
r.compute_pose(
R,
t);
322 Eigen::Quaterniond
q(
R);
324 pose_mat <<
t,
q.vec();
332 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
333 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
339 bool mrpt::vision::pnp::CPnP::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)
343 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
346 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
348 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
351 if(obj_pts.rows() < obj_pts.cols())
353 cam_in_eig=cam_intrinsic.transpose();
354 img_pts_eig=img_pts.transpose();
355 obj_pts_eig=obj_pts.transpose();
359 cam_in_eig=cam_intrinsic;
371 bool ret =
p.compute_pose(
R,
t,
n);
373 Eigen::Quaterniond
q(
R);
375 pose_mat <<
t,
q.vec();
383 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
384 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
390 bool mrpt::vision::pnp::CPnP::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)
394 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
397 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
399 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
402 if(obj_pts.rows() < obj_pts.cols())
404 cam_in_eig=cam_intrinsic.transpose();
405 img_pts_eig=img_pts.transpose().block(0,0,
n,2);
406 obj_pts_eig=obj_pts.transpose();
410 cam_in_eig=cam_intrinsic;
411 img_pts_eig=img_pts.block(0,0,
n,2);
422 bool ret =
p.compute_pose(
R,
t);
424 Eigen::Quaterniond
q(
R);
426 pose_mat <<
t,
q.vec();
434 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
435 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
442 bool mrpt::vision::pnp::CPnP::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)
446 Eigen::MatrixXd cam_in_eig,img_pts_eig, obj_pts_eig;
449 if (img_pts.rows() != obj_pts.rows() || img_pts.cols() !=obj_pts.cols())
451 else if (cam_intrinsic.rows()!=3 || cam_intrinsic.cols()!=3)
454 if(obj_pts.rows() < obj_pts.cols())
456 cam_in_eig=cam_intrinsic.transpose();
457 img_pts_eig=img_pts.transpose();
458 obj_pts_eig=obj_pts.transpose();
462 cam_in_eig=cam_intrinsic;
476 Eigen::Quaterniond
q(
R);
486 case 2: std::cout <<
"2d/3d correspondences mismatch\n Check dimension of obj_pts and img_pts" << std::endl;
break;
487 case 3: std::cout <<
"Camera intrinsic matrix does not have 3x3 dimensions " << std::endl;
break;
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.