28     fx = cam_intrinsic(0, 0);
    29     fy = cam_intrinsic(1, 1);
    30     cx = cam_intrinsic(0, 2);
    31     cy = cam_intrinsic(1, 2);
    32     init_inverse_parameters();
    41     init_inverse_parameters();
    47     if (cameraMatrix.depth() == CV_32F)
    48         init_camera_parameters<float>(cameraMatrix);
    50         init_camera_parameters<double>(cameraMatrix);
    51     init_inverse_parameters();
    55     cv::Mat& 
R, cv::Mat& tvec, 
const cv::Mat& opoints, 
const cv::Mat& ipoints)
    57     double rotation_matrix[3][3], translation[3];
    58     std::vector<double> points;
    59     if (opoints.depth() == ipoints.depth())
    61         if (opoints.depth() == CV_32F)
    62             extract_points<cv::Point3f, cv::Point2f>(opoints, ipoints, points);
    64             extract_points<cv::Point3d, cv::Point2d>(opoints, ipoints, points);
    66     else if (opoints.depth() == CV_32F)
    67         extract_points<cv::Point3f, cv::Point2d>(opoints, ipoints, points);
    69         extract_points<cv::Point3d, cv::Point2f>(opoints, ipoints, points);
    72         rotation_matrix, translation, points[0], points[1], points[2],
    73         points[3], points[4], points[5], points[6], points[7], points[8],
    74         points[9], points[10], points[11], points[12], points[13], points[14],
    75         points[15], points[16], points[17], points[18], points[19]);
    76     cv::Mat(3, 1, CV_64F, translation).copyTo(tvec);
    77     cv::Mat(3, 3, CV_64F, rotation_matrix).copyTo(
R);
    84     Eigen::Ref<Eigen::Matrix3d> 
R, Eigen::Ref<Eigen::Vector3d> t,
    85     Eigen::MatrixXd obj_pts, Eigen::MatrixXd img_pts)
    87     double rotation_matrix[3][3], translation[3];
    88     std::vector<double> points;
    89     extract_points(obj_pts, img_pts, points);
    91         rotation_matrix, translation, points[0], points[1], points[2],
    92         points[3], points[4], points[5], points[6], points[7], points[8],
    93         points[9], points[10], points[11], points[12], points[13], points[14],
    94         points[15], points[16], points[17], points[18], points[19]);
   101     double R[3][3], 
double t[3], 
double mu0, 
double mv0, 
double X0, 
double Y0,
   102     double Z0, 
double mu1, 
double mv1, 
double X1, 
double Y1, 
double Z1,
   103     double mu2, 
double mv2, 
double X2, 
double Y2, 
double Z2, 
double mu3,
   104     double mv3, 
double X3, 
double Y3, 
double Z3)
   106     double Rs[4][3][3], ts[4][3];
   109         Rs, ts, mu0, mv0, X0, Y0, Z0, mu1, mv1, X1, Y1, Z1, mu2, mv2, X2, Y2,
   112     if (n == 0) 
return false;
   115     double min_reproj = 0;
   116     for (
int i = 0; i < n; i++)
   119             Rs[i][0][0] * X3 + Rs[i][0][1] * Y3 + Rs[i][0][2] * Z3 + ts[i][0];
   121             Rs[i][1][0] * X3 + Rs[i][1][1] * Y3 + Rs[i][1][2] * Z3 + ts[i][1];
   123             Rs[i][2][0] * X3 + Rs[i][2][1] * Y3 + Rs[i][2][2] * Z3 + ts[i][2];
   124         double mu3p = cx + fx * X3p / Z3p;
   125         double mv3p = cy + fy * Y3p / Z3p;
   127             (mu3p - mu3) * (mu3p - mu3) + (mv3p - mv3) * (mv3p - mv3);
   128         if (i == 0 || min_reproj > reproj)
   135     for (
int i = 0; i < 3; i++)
   137         for (
int j = 0; j < 3; j++) 
R[i][j] = Rs[ns][i][j];
   145     double R[4][3][3], 
double t[4][3], 
double mu0, 
double mv0, 
double X0,
   146     double Y0, 
double Z0, 
double mu1, 
double mv1, 
double X1, 
double Y1,
   147     double Z1, 
