17 #include <Eigen/Dense>    19 #include <Eigen/StdVector>    20 #include <unsupported/Eigen/Polynomials>    25     Eigen::MatrixXd obj_pts_, Eigen::MatrixXd img_pts_, Eigen::MatrixXd cam_,
    37     for (
int i = 0; i < 
n; i++) 
Q.col(i) = 
Q.col(i) / 
Q.col(i).norm();
    44     Eigen::Ref<Eigen::Matrix3d> R_, Eigen::Ref<Eigen::Vector3d> t_)
    49         Q(0, i1) * Q(0, i2) + Q(1, i1) * Q(1, i2) + Q(2, i1) * Q(2, i2);
    51     Eigen::MatrixXi rij(n, 2);
    53     R_ = Eigen::MatrixXd::Identity(3, 3);
    54     t_ = Eigen::Vector3d::Zero();
    56     for (
int i = 0; i < n; i++)
    57         for (
int j = 0; j < 2; j++) rij(i, j) = rand() % n;
    59     for (
int ii = 0; ii < n; ii++)
    61         int i = rij(ii, 0), j = rij(ii, 1);
    65         double l = Q(0, i) * Q(0, j) + Q(1, i) * Q(1, j) + Q(2, i) * Q(2, j);
    76     Eigen::Vector3d p1, p2, p0, x, y, z, dum_vec;
    85     if (std::abs(x(1)) < std::abs(x(2)))
   108     for (
int i = 0; i < n; i++) P.col(i) = R0.transpose() * (P.col(i) - p0);
   113     Eigen::Vector3d v1 = Q.col(i1), v2 = Q.col(i2);
   114     double cg1 = v1.dot(v2);
   115     double sg1 = sqrt(1 - cg1 * cg1);
   116     double D1 = (P.col(i1) - P.col(i2)).
norm();
   117     Eigen::MatrixXd D4(n - 2, 5);
   119     Eigen::VectorXd rowvec(5);
   120     for (
int i = 0, j = 0; i < n; i++)
   122         if (i == i1 || i == i2) 
continue;
   124         Eigen::Vector3d vi = Q.col(i);
   125         double cg2 = v1.dot(vi);
   126         double cg3 = v2.dot(vi);
   127         double sg2 = sqrt(1 - cg2 * cg2);
   128         double D2 = (P.col(i1) - P.col(i)).
norm();
   129         double D3 = (P.col(i) - P.col(i2)).
norm();
   133         rowvec = getp3p(cg1, cg2, cg3, sg1, sg2, D1, D2, D3);
   137         if (j > n - 3) 
