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>
46const double vpHomography::m_threshold_rotation = 1
e-7;
47const double vpHomography::m_threshold_displacement = 1
e-18;
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
54 const unsigned int val_3 = 3;
56 double s = sqrt((dx[0] * dx[0]) + (dx[1] * dx[1]) + (dx[2] * dx[2]));
60 for (
unsigned int i = 0;
i < val_3; ++
i) {
65 double mcosi = 1 - cosi;
66 rd[0][0] = cosi + (mcosi *
u[0] *
u[0]);
67 rd[0][1] = (-sinu *
u[2]) + (mcosi * u[0] * u[1]);
68 rd[0][2] = (sinu *
u[1]) + (mcosi * u[0] * u[2]);
69 rd[1][0] = (sinu *
u[2]) + (mcosi * u[1] * u[0]);
70 rd[1][1] = cosi + (mcosi *
u[1] *
u[1]);
71 rd[1][2] = (-sinu *
u[0]) + (mcosi * u[1] * u[2]);
72 rd[2][0] = (-sinu *
u[1]) + (mcosi * u[2] * u[0]);
73 rd[2][1] = (sinu *
u[0]) + (mcosi * u[2] * u[1]);
74 rd[2][2] = cosi + (mcosi *
u[2] *
u[2]);
77 for (
unsigned int i = 0;
i < val_3; ++
i) {
78 for (
unsigned int j = 0;
j < val_3; ++
j) {
110 const unsigned int val_3 = 3;
113 for (
unsigned int i = 0;
i < nbpoint; ++
i) {
115 if ((std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.))) &&
116 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.)))) {
120 if ((!only_1) && (!only_2)) {
128 robust.setMinMedianAbsoluteDeviation(0.00001);
129 vpMatrix W(2 * n, 2 * n);
131 vpMatrix c2Rc1(3, 3);
134 while ((
vpMath::equal(r_1, r, m_threshold_rotation) ==
false) && (stop ==
false)) {
140 for (
unsigned int i = 0;
i < val_3; ++
i) {
141 for (
unsigned int j = 0;
j < val_3; ++
j) {
142 c2Rc1[
i][
j] = c2Mc1[
i][
j];
146 vpMatrix L(2, 3), Lp;
148 for (
unsigned int i = 0;
i < nbpoint; ++
i) {
149 if ((std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.))) &&
150 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.)))) {
158 Hp2 = c2Rc1.t() * p2;
169 H2[0][1] = -(1 + (
x *
x));
171 H2[1][0] = 1 + (
y *
y);
178 e2[0] = Hp2[0] - c1P[
i].
get_x();
179 e2[1] = Hp2[1] - c1P[
i].
get_y();
186 H1[0][1] = -(1 + (
x *
x));
188 H1[1][0] = 1 + (
y *
y);
193 e1[0] = Hp1[0] - c2P[
i].
get_x();
194 e1[1] = Hp1[1] - c2P[
i].
get_y();
234 for (
unsigned int l = 0; l < n; ++l) {
240 for (
unsigned int l = 0; l < n; ++l) {
241 W[2 * l][2 * l] =
w[l];
242 W[(2 * l) + 1][(2 * l) + 1] =
w[l];
246 for (
unsigned int l = 0; l < (2 * n); ++l) {
250 L.pseudoInverse(Lp, 1e-6);
252 vpColVector c2rc1,
v(6);
254 c2rc1 = -2 * Lp * W *
e;
255 for (
unsigned int i = 0;
i < val_3; ++
i) {
261 updatePoseRotation(c2rc1, c2Mc1);
264 if (((W * e).sumSquare() < 1e-10) || (iter > 25)) {
270 return (W * e).sumSquare();
278 double D1 = oN.
getD() - ((
cMo[0][3] * A1) + (
cMo[1][3] * B1) + (
cMo[2][3] * C1));
313 robust.setMinMedianAbsoluteDeviation(0.00001);
314 vpMatrix W(2 * n, 2 * n);
317 vpColVector N1(3), N2(3);
324 while ((!
vpMath::equal(r_1, r, m_threshold_displacement)) && (stop ==
false)) {
329 vpHomogeneousMatrix c1Mc2, c2Mo;
330 vpRotationMatrix c1Rc2, c2Rc1;
331 vpTranslationVector c1Tc2, c2Tc1;
340 getPlaneInfo(oN, c1Mo, N1, d1);
341 getPlaneInfo(oN, c2Mo, N2, d2);
343 vpMatrix L(2, 3), Lp;
345 for (
unsigned int i = 0;
i < nbpoint; ++
i) {
355 Hp2 = (
static_cast<vpMatrix
>(c1Rc2) + ((c1Tc2 * N2.
t()) / d2)) * p2;
356 Hp1 = (
static_cast<vpMatrix
>(c2Rc1) + ((c2Tc1 * N1.
t()) / d1)) * p1;
366 Z1 = ((N1[0] *
x) + (N1[1] *
y) + N1[2]) / d1;
375 H2[0][4] = -(1 + (
x *
x));
377 H2[1][3] = 1 + (
y *
y);
382 vpMatrix c1CFc2(6, 6);
384 sTR = c1Tc2.
skew() * c1Rc2;
385 for (
unsigned int k_ = 0; k_ < 3; ++k_) {
386 for (
unsigned int l = 0; l < 3; ++l) {
387 c1CFc2[k_][l] = c1Rc2[k_][l];
388 c1CFc2[k_ + 3][l + 3] = c1Rc2[k_][l];
389 c1CFc2[k_][l + 3] = sTR[k_][l];
396 e2[0] = Hp2[0] - c1P[
i].
get_x();
397 e2[1] = Hp2[1] - c1P[
i].
get_y();
402 Z1 = ((N2[0] *
x) + (N2[1] *
y) + N2[2]) / d2;
411 H1[0][4] = -(1 + (
x *
x));
413 H1[1][3] = 1 + (
y *
y);
418 e1[0] = Hp1[0] - c2P[
i].
get_x();
419 e1[1] = Hp1[1] - c2P[
i].
get_y();
458 for (
unsigned int l = 0; l < n; ++l) {
464 for (
unsigned int l = 0; l < n; ++l) {
465 W[2 * l][2 * l] =
w[l];
466 W[(2 * l) + 1][(2 * l) + 1] =
w[l];
470 for (
unsigned int l = 0; l < (2 * n); ++l) {
474 (W * L).pseudoInverse(Lp, 1e-16);
478 c2Tcc1 = -1 * Lp * W *
e;
483 r = (W *
e).sumSquare();
485 if ((r < 1e-15) || (iter > 1000) || (r > r_1)) {
491 return (W * e).sumSquare();
522 robust.setMinMedianAbsoluteDeviation(0.00001);
523 vpMatrix W(2 * n, 2 * n);
526 vpColVector N1(3), N2(3);
533 while ((!
vpMath::equal(r_1, r, m_threshold_displacement)) && (stop ==
false)) {
538 vpHomogeneousMatrix c1Mc2, c2Mo;
539 vpRotationMatrix c1Rc2, c2Rc1;
540 vpTranslationVector c1Tc2, c2Tc1;
549 vpMatrix L(2, 3), Lp;
551 for (i = 0;
i < nbpoint; ++
i) {
552 getPlaneInfo(oN[i], c1Mo, N1, d1);
553 getPlaneInfo(oN[i], c2Mo, N2, d2);
563 Hp2 = (
static_cast<vpMatrix
>(c1Rc2) + ((c1Tc2 * N2.
t()) / d2)) * p2;
564 Hp1 = (
static_cast<vpMatrix
>(c2Rc1) + ((c2Tc1 * N1.
t()) / d1)) * p1;
574 Z1 = ((N1[0] *
x) + (N1[1] *
y) + N1[2]) / d1;
583 H2[0][4] = -(1 + (
x *
x));
585 H2[1][3] = 1 + (
y *
y);
590 vpMatrix c1CFc2(6, 6);
592 sTR = c1Tc2.
skew() *
static_cast<vpMatrix
>(c1Rc2);
593 for (
unsigned int k_ = 0; k_ < 3; ++k_) {
594 for (
unsigned int l = 0; l < 3; ++l) {
595 c1CFc2[k_][l] = c1Rc2[k_][l];
596 c1CFc2[k_ + 3][l + 3] = c1Rc2[k_][l];
597 c1CFc2[k_][l + 3] = sTR[k_][l];
604 e2[0] = Hp2[0] - c1P[
i].
get_x();
605 e2[1] = Hp2[1] - c1P[
i].
get_y();
610 Z1 = ((N2[0] *
x) + (N2[1] *
y) + N2[2]) / d2;
619 H1[0][4] = -(1 + (
x *
x));
621 H1[1][3] = 1 + (
y *
y);
626 e1[0] = Hp1[0] - c2P[
i].
get_x();
627 e1[1] = Hp1[1] - c2P[
i].
get_y();
666 for (
unsigned int k_ = 0; k_ < n; ++k_) {
672 for (
unsigned int k_ = 0; k_ < n; ++k_) {
673 W[2 * k_][2 * k_] =
w[k_];
674 W[(2 * k_) + 1][(2 * k_) + 1] =
w[k_];
678 for (
unsigned int k_ = 0; k_ < (2 * n); ++k_) {
682 (W * L).pseudoInverse(Lp, 1e-16);
686 c2Tcc1 = -1 * Lp * W *
e;
691 r = (W *
e).sumSquare();
693 if ((r < 1e-15) || (iter > 1000) || (r > r_1)) {
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)
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.
@ TUKEY
Tukey influence function.
Implementation of a rotation matrix and operations on such kind of matrices.