16 #include <Eigen/Dense>    18 #include <Eigen/StdVector>    19 #include <unsupported/Eigen/Polynomials>    35         for (
int i = 0; i < 
n; i++)
    36                 Q.col(i) = 
Q.col(i) / 
Q.col(i).norm();
    46         double lmin = Q(0, i1)*Q(0, i2) + Q(1, i1)*Q(1, i2) + Q(2, i1)*Q(2, i2);
    48         Eigen::MatrixXi rij (
n,2);
    50     R_=Eigen::MatrixXd::Identity(3,3);
    51     t_=Eigen::Vector3d::Zero();
    53         for (
int i = 0; i < 
n; i++)
    54                 for (
int j = 0; j < 2; j++)
    55                         rij(i, j) = rand() % 
n;
    57         for (
int ii = 0; ii < 
n; ii++)
    59                 int i = rij(ii, 0), j = rij(ii,1);
    64                 double l = Q(0, i)*Q(0, j) + Q(1, i)*Q(1, j) + Q(2, i)*Q(2, j);
    75         Eigen::Vector3d p1, p2, p0, 
x, 
y, 
z, dum_vec;
    81         x = p2 - p0; 
x /= 
x.norm();
    83         if (std::abs(
x(1)) < std::abs(
x(2)) )
    86                 z = 
x.cross(dum_vec); 
z /= 
z.norm();
    87                 y = 
z.cross(
x); 
y /= 
y.norm();
    92                 y = dum_vec.cross(
x); 
y /= 
y.norm();
    93                 z = 
x.cross(
y); 
x /= 
x.norm();
    98         R0.col(0) = 
x; R0.col(1) =
y; R0.col(2) = 
z;
   100         for (
int i = 0; i < 
n; i++)
   101                 P.col(i) = R0.transpose() * (P.col(i) - p0);
   106         Eigen::Vector3d 
v1 = Q.col(i1), 
v2 = Q.col(i2);
   107         double cg1 = 
v1.dot(
v2);
   108         double sg1 = sqrt(1 - cg1*cg1);
   109         double D1 = (P.col(i1) - P.col(i2)).
norm();
   110         Eigen::MatrixXd D4(
n - 2, 5);
   114     Eigen::VectorXd rowvec(5);
   115         for (
int i = 0; i < 
n; i++)
   117                 if (i == i1 || i == i2)
   121                 double cg2 = 
v1.dot(vi); 
   122                 double cg3 = 
v2.dot(vi);
   123                 double sg2 = sqrt(1 - cg2*cg2);
   124                 double D2 = (P.col(i1) - P.col(i)).
norm();
   125                 double D3 = (P.col(i) - P.col(i2)).
norm();
   129                 rowvec = getp3p(cg1, cg2, cg3, sg1, sg2, D1, D2, D3);
   137         Eigen::VectorXd D7(8), dumvec(8), dumvec1(5);
   140         for (
int i = 0; i < 
n-2; i++)
   143                 dumvec= getpoly7(dumvec1);
   147         Eigen::PolynomialSolver<double, 7> psolve(D7.reverse());
   148         Eigen::VectorXcd comp_roots = psolve.roots().transpose();
   149         Eigen::VectorXd real_comp, imag_comp;
   150         real_comp = comp_roots.real();
   151         imag_comp = comp_roots.imag();
   153         Eigen::VectorXd::Index max_index;
   155         double max_real= real_comp.cwiseAbs().maxCoeff(&max_index);
   157     std::vector<double> act_roots_;
   161         for (
int i=0; i<imag_comp.size(); i++ )
   163                 if(std::abs(imag_comp(i))/max_real<0.001)
   165                                 act_roots_.push_back(real_comp(i));
   170     double* ptr = &act_roots_[0];
   171     Eigen::Map<Eigen::VectorXd> act_roots(ptr, cnt); 
   178     Eigen::VectorXd act_roots1(cnt);
   179     act_roots1 << act_roots.segment(0,cnt);
   181         std::vector<Eigen::Matrix3d> R_cum(cnt);
   182         std::vector<Eigen::Vector3d> t_cum(cnt);
   183         std::vector<double> err_cum(cnt);
   185         for(
int i=0; i<cnt; i++)
   187                 double root = act_roots(i);
   191                 double d2 = cg1 + root;
   193                 Eigen::Vector3d unitx, unity, unitz;
   199                 if (std::abs(unity.dot(
x)) < std::abs(unitz.dot(
x)))
   201                         z = 
x.cross(unity);
z/=
z.norm();
   202                         y=
z.cross(
x); 
y/
y.norm();
   206                         y=unitz.cross(
x); 
y/=
y.norm();
   207                         z = 
x.cross(
y); 
z/=
z.norm();
   215                 Eigen::MatrixXd D(2 * 
n, 6);
   219                 Eigen::VectorXd 
r(Eigen::Map<Eigen::VectorXd>(R0.data(), R0.cols()*R0.rows()));
   221                 for (
int j = 0; j<
n; j++)
   223                         double ui = img_pts(j, 0), vi = img_pts(j, 1), xi = P(0, j), yi = P(1, j), zi = P(2, j);
   224                         D.row(2 * j) << -
r(1)*yi + ui*(
r(7)*yi + 
r(8)*zi) - 
r(2)*zi,
   225                                 -
r(2)*yi + ui*(
r(8)*yi - 
r(7)*zi) + 
r(1)*zi,
   229                                 ui*
r(6)*xi - 
r(0)*xi;
   231                         D.row(2 * j + 1) << -
r(4)*yi + vi*(
r(7)*yi + 
r(8)*zi) - 
r(5)*zi,
   232                                 -