double mu2, 
double mv2, 
double X2, 
double Y2, 
double Z2)
   149     double mk0, mk1, mk2;
   152     mu0 = inv_fx * mu0 - cx_fx;
   153     mv0 = inv_fy * mv0 - cy_fy;
   154     norm = sqrt(mu0 * mu0 + mv0 * mv0 + 1);
   159     mu1 = inv_fx * mu1 - cx_fx;
   160     mv1 = inv_fy * mv1 - cy_fy;
   161     norm = sqrt(mu1 * mu1 + mv1 * mv1 + 1);
   166     mu2 = inv_fx * mu2 - cx_fx;
   167     mv2 = inv_fy * mv2 - cy_fy;
   168     norm = sqrt(mu2 * mu2 + mv2 * mv2 + 1);
   175         (X1 - X2) * (X1 - X2) + (Y1 - Y2) * (Y1 - Y2) + (Z1 - Z2) * (Z1 - Z2));
   177         (X0 - X2) * (X0 - X2) + (Y0 - Y2) * (Y0 - Y2) + (Z0 - Z2) * (Z0 - Z2));
   179         (X0 - X1) * (X0 - X1) + (Y0 - Y1) * (Y0 - Y1) + (Z0 - Z1) * (Z0 - Z1));
   183     cosines[0] = mu1 * mu2 + mv1 * mv2 + mk1 * mk2;
   184     cosines[1] = mu0 * mu2 + mv0 * mv2 + mk0 * mk2;
   185     cosines[2] = mu0 * mu1 + mv0 * mv1 + mk0 * mk1;
   187     double lengths[4][3];
   188     int n = solve_for_lengths(lengths, distances, cosines);
   190     int nb_solutions = 0;
   191     for (
int i = 0; i < n; i++)
   195         M_orig[0][0] = lengths[i][0] * mu0;
   196         M_orig[0][1] = lengths[i][0] * mv0;
   197         M_orig[0][2] = lengths[i][0] * mk0;
   199         M_orig[1][0] = lengths[i][1] * mu1;
   200         M_orig[1][1] = lengths[i][1] * mv1;
   201         M_orig[1][2] = lengths[i][1] * mk1;
   203         M_orig[2][0] = lengths[i][2] * mu2;
   204         M_orig[2][1] = lengths[i][2] * mv2;
   205         M_orig[2][2] = lengths[i][2] * mk2;
   208                 M_orig, X0, Y0, Z0, X1, Y1, Z1, X2, Y2, Z2, 
R[nb_solutions],
   234     double lengths[4][3], 
double distances[3], 
double cosines[3])
   236     double p = cosines[0] * 2;
   237     double q = cosines[1] * 2;
   238     double r = cosines[2] * 2;
   240     double inv_d22 = 1. / (distances[2] * distances[2]);
   241     double a = inv_d22 * (distances[0] * distances[0]);
   242     double b = inv_d22 * (distances[1] * distances[1]);
   244     double a2 = a * a, 
b2 = b * b, p2 = p * p, q2 = q * q, r2 = r * r;
   245     double pr = p * r, pqr = q * pr;
   248     if (p2 + q2 + r2 - pqr - 1 == 0) 
return 0;
   250     double ab = a * b, a_2 = 2 * a;
   252     double A = -2 * b + 
b2 + 
a2 + 1 + ab * (2 - r2) - a_2;
   255     if (
A == 0) 
return 0;
   260         q * (-2 * (ab + 
a2 + 1 - b) + r2 * ab + a_4) + pr * (b - 
b2 + ab);
   261     double C = q2 + 
b2 * (r2 + p2 - 2) - b * (p2 + pqr) - ab * (r2 + pqr) +
   262                (
a2 - a_2) * (2 + q2) + 2;
   264         pr * (ab - 
b2 + b) + q * ((p2 - 2) * b + 2 * (ab - 
a2) + a_4 - 2);
   265     double E = 1 + 2 * (b - a - ab) + 
b2 - b * p2 + 
a2;
   267     double temp = (p2 * (a - 1 + b) + r2 * (a - 1 - b) + pqr - a * pqr);
   268     double b0 = b * temp * temp;
   270     if (
b0 == 0) 
return 0;
   272     double real_roots[4];
   274         A, B, C, D, E, real_roots[0], real_roots[1], real_roots[2],
   277     if (n == 0) 
return 0;
   279     int nb_solutions = 0;
   280     double r3 = r2 * r, pr2 = p * r2, r3q = r3 * q;
   281     double inv_b0 = 1. / 
b0;
   284     for (
int i = 0; i < n; i++)
   286         double x = real_roots[i];
   289         if (x <= 0) 