break;
   140     Eigen::VectorXd D7(8), dumvec(8), dumvec1(5);
   143     for (
int i = 0; i < n - 2; i++)
   146         dumvec = getpoly7(dumvec1);
   150     Eigen::PolynomialSolver<double, 7> psolve(D7.reverse());
   151     Eigen::VectorXcd comp_roots = psolve.roots().transpose();
   152     Eigen::VectorXd real_comp, imag_comp;
   153     real_comp = comp_roots.real();
   154     imag_comp = comp_roots.imag();
   156     Eigen::VectorXd::Index max_index;
   158     double max_real = real_comp.cwiseAbs().maxCoeff(&max_index);
   160     std::vector<double> act_roots_;
   164     for (
int i = 0; i < imag_comp.size(); i++)
   166         if (std::abs(imag_comp(i)) / max_real < 0.001)
   168             act_roots_.push_back(real_comp(i));
   173     double* ptr = &act_roots_[0];
   181     Eigen::VectorXd act_roots1(cnt);
   182     act_roots1 << act_roots.segment(0, cnt);
   184     std::vector<Eigen::Matrix3d> R_cum(cnt);
   185     std::vector<Eigen::Vector3d> t_cum(cnt);
   186     std::vector<double> err_cum(cnt);
   188     for (
int i = 0; i < cnt; i++)
   190         double root = act_roots(i);
   194         double d2 = cg1 + root;
   196         Eigen::Vector3d unitx, unity, unitz;
   202         if (std::abs(unity.dot(x)) < std::abs(unitz.dot(x)))
   222         Eigen::MatrixXd D(2 * n, 6);
   229         for (
int j = 0; j < n; j++)
   231             double ui = img_pts(j, 0), vi = img_pts(j, 1), xi = P(0, j),
   232                    yi = P(1, j), zi = P(2, j);
   233             D.row(2 * j) << -r(1) * yi + ui * (r(7) * yi + r(8) * zi) -
   235                 -r(2) * yi + ui * (r(8) * yi - r(7) * zi) + r(1) * zi, -1, 0,
   236                 ui, ui * r(6) * xi - r(0) * xi;
   239                 << -r(4) * yi + vi * (r(7) * yi + r(8) * zi) - r(5) * zi,
   240                 -r(5) * yi + vi * (r(8) * yi - r(7) * zi) + r(4) * zi, 0, -1,
   241                 vi, vi * r(6) * xi - r(3) * xi;
   244         Eigen::MatrixXd DTD = D.transpose() * D;
   246         Eigen::EigenSolver<Eigen::MatrixXd> es(DTD);
   248         Eigen::VectorXd Diag = es.pseudoEigenvalueMatrix().diagonal();
   250         Eigen::MatrixXd V_mat = es.pseudoEigenvectors();
   252         Eigen::MatrixXd::Index min_index;
   254         Diag.minCoeff(&min_index);
   256         Eigen::VectorXd V = V_mat.col(min_index);
   260         double c = V(0), s = V(1);
   261         t << V(2), V(3), V(4);
   264         Eigen::VectorXd xi, yi, zi;
   269         Eigen::MatrixXd XXcs(3, n), XXc(3, n);
   272         XXcs.row(0) = r(0) * xi + (r(1) * c + r(2) * s) * yi +
   273                       (-r(1) * s + r(2) * c) * zi +
   274                       t(0) * Eigen::VectorXd::Ones(n);
   275         XXcs.row(1) = r(3) * xi + (r(4) * c + r(5) * s) * yi +
   276                       (-r(4) * s + r(5) * c) * zi +
   277                       t(1) * Eigen::VectorXd::Ones(n);
   278         XXcs.row(2) = r(6) * xi + (r(7) * c + r(8) * s) * yi +
   279                       (-r(7) * s + r(8) * c) * zi +
   280                       t(2) * Eigen::VectorXd::Ones(n);
   282         for (
int ii = 0; ii < n; ii++)
   283             XXc.col(ii) = Q.col(ii) * XXcs.col(ii).norm();
   288         Eigen::MatrixXd XXw = obj_pts.transpose();
   290         calcampose(XXc, XXw, R2, t2);
   295         for (
int k = 0; k < n; k++) XXc.col(k) = R2 * XXw.col(k) + t2;
   297         Eigen::MatrixXd xxc(2, n);
   299         xxc.row(0) = XXc.row(0).array() / XXc.row(2).array();
   300         xxc.row(1) = XXc.row(1).array() / XXc.row(2).array();
   302         double res = ((xxc.row(0) - img_pts.col(0).transpose()).
norm() +
   303                       (xxc.row(1) - img_pts.col(1).transpose()).
norm()) /
   310         std::min_element(err_cum.begin(), err_cum.end()) - err_cum.begin();
   319     Eigen::MatrixXd& XXc, Eigen::MatrixXd& XXw, Eigen::Matrix3d& R2,
   322     Eigen::MatrixXd X = XXc;
   323     Eigen::MatrixXd Y = XXw;
   325         Eigen::MatrixXd::Identity(n, n) - Eigen::MatrixXd::Ones(n, n) * 1 / n;
   326     Eigen::VectorXd ux, uy;
   327     uy = X.rowwise().mean();
   328     ux = Y.rowwise().mean();
   332         (((X * K).array() * (X * K).array()).colwise().sum()).