r(5)*yi + vi*(
r(8)*yi - 
r(7)*zi) + 
r(4)*zi,
   236                                 vi*
r(6)*xi - 
r(3)*xi;
   239                 Eigen::MatrixXd DTD = D.transpose()*D;
   241                 Eigen::EigenSolver<Eigen::MatrixXd> es(DTD);
   243                 Eigen::VectorXd Diag = es.pseudoEigenvalueMatrix().diagonal();
   245                 Eigen::MatrixXd V_mat = es.pseudoEigenvectors();
   247                 Eigen::MatrixXd::Index min_index;
   249                 Diag.minCoeff(&min_index);
   251                 Eigen::VectorXd V = V_mat.col(min_index);
   255                 double c = V(0), 
s = V(1);
   256                 t << V(2), V(3), V(4);
   259                 Eigen::VectorXd xi, yi, zi;
   264                 Eigen::MatrixXd XXcs(3, 
n), XXc(3,
n);
   267                 XXcs.row(0) = 
r(0)*xi + (
r(1)*
c + 
r(2)*
s)*yi + (-
r(1)*
s + 
r(2)*
c)*zi + 
t(0)*Eigen::VectorXd::Ones(
n);
   268                 XXcs.row(1) = 
r(3)*xi + (
r(4)*
c + 
r(5)*
s)*yi + (-
r(4)*
s + 
r(5)*
c)*zi + 
t(1)*Eigen::VectorXd::Ones(
n);
   269                 XXcs.row(2) = 
r(6)*xi + (
r(7)*
c + 
r(8)*
s)*yi + (-
r(7)*
s + 
r(8)*
c)*zi + 
t(2)*Eigen::VectorXd::Ones(
n);
   271                 for (
int ii = 0; ii < 
n; ii++)
   272                         XXc.col(ii) = Q.col(ii)*XXcs.col(ii).norm();
   277                 Eigen::MatrixXd XXw = obj_pts.transpose();
   279                 calcampose(XXc, XXw, R2, t2);
   284                 for (
int k = 0; k < 
n; k++)
   285                         XXc.col(k) = R2 * XXw.col(k) + t2;
   287                 Eigen::MatrixXd xxc(2, 
n);
   289                 xxc.row(0) = XXc.row(0).array() / XXc.row(2).array();
   290                 xxc.row(1) = XXc.row(1).array() / XXc.row(2).array();
   292                 double res = ((xxc.row(0) - img_pts.col(0).transpose()).
norm() + (xxc.row(1) - img_pts.col(1).transpose()).
norm()) / 2;
   298         int pos_cum = std::min_element(err_cum.begin(), err_cum.end()) - err_cum.begin();
   308         Eigen::MatrixXd X = XXc;
   309         Eigen::MatrixXd Y = XXw;
   310         Eigen::MatrixXd K = Eigen::MatrixXd::Identity(
n, 
n) - Eigen::MatrixXd::Ones(
n, 
n) * 1 / 
n;
   311         Eigen::VectorXd ux, uy;
   312         uy = X.rowwise().mean();
   313         ux = Y.rowwise().mean();
   316         double sigmax2 = (((X*K).array() * (X*K).array()).colwise().sum()).
mean();
   318         Eigen::MatrixXd SXY = Y*K*(X.transpose()) / 
n;
   320         Eigen::JacobiSVD<Eigen::MatrixXd> svd(SXY, Eigen::ComputeThinU | Eigen::ComputeThinV);
   322         Eigen::Matrix3d S = Eigen::MatrixXd::Identity(3, 3);
   323         if (SXY.determinant() <0)
   326         R2 = svd.matrixV()*S*svd.matrixU().transpose();
   328         double c2 = (svd.singularValues().asDiagonal()*S).trace() / sigmax2;
   331         Eigen::Vector3d 
x, 
y, 
z;
   336         if ((
x.cross(
y) - 
z).
norm()>0.02)
   337                 R2.col(2) = -R2.col(2);
   342         Eigen::VectorXd vout(8);
   343         vout << 4 * pow(vin(0), 2),
   345                 6 * vin(2)*vin(0) + 3 * pow(vin(1), 2),
   346                 5 * vin(3)*vin(0) + 5 * vin(2)*vin(1),
   347                 4 * vin(4)*vin(0) + 4 * vin(3)*vin(1) + 2 * pow(vin(2), 2),
   348                 3 * vin(4)*vin(1) + 3 * vin(3)*vin(2),
   349                 2 * vin(4)*vin(2) + pow(vin(3), 2),
   356         double A1 = (D2 / D1)*(D2 / D1);
   357         double A2 = 
A1*pow(C1, 2) - pow(C2, 2);
   358         double A3 = l2*A5 - l1;
   359         double A4 = l1*A5 - l2;
   360         double A6 = (pow(D3, 2) - pow(D1, 2) - pow(D2, 2)) / (2 * pow(D1, 2));
   361         double A7 = 1 - pow(l1, 2) - pow(l2, 2) + l1*l2*A5 + A6*pow(C1, 2);
   363     Eigen::VectorXd vec(5);
   365         vec << pow(A6, 2) - 
A1*pow(A5, 2),
   366                 2 * (A3*A6 - 
A1*A4*A5),
   367                 pow(A3, 2) + 2 * A6*A7 - 
A1*pow(A4, 2) - A2*pow(A5, 2),
   368                 2 * (A3*A7 - A2*A4*A5),
   369                 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. 
 
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 A1
UTC constant and 1st order terms. 
 
GLdouble GLdouble GLdouble r
 
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. 
 
GLfloat GLfloat GLfloat v2
 
EIGEN_STRONG_INLINE double mean() const
Computes the mean of the entire matrix. 
 
CONTAINER::Scalar norm(const CONTAINER &v)