continue;
   294             ((1 - a - b) * x2 + (q * a - q) * x + 1 - a + b) *
   295             (((r3 * (
a2 + ab * (2 - r2) - a_2 + 
b2 - 2 * b + 1)) * x +
   297               (r3q * (2 * (b - 
a2) + a_4 + ab * (r2 - 2) - 2) +
   298                pr2 * (1 + 
a2 + 2 * (ab - a - b) + r2 * (b - 
b2) + 
b2))) *
   301              (r3 * (q2 * (1 - 2 * a + 
a2) + r2 * (
b2 - ab) - a_4 +
   303               r * p2 * (
b2 + 2 * (ab - b - a) + 1 + 
a2) +
   304               pr2 * q * (a_4 + 2 * (b - ab - 
a2) - 2 - r2 * b)) *
   307              2 * r3q * (a_2 - b - 
a2 + ab - 1) +
   308              pr2 * (q2 - a_4 + 2 * (
a2 - 
b2) + r2 * b + q2 * (
a2 - a_2) + 2) +
   309              p2 * (p * (2 * (ab - a - b) + 
a2 + 
b2 + 1) +
   310                    2 * q * r * (b + a_2 - 
a2 - ab - 1)));
   313         if (
b1 <= 0) 
continue;
   315         double y = inv_b0 * 
b1;
   316         double v = x2 + y * y - x * y * r;
   318         if (v <= 0) 
continue;
   320         double Z = distances[2] / sqrt(v);
   324         lengths[nb_solutions][0] = X;
   325         lengths[nb_solutions][1] = Y;
   326         lengths[nb_solutions][2] = Z;
   335     double M_end[3][3], 
double X0, 
double Y0, 
double Z0, 
double X1, 
double Y1,
   336     double Z1, 
double X2, 
double Y2, 
double Z2, 
double R[3][3], 
double T[3])
   339     double C_start[3], C_end[3];
   340     for (
int i = 0; i < 3; i++)
   341         C_end[i] = (M_end[0][i] + M_end[1][i] + M_end[2][i]) / 3;
   342     C_start[0] = (X0 + X1 + X2) / 3;
   343     C_start[1] = (Y0 + Y1 + Y2) / 3;
   344     C_start[2] = (Z0 + Z1 + Z2) / 3;
   348     for (
int j = 0; j < 3; j++)
   351             (X0 * M_end[0][j] + X1 * M_end[1][j] + X2 * M_end[2][j]) / 3 -
   352             C_end[j] * C_start[0];
   354             (Y0 * M_end[0][j] + Y1 * M_end[1][j] + Y2 * M_end[2][j]) / 3 -
   355             C_end[j] * C_start[1];
   357             (Z0 * M_end[0][j] + Z1 * M_end[1][j] + Z2 * M_end[2][j]) / 3 -
   358             C_end[j] * C_start[2];
   361     double Qs[16], evs[4], U[16];
   363     Qs[0 * 4 + 0] = s[0 * 3 + 0] + s[1 * 3 + 1] + s[2 * 3 + 2];
   364     Qs[1 * 4 + 1] = s[0 * 3 + 0] - s[1 * 3 + 1] - s[2 * 3 + 2];
   365     Qs[2 * 4 + 2] = s[1 * 3 + 1] - s[2 * 3 + 2] - s[0 * 3 + 0];
   366     Qs[3 * 4 + 3] = s[2 * 3 + 2] - s[0 * 3 + 0] - s[1 * 3 + 1];
   368     Qs[1 * 4 + 0] = Qs[0 * 4 + 1] = s[1 * 3 + 2] - s[2 * 3 + 1];
   369     Qs[2 * 4 + 0] = Qs[0 * 4 + 2] = s[2 * 3 + 0] - s[0 * 3 + 2];
   370     Qs[3 * 4 + 0] = Qs[0 * 4 + 3] = s[0 * 3 + 1] - s[1 * 3 + 0];
   371     Qs[2 * 4 + 1] = Qs[1 * 4 + 2] = s[1 * 3 + 0] + s[0 * 3 + 1];
   372     Qs[3 * 4 + 1] = Qs[1 * 4 + 3] = s[2 * 3 + 0] + s[0 * 3 + 2];
   373     Qs[3 * 4 + 2] = Qs[2 * 4 + 3] = s[2 * 3 + 1] + s[1 * 3 + 2];
   375     jacobi_4x4(Qs, evs, U);
   379     double ev_max = evs[i_ev];
   380     for (
int i = 1; i < 4; i++)
   381         if (evs[i] > ev_max) ev_max = evs[i_ev = i];
   385     for (
int i = 0; i < 4; i++) q[i] = U[i * 4 + i_ev];
   387     double q02 = q[0] * q[0], q12 = q[1] * q[1], q22 = q[2] * q[2],
   389     double q0_1 = q[0] * q[1], q0_2 = q[0] * q[2], q0_3 = q[0] * q[3];
   390     double q1_2 = q[1] * q[2], q1_3 = q[1] * q[3];
   391     double q2_3 = q[2] * q[3];
   393     R[0][0] = q02 + q12 - q22 - q32;
   394     R[0][1] = 2. * (q1_2 - q0_3);
   395     R[0][2] = 2. * (q1_3 + q0_2);
   397     R[1][0] = 2. * (q1_2 + q0_3);
   398     R[1][1] = q02 + q22 - q12 - q32;
   399     R[1][2] = 2. * (q2_3 - q0_1);
   401     R[2][0] = 2. * (q1_3 - q0_2);
   402     R[2][1] = 2. * (q2_3 + q0_1);
   403     R[2][2] = q02 + q32 - q12 - q22;
   405     for (
int i = 0; i < 3; i++)
   406         T[i] = C_end[i] - (
R[i][0] * C_start[0] + 
R[i][1] * C_start[1] +
   407                            R[i][2] * C_start[2]);
   415     double Id[16] = {1., 0., 0., 0., 0., 1., 0., 0.,
   416                      0., 0., 1., 0., 0., 0., 0., 1.};
   418     memcpy(U, Id, 16 * 
sizeof(
double));
   424     memcpy(D, B, 4 * 
sizeof(
double));
   425     memset(Z, 0, 4 * 
sizeof(
double));
   427     for (
int iter = 0; iter < 50; iter++)
   429         double sum = fabs(
A[1]) + fabs(
A[2]) + fabs(
A[3]) + fabs(
A[6]) +
   430                      fabs(
A[7]) + fabs(
A[11]);
   432         if (
sum == 0.0) 
return true;
   434         double tresh = (iter < 3) ? 0.2 * 
