35 #include <visp3/core/vpExponentialMap.h>
36 #include <visp3/core/vpHomogeneousMatrix.h>
37 #include <visp3/core/vpMath.h>
38 #include <visp3/core/vpMatrix.h>
39 #include <visp3/core/vpPlane.h>
40 #include <visp3/core/vpPoint.h>
41 #include <visp3/core/vpRobust.h>
42 #include <visp3/vision/vpHomography.h>
44 const double vpHomography::m_threshold_rotation = 1e-7;
45 const double vpHomography::m_threshold_displacement = 1e-18;
47 #ifndef DOXYGEN_SHOULD_SKIP_THIS
53 double s = sqrt((dx[0] * dx[0]) + (dx[1] * dx[1]) + (dx[2] * dx[2]));
57 for (
unsigned int i = 0; i < 3; ++i) {
62 double mcosi = 1 - cosi;
63 rd[0][0] = cosi + (mcosi * u[0] * u[0]);
64 rd[0][1] = (-sinu * u[2]) + (mcosi * u[0] * u[1]);
65 rd[0][2] = (sinu * u[1]) + (mcosi * u[0] * u[2]);
66 rd[1][0] = (sinu * u[2]) + (mcosi * u[1] * u[0]);
67 rd[1][1] = cosi + (mcosi * u[1] * u[1]);
68 rd[1][2] = (-sinu * u[0]) + (mcosi * u[1] * u[2]);
69 rd[2][0] = (-sinu * u[1]) + (mcosi * u[2] * u[0]);
70 rd[2][1] = (sinu * u[0]) + (mcosi * u[2] * u[1]);
71 rd[2][2] = cosi + (mcosi * u[2] * u[2]);
74 for (
unsigned int i = 0; i < 3; ++i) {
75 for (
unsigned int j = 0; j < 3; ++j) {
109 for (
unsigned int i = 0; i < nbpoint; ++i) {
111 if ((std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.))) &&
112 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.)))) {
116 if ((!only_1) && (!only_2)) {
124 robust.setMinMedianAbsoluteDeviation(0.00001);
130 while ((
vpMath::equal(r_1, r, m_threshold_rotation) ==
false) && (stop ==
false)) {
136 for (
unsigned int i = 0; i < 3; ++i) {
137 for (
unsigned int j = 0; j < 3; ++j) {
138 c2Rc1[i][j] = c2Mc1[i][j];
144 for (
unsigned int i = 0; i < nbpoint; ++i) {
145 if ((std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.))) &&
146 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.)))) {
147 p2[0] = c2P[i].
get_x();
148 p2[1] = c2P[i].
get_y();
150 p1[0] = c1P[i].
get_x();
151 p1[1] = c1P[i].
get_y();
154 Hp2 = c2Rc1.t() * p2;
165 H2[0][1] = -(1 + (x * x));
167 H2[1][0] = 1 + (y * y);
174 e2[0] = Hp2[0] - c1P[i].
get_x();
175 e2[1] = Hp2[1] - c1P[i].
get_y();
182 H1[0][1] = -(1 + (x * x));
184 H1[1][0] = 1 + (y * y);
189 e1[0] = Hp1[0] - c2P[i].
get_x();
190 e1[1] = Hp1[1] - c2P[i].
get_y();
230 for (
unsigned int l = 0; l < n; ++l) {
236 for (
unsigned int l = 0; l < n; ++l) {
237 W[2 * l][2 * l] = w[l];
238 W[(2 * l) + 1][(2 * l) + 1] = w[l];
242 for (
unsigned int l = 0; l < (2 * n); ++l) {
246 L.pseudoInverse(Lp, 1e-6);
250 c2rc1 = -2 * Lp * W * e;
251 for (
unsigned int i = 0; i < 3; ++i) {
257 updatePoseRotation(c2rc1, c2Mc1);
260 if (((W * e).sumSquare() < 1e-10) || (iter > 25)) {
266 return (W * e).sumSquare();
271 double A1 = (cMo[0][0] * oN.
getA()) + (cMo[0][1] * oN.
getB()) + (cMo[0][2] * oN.
getC());
272 double B1 = (cMo[1][0] * oN.
getA()) + (cMo[1][1] * oN.
getB()) + (cMo[1][2] * oN.
getC());
273 double C1 = (cMo[2][0] * oN.
getA()) + (cMo[2][1] * oN.
getB()) + (cMo[2][2] * oN.
getC());
274 double D1 = oN.
getD() - ((cMo[0][3] * A1) + (cMo[1][3] * B1) + (cMo[2][3] * C1));
309 robust.setMinMedianAbsoluteDeviation(0.00001);
320 while ((!
vpMath::equal(r_1, r, m_threshold_displacement)) && (stop ==
false)) {
336 getPlaneInfo(oN, c1Mo, N1, d1);
337 getPlaneInfo(oN, c2Mo, N2, d2);
341 for (
unsigned int i = 0; i < nbpoint; ++i) {
342 p2[0] = c2P[i].
get_x();
343 p2[1] = c2P[i].
get_y();
345 p1[0] = c1P[i].
get_x();
346 p1[1] = c1P[i].
get_y();
351 Hp2 = (
static_cast<vpMatrix>(c1Rc2) + ((c1Tc2 * N2.t()) / d2)) * p2;
352 Hp1 = (
static_cast<vpMatrix>(c2Rc1) + ((c2Tc1 * N1.t()) / d1)) * p1;
362 Z1 = ((N1[0] * x) + (N1[1] * y) + N1[2]) / d1;
371 H2[0][4] = -(1 + (x * x));
373 H2[1][3] = 1 + (y * y);
380 sTR = c1Tc2.
skew() * c1Rc2;
381 for (
unsigned int k_ = 0; k_ < 3; ++k_) {
382 for (
unsigned int l = 0; l < 3; ++l) {
383 c1CFc2[k_][l] = c1Rc2[k_][l];
384 c1CFc2[k_ + 3][l + 3] = c1Rc2[k_][l];
385 c1CFc2[k_][l + 3] = sTR[k_][l];
392 e2[0] = Hp2[0] - c1P[i].
get_x();
393 e2[1] = Hp2[1] - c1P[i].
get_y();
398 Z1 = ((N2[0] * x) + (N2[1] * y) + N2[2]) / d2;
407 H1[0][4] = -(1 + (x * x));
409 H1[1][3] = 1 + (y * y);
414 e1[0] = Hp1[0] - c2P[i].
get_x();
415 e1[1] = Hp1[1] - c2P[i].
get_y();
454 for (
unsigned int l = 0; l < n; ++l) {
460 for (
unsigned int l = 0; l < n; ++l) {
461 W[2 * l][2 * l] = w[l];
462 W[(2 * l) + 1][(2 * l) + 1] = w[l];
466 for (
unsigned int l = 0; l < (2 * n); ++l) {
470 (W * L).pseudoInverse(Lp, 1e-16);
474 c2Tcc1 = -1 * Lp * W * e;
479 r = (W * e).sumSquare();
481 if ((r < 1e-15) || (iter > 1000) || (r > r_1)) {
487 return (W * e).sumSquare();
518 robust.setMinMedianAbsoluteDeviation(0.00001);
529 while ((!
vpMath::equal(r_1, r, m_threshold_displacement)) && (stop ==
false)) {
547 for (i = 0; i < nbpoint; ++i) {
548 getPlaneInfo(oN[i], c1Mo, N1, d1);
549 getPlaneInfo(oN[i], c2Mo, N2, d2);
550 p2[0] = c2P[i].
get_x();
551 p2[1] = c2P[i].
get_y();
553 p1[0] = c1P[i].
get_x();
554 p1[1] = c1P[i].
get_y();
559 Hp2 = (
static_cast<vpMatrix>(c1Rc2) + ((c1Tc2 * N2.t()) / d2)) * p2;
560 Hp1 = (
static_cast<vpMatrix>(c2Rc1) + ((c2Tc1 * N1.t()) / d1)) * p1;
570 Z1 = ((N1[0] * x) + (N1[1] * y) + N1[2]) / d1;
579 H2[0][4] = -(1 + (x * x));
581 H2[1][3] = 1 + (y * y);
589 for (
unsigned int k_ = 0; k_ < 3; ++k_) {
590 for (
unsigned int l = 0; l < 3; ++l) {
591 c1CFc2[k_][l] = c1Rc2[k_][l];
592 c1CFc2[k_ + 3][l + 3] = c1Rc2[k_][l];
593 c1CFc2[k_][l + 3] = sTR[k_][l];
600 e2[0] = Hp2[0] - c1P[i].
get_x();
601 e2[1] = Hp2[1] - c1P[i].
get_y();
606 Z1 = ((N2[0] * x) + (N2[1] * y) + N2[2]) / d2;
615 H1[0][4] = -(1 + (x * x));
617 H1[1][3] = 1 + (y * y);
622 e1[0] = Hp1[0] - c2P[i].
get_x();
623 e1[1] = Hp1[1] - c2P[i].
get_y();
662 for (
unsigned int k_ = 0; k_ < n; ++k_) {
668 for (
unsigned int k_ = 0; k_ < n; ++k_) {
669 W[2 * k_][2 * k_] = w[k_];
670 W[(2 * k_) + 1][(2 * k_) + 1] = w[k_];
674 for (
unsigned int k_ = 0; k_ < (2 * n); ++k_) {
678 (W * L).pseudoInverse(Lp, 1e-16);
682 c2Tcc1 = -1 * Lp * W * e;
687 r = (W * e).sumSquare();
689 if ((r < 1e-15) || (iter > 1000) || (r > r_1)) {
695 return (W * e).sumSquare();
Implementation of column vector and the associated operations.
void resize(unsigned int i, bool flagNullify=true)
static vpHomogeneousMatrix direct(const vpColVector &v)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
void extract(vpRotationMatrix &R) const
void insert(const vpRotationMatrix &R)
void computeDisplacement(vpRotationMatrix &aRb, vpTranslationVector &atb, vpColVector &n)
static void robust(const std::vector< double > &xb, const std::vector< double > &yb, const std::vector< double > &xa, const std::vector< double > &ya, vpHomography &aHb, std::vector< bool > &inliers, double &residual, double weights_threshold=0.4, unsigned int niter=4, bool normalization=true)
static Type maximum(const Type &a, const Type &b)
static double sqr(double x)
static bool equal(double x, double y, double threshold=0.001)
Implementation of a matrix and operations on matrices.
void stack(const vpMatrix &A)
This class defines the container for a plane geometrical structure.
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
double get_y() const
Get the point y coordinate in the image plane.
double get_x() const
Get the point x coordinate in the image plane.
Contains an M-estimator and various influence function.
@ TUKEY
Tukey influence function.
Implementation of a rotation matrix and operations on such kind of matrices.
Class that consider the case of a translation vector.