40 #include <visp3/core/vpRobust.h>
41 #include <visp3/core/vpHomogeneousMatrix.h>
42 #include <visp3/vision/vpHomography.h>
43 #include <visp3/core/vpMath.h>
44 #include <visp3/core/vpMatrix.h>
45 #include <visp3/core/vpPoint.h>
46 #include <visp3/core/vpPlane.h>
48 #include <visp3/core/vpExponentialMap.h>
51 const double vpHomography::threshold_rotation = 1e-7;
52 const double vpHomography::threshold_displacement = 1e-18;
54 #ifndef DOXYGEN_SHOULD_SKIP_THIS
61 double s = sqrt(dx[0]*dx[0] + dx[1]*dx[1] + dx[2]*dx[2]);
66 for (
unsigned int i=0;i<3;i++) u[i] = dx[i]/s;
69 double mcosi = 1-cosi;
70 rd[0][0] = cosi + mcosi*u[0]*u[0];
71 rd[0][1] = -sinu*u[2] + mcosi*u[0]*u[1];
72 rd[0][2] = sinu*u[1] + mcosi*u[0]*u[2];
73 rd[1][0] = sinu*u[2] + mcosi*u[1]*u[0];
74 rd[1][1] = cosi + mcosi*u[1]*u[1];
75 rd[1][2] = -sinu*u[0] + mcosi*u[1]*u[2];
76 rd[2][0] = -sinu*u[1] + mcosi*u[2]*u[0];
77 rd[2][1] = sinu*u[0] + mcosi*u[2]*u[1];
78 rd[2][2] = cosi + mcosi*u[2]*u[2];
82 for (
unsigned int i=0;i<3;i++)
84 for (
unsigned int j=0;j<3;j++) rd[i][j] = 0.0;
96 vpHomography::computeRotation(
unsigned int nbpoint,
121 for (
unsigned int i=0 ; i < nbpoint ; i++) {
123 if ( (std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.)))
125 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.))) )
130 if ( (! only_1) && (! only_2) )
137 robust.setThreshold(0.0000) ;
149 for (
unsigned int i=0 ; i < 3 ; i++)
150 for (
unsigned int j=0 ; j < 3 ; j++)
151 c2Rc1[i][j] = c2Mc1[i][j] ;
155 for (
unsigned int i=0 ; i < nbpoint ; i++) {
157 if ( (std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.)))
159 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.))) )
161 p2[0] = c2P[i].
get_x() ;
162 p2[1] = c2P[i].
get_y() ;
164 p1[0] = c1P[i].
get_x() ;
165 p1[1] = c1P[i].
get_y() ;
179 H2[0][0] = x*y ; H2[0][1] = -(1+x*x) ; H2[0][2] = y ;
180 H2[1][0] = 1+y*y ; H2[1][1] = -x*y ; H2[1][2] = -x ;
185 e2[0] = Hp2[0] - c1P[i].
get_x() ;
186 e2[1] = Hp2[1] - c1P[i].
get_y() ;
192 H1[0][0] = x*y ; H1[0][1] = -(1+x*x) ; H1[0][2] = y ;
193 H1[1][0] = 1+y*y ; H1[1][1] = -x*y ; H1[1][2] = -x ;
196 e1[0] = Hp1[0] - c2P[i].
get_x() ;
197 e1[1] = Hp1[1] - c2P[i].
get_y() ;
201 if (k == 0) { L = H2 ; e = e2 ; }
211 if (k == 0) { L = H1 ; e= e1 ; }
220 if (k == 0) {L = H2 ; e = e2 ; }
238 for (
unsigned int l=0 ; l < n ; l++)
246 for (
unsigned int l=0 ; l < n ; l++)
249 W[2*l+1][2*l+1] = w[l] ;
254 for (
unsigned int l=0 ; l < 2*n ; l++) W[l][l] = 1 ;
257 (L).pseudoInverse(Lp, 1e-6) ;
262 for (
unsigned int i=0 ; i < 3 ; i++) v[i+3] = c2rc1[i] ;
266 updatePoseRotation(c2rc1, c2Mc1) ;
269 if ((W*e).sumSquare() < 1e-10) break ;
276 return (W*e).sumSquare() ;
283 double A1 = cMo[0][0]*oN.
getA()+ cMo[0][1]*oN.
getB() + cMo[0][2]*oN.
getC();
284 double B1 = cMo[1][0]*oN.
getA()+ cMo[1][1]*oN.
getB() + cMo[1][2]*oN.
getC();
285 double C1 = cMo[2][0]*oN.
getA()+ cMo[2][1]*oN.
getB() + cMo[2][2]*oN.
getC();
286 double D1 = oN.
getD() - (cMo[0][3]*A1 + cMo[1][3]*B1 + cMo[2][3]*C1);
332 robust.setThreshold(0.0000) ;
341 while (
vpMath::equal(r_1,r,threshold_displacement) ==
false )
358 getPlaneInfo(oN, c1Mo, N1, d1) ;
359 getPlaneInfo(oN, c2Mo, N2, d2) ;
363 for (
unsigned int i=0 ; i < nbpoint ; i++)
365 p2[0] = c2P[i].
get_x() ;
366 p2[1] = c2P[i].
get_y() ;
368 p1[0] = c1P[i].
get_x() ;
369 p1[1] = c1P[i].
get_y() ;
374 Hp2 = ((
vpMatrix)c1Rc2 + (c1Tc2*N2.
t())/d2)*p2 ;
375 Hp1 = ((
vpMatrix)c2Rc1 + (c2Tc1*N1.
t())/d1)*p1 ;
386 Z1 = (N1[0]*x+N1[1]*y+N1[2])/d1 ;
389 H2[0][0] = -Z1 ; H2[0][1] = 0 ; H2[0][2] = x*Z1 ;
390 H2[1][0] = 0 ; H2[1][1] = -Z1 ; H2[1][2] = y*Z1 ;
391 H2[0][3] = x*y ; H2[0][4] = -(1+x*x) ; H2[0][5] = y ;
392 H2[1][3] = 1+y*y ; H2[1][4] = -x*y ; H2[1][5] = -x ;
398 for (
unsigned int k_=0 ; k_ < 3 ; k_++)
399 for (
unsigned int l=0 ; l<3 ; l++)
401 c1CFc2[k_][l] = c1Rc2[k_][l] ;
402 c1CFc2[k_+3][l+3] = c1Rc2[k_][l] ;
403 c1CFc2[k_][l+3] = sTR[k_][l] ;
409 e2[0] = Hp2[0] - c1P[i].
get_x() ;
410 e2[1] = Hp2[1] - c1P[i].
get_y() ;
415 Z1 = (N2[0]*x+N2[1]*y+N2[2])/d2 ;
417 H1[0][0] = -Z1 ; H1[0][1] = 0 ; H1[0][2] = x*Z1 ;
418 H1[1][0] = 0 ; H1[1][1] = -Z1 ; H1[1][2] = y*Z1;
419 H1[0][3] = x*y ; H1[0][4] = -(1+x*x) ; H1[0][5] = y ;
420 H1[1][3] = 1+y*y ; H1[1][4] = -x*y ; H1[1][5] = -x ;
423 e1[0] = Hp1[0] - c2P[i].
get_x() ;
424 e1[1] = Hp1[1] - c2P[i].
get_y() ;
428 if (k == 0) { L = H2 ; e = e2 ; }
438 if (k == 0) { L = H1 ; e= e1 ; }
447 if (k == 0) {L = H2 ; e = e2 ; }
464 for (
unsigned int l=0 ; l < n ; l++)
471 for (
unsigned int l=0 ; l < n ; l++)
474 W[2*l+1][2*l+1] = w[l] ;
479 for (
unsigned int l=0 ; l < 2*n ; l++) W[l][l] = 1 ;
481 (W*L).pseudoInverse(Lp, 1e-16) ;
491 r =(W*e).sumSquare() ;
493 if (r < 1e-15) {break ; }
494 if (iter>1000){break ; }
495 if (r>r_1) { break ; }
499 return (W*e).sumSquare() ;
544 robust.setThreshold(0.0000) ;
553 while (
vpMath::equal(r_1,r,threshold_displacement) ==
false )
572 for (i=0 ; i < nbpoint ; i++)
574 getPlaneInfo(oN[i], c1Mo, N1, d1) ;
575 getPlaneInfo(oN[i], c2Mo, N2, d2) ;
576 p2[0] = c2P[i].
get_x() ;
577 p2[1] = c2P[i].
get_y() ;
579 p1[0] = c1P[i].
get_x() ;
580 p1[1] = c1P[i].
get_y() ;
585 Hp2 = ((
vpMatrix)c1Rc2 + (c1Tc2*N2.
t())/d2)*p2 ;
586 Hp1 = ((
vpMatrix)c2Rc1 + (c2Tc1*N1.
t())/d1)*p1 ;
596 Z1 = (N1[0]*x+N1[1]*y+N1[2])/d1 ;
598 H2[0][0] = -Z1 ; H2[0][1] = 0 ; H2[0][2] = x*Z1 ;
599 H2[1][0] = 0 ; H2[1][1] = -Z1 ; H2[1][2] = y*Z1 ;
600 H2[0][3] = x*y ; H2[0][4] = -(1+x*x) ; H2[0][5] = y ;
601 H2[1][3] = 1+y*y ; H2[1][4] = -x*y ; H2[1][5] = -x ;
607 for (
unsigned int k_=0 ; k_ < 3 ; k_++)
608 for (
unsigned int l=0 ; l<3 ; l++)
610 c1CFc2[k_][l] = c1Rc2[k_][l] ;
611 c1CFc2[k_+3][l+3] = c1Rc2[k_][l] ;
612 c1CFc2[k_][l+3] = sTR[k_][l] ;
618 e2[0] = Hp2[0] - c1P[i].
get_x() ;
619 e2[1] = Hp2[1] - c1P[i].
get_y() ;
624 Z1 = (N2[0]*x+N2[1]*y+N2[2])/d2 ;
626 H1[0][0] = -Z1 ; H1[0][1] = 0 ; H1[0][2] = x*Z1 ;
627 H1[1][0] = 0 ; H1[1][1] = -Z1 ; H1[1][2] = y*Z1;
628 H1[0][3] = x*y ; H1[0][4] = -(1+x*x) ; H1[0][5] = y ;
629 H1[1][3] = 1+y*y ; H1[1][4] = -x*y ; H1[1][5] = -x ;
632 e1[0] = Hp1[0] - c2P[i].
get_x() ;
633 e1[1] = Hp1[1] - c2P[i].
get_y() ;
638 if (k == 0) { L = H2 ; e = e2 ; }
648 if (k == 0) { L = H1 ; e= e1 ; }
657 if (k == 0) {L = H2 ; e = e2 ; }
674 for (
unsigned int k_=0 ; k_ < n ; k_++)
682 for (
unsigned int k_=0 ; k_ < n ; k_++)
684 W[2*k_][2*k_] = w[k_] ;
685 W[2*k_+1][2*k_+1] = w[k_] ;
690 for (
unsigned int k_=0 ; k_ < 2*n ; k_++) W[k_][k_] = 1 ;
692 (W*L).pseudoInverse(Lp, 1e-16) ;
702 r =(W*e).sumSquare() ;
705 if (r < 1e-15) {break ; }
706 if (iter>1000){break ; }
707 if (r>r_1) { break ; }
711 return (W*e).sumSquare() ;
715 #endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS
Implementation of a matrix and operations on matrices.
void stack(const double &d)
Implementation of an homogeneous matrix and operations on such kind of matrices.
static bool equal(double x, double y, double s=0.001)
void stack(const vpMatrix &A)
double get_y() const
Get the point y coordinate in the image plane.
void computeDisplacement(vpRotationMatrix &aRb, vpTranslationVector &atb, vpColVector &n)
Class that defines what is a point.
static Type maximum(const Type &a, const Type &b)
Implementation of a rotation matrix and operations on such kind of matrices.
void insert(const vpRotationMatrix &R)
static double sqr(double x)
void extract(vpRotationMatrix &R) const
double get_x() const
Get the point x coordinate in the image plane.
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 > &inlier, double &residual, double weights_threshold=0.4, unsigned int niter=4, bool normalization=true)
Implementation of column vector and the associated operations.
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix direct(const vpColVector &v)
Contains an M-Estimator and various influence function.
This class defines the container for a plane geometrical structure.
Class that consider the case of a translation vector.
void resize(const unsigned int i, const bool flagNullify=true)