mean();
   334     Eigen::MatrixXd SXY = Y * K * (X.transpose()) / n;
   336     Eigen::JacobiSVD<Eigen::MatrixXd> svd(
   337         SXY, Eigen::ComputeThinU | Eigen::ComputeThinV);
   339     Eigen::Matrix3d S = Eigen::MatrixXd::Identity(3, 3);
   340     if (SXY.determinant() < 0) S(2, 2) = -1;
   342     R2 = svd.matrixV() * S * svd.matrixU().transpose();
   344     double c2 = (svd.singularValues().asDiagonal() * S).trace() / sigmax2;
   345     t2 = uy - c2 * R2 * ux;
   347     Eigen::Vector3d x, y, z;
   352     if ((x.cross(y) - z).
norm() > 0.02) R2.col(2) = -R2.col(2);
   357     Eigen::VectorXd vout(8);
   358     vout << 4 * pow(vin(0), 2), 7 * vin(1) * vin(0),
   359         6 * vin(2) * vin(0) + 3 * pow(vin(1), 2),
   360         5 * vin(3) * vin(0) + 5 * vin(2) * vin(1),
   361         4 * vin(4) * vin(0) + 4 * vin(3) * vin(1) + 2 * pow(vin(2), 2),
   362         3 * vin(4) * vin(1) + 3 * vin(3) * vin(2),
   363         2 * vin(4) * vin(2) + pow(vin(3), 2), vin(4) * vin(3);
   368     double l1, 
double l2, 
double A5, 
double C1, 
double C2, 
double D1, 
double D2,
   371     double A1 = (D2 / D1) * (D2 / D1);
   372     double A2 = 
A1 * pow(C1, 2) - pow(C2, 2);
   373     double A3 = l2 * A5 - l1;
   374     double A4 = l1 * A5 - l2;
   375     double A6 = (pow(D3, 2) - pow(D1, 2) - pow(D2, 2)) / (2 * pow(D1, 2));
   376     double A7 = 1 - pow(l1, 2) - pow(l2, 2) + l1 * l2 * A5 + A6 * pow(C1, 2);
   378     Eigen::VectorXd vec(5);
   380     vec << pow(A6, 2) - 
A1 * pow(A5, 2), 2 * (A3 * A6 - 
A1 * A4 * A5),
   381         pow(A3, 2) + 2 * A6 * A7 - 
A1 * pow(A4, 2) - A2 * pow(A5, 2),
   382         2 * (A3 * A7 - A2 * A4 * A5), pow(A7, 2) - A2 * pow(A4, 2);
 Eigen::MatrixXd P
Camera Intrinsic Matrix. 
 
void calcampose(Eigen::MatrixXd &XXc, Eigen::MatrixXd &XXw, Eigen::Matrix3d &R2, Eigen::Vector3d &t2)
Function to calculate final pose. 
 
Eigen::MatrixXd cam_intrinsic
Image Points (n X 3) in Camera Co-ordinate system. 
 
Eigen::Vector3d t
Rotation matrix. 
 
rpnp(Eigen::MatrixXd obj_pts_, Eigen::MatrixXd img_pts_, Eigen::MatrixXd cam_, int n0)
Number of 2D/3D correspondences. 
 
Eigen::VectorXd getp3p(double l1, double l2, double A5, double C1, double C2, double D1, double D2, double D3)
Function to compute pose using P3P. 
 
Eigen::MatrixXd img_pts
Object Points (n X 3) in Camera Co-ordinate system. 
 
Robust - PnP class definition for computing pose. 
 
bool compute_pose(Eigen::Ref< Eigen::Matrix3d > R_, Eigen::Ref< Eigen::Vector3d > t_)
Function to compute pose. 
 
double mean(const CONTAINER &v)
Computes the mean value of a vector. 
 
Eigen::MatrixXd Q
Transposed Object Points (3 X n) for computations. 
 
Eigen::Matrix3d R
Transposed Image Points (3 X n) for computations. 
 
Eigen::VectorXd getpoly7(const Eigen::VectorXd &vin)
Get Polynomial from input vector. 
 
CONTAINER::Scalar norm(const CONTAINER &v)