sum / 16. : 0.0;
   435         for (
int i = 0; i < 3; i++)
   437             double* pAij = 
A + 5 * i + 1;
   438             for (
int j = i + 1; j < 4; j++)
   441                 double eps_machine = 100.0 * fabs(Aij);
   443                 if (iter > 3 && fabs(D[i]) + eps_machine == fabs(D[i]) &&
   444                     fabs(D[j]) + eps_machine == fabs(D[j]))
   446                 else if (fabs(Aij) > tresh)
   448                     double hh = D[j] - D[i], t;
   449                     if (fabs(hh) + eps_machine == fabs(hh))
   453                         double theta = 0.5 * hh / Aij;
   454                         t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
   455                         if (theta < 0.0) t = -t;
   465                     double c = 1.0 / sqrt(1 + t * t);
   467                     double tau = s / (1.0 + c);
   468                     for (
int k = 0; k <= i - 1; k++)
   470                         double g = 
A[k * 4 + i], h = 
A[k * 4 + j];
   471                         A[k * 4 + i] = g - s * (h + g * tau);
   472                         A[k * 4 + j] = h + s * (g - h * tau);
   474                     for (
int k = i + 1; k <= j - 1; k++)
   476                         double g = 
A[i * 4 + k], h = 
A[k * 4 + j];
   477                         A[i * 4 + k] = g - s * (h + g * tau);
   478                         A[k * 4 + j] = h + s * (g - h * tau);
   480                     for (
int k = j + 1; k < 4; k++)
   482                         double g = 
A[i * 4 + k], h = 
A[j * 4 + k];
   483                         A[i * 4 + k] = g - s * (h + g * tau);
   484                         A[j * 4 + k] = h + s * (g - h * tau);
   486                     for (
int k = 0; k < 4; k++)
   488                         double g = U[k * 4 + i], h = U[k * 4 + j];
   489                         U[k * 4 + i] = g - s * (h + g * tau);
   490                         U[k * 4 + j] = h + s * (g - h * tau);
   497         for (
int i = 0; i < 4; i++) B[i] += Z[i];
   498         memcpy(D, B, 4 * 
sizeof(
double));
   499         memset(Z, 0, 4 * 
sizeof(
double));
 
bool solve(cv::Mat &R, cv::Mat &tvec, const cv::Mat &opoints, const cv::Mat &ipoints)
Function to compute pose by P3P using OpenCV. 
 
bool jacobi_4x4(double *A, double *D, double *U)
Function used to compute the SVD. 
 
double inv_fy
Inverse of focal length x. 
 
bool align(double M_start[3][3], double X0, double Y0, double Z0, double X1, double Y1, double Z1, double X2, double Y2, double Z2, double R[3][3], double T[3])
 
int solve_for_lengths(double lengths[4][3], double distances[3], double cosines[3])
Helper function to  solve() 
 
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements. 
 
double cy_fy
Inverse of image center point x. 
 
int solve_deg4(double a, double b, double c, double d, double e, double &x0, double &x1, double &x2, double &x3)
Reference : Eric W. 
 
void init_inverse_parameters()
Function to compute inverse parameters of camera intrinsic matrix. 
 
p3p(double fx, double fy, double cx, double cy)
Constructor for p3p class using C. 
 
double cx_fx
Inverse of focal length y. 
 
double inv_fx
Image center y. 
 
CONTAINER::Scalar norm(const CONTAINER &v)
 
P3P Pose estimation Algorithm - Eigen Implementation. 
 
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".