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.
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.
GLdouble GLdouble GLdouble r
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.
GLfloat GLfloat GLfloat v2
CONTAINER::Scalar norm(const CONTAINER &v)