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 sinu,cosi,mcosi,u[3], s;
65 s = sqrt(dx[0]*dx[0] + dx[1]*dx[1] + dx[2]*dx[2]);
69 for (i=0;i<3;i++) u[i] = dx[i]/s;
73 rd[0][0] = cosi + mcosi*u[0]*u[0];
74 rd[0][1] = -sinu*u[2] + mcosi*u[0]*u[1];
75 rd[0][2] = sinu*u[1] + mcosi*u[0]*u[2];
76 rd[1][0] = sinu*u[2] + mcosi*u[1]*u[0];
77 rd[1][1] = cosi + mcosi*u[1]*u[1];
78 rd[1][2] = -sinu*u[0] + mcosi*u[1]*u[2];
79 rd[2][0] = -sinu*u[1] + mcosi*u[2]*u[0];
80 rd[2][1] = sinu*u[0] + mcosi*u[2]*u[1];
81 rd[2][2] = cosi + mcosi*u[2]*u[2];
87 for (j=0;j<3;j++) rd[i][j] = 0.0;
100 vpHomography::computeRotation(
unsigned int nbpoint,
125 for (
unsigned int i=0 ; i < nbpoint ; i++) {
127 if ( (std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.)))
129 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.))) )
135 if ( (! only_1) && (! only_2) )
142 robust.setThreshold(0.0000) ;
154 for (
unsigned int i=0 ; i < 3 ; i++)
155 for (
unsigned int j=0 ; j < 3 ; j++)
156 c2Rc1[i][j] = c2Mc1[i][j] ;
160 for (
unsigned int i=0 ; i < nbpoint ; i++) {
162 if ( (std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.)))
164 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.))) )
166 p2[0] = c2P[i].
get_x() ;
167 p2[1] = c2P[i].
get_y() ;
169 p1[0] = c1P[i].
get_x() ;
170 p1[1] = c1P[i].
get_y() ;
184 H2[0][0] = x*y ; H2[0][1] = -(1+x*x) ; H2[0][2] = y ;
185 H2[1][0] = 1+y*y ; H2[1][1] = -x*y ; H2[1][2] = -x ;
190 e2[0] = Hp2[0] - c1P[i].
get_x() ;
191 e2[1] = Hp2[1] - c1P[i].
get_y() ;
197 H1[0][0] = x*y ; H1[0][1] = -(1+x*x) ; H1[0][2] = y ;
198 H1[1][0] = 1+y*y ; H1[1][1] = -x*y ; H1[1][2] = -x ;
201 e1[0] = Hp1[0] - c2P[i].
get_x() ;
202 e1[1] = Hp1[1] - c2P[i].
get_y() ;
206 if (k == 0) { L = H2 ; e = e2 ; }
216 if (k == 0) { L = H1 ; e= e1 ; }
225 if (k == 0) {L = H2 ; e = e2 ; }
243 for (
unsigned int l=0 ; l < n ; l++)
251 for (
unsigned int l=0 ; l < n ; l++)
254 W[2*l+1][2*l+1] = w[l] ;
259 for (
unsigned int l=0 ; l < 2*n ; l++) W[l][l] = 1 ;
262 (L).pseudoInverse(Lp, 1e-6) ;
267 for (
unsigned int i=0 ; i < 3 ; i++) v[i+3] = c2rc1[i] ;
271 updatePoseRotation(c2rc1, c2Mc1) ;
274 if ((W*e).sumSquare() < 1e-10) break ;
281 return (W*e).sumSquare() ;
288 double A1 = cMo[0][0]*oN.
getA()+ cMo[0][1]*oN.
getB() + cMo[0][2]*oN.
getC();
289 double B1 = cMo[1][0]*oN.
getA()+ cMo[1][1]*oN.
getB() + cMo[1][2]*oN.
getC();
290 double C1 = cMo[2][0]*oN.
getA()+ cMo[2][1]*oN.
getB() + cMo[2][2]*oN.
getC();
291 double D1 = oN.
getD() - (cMo[0][3]*A1 + cMo[1][3]*B1 + cMo[2][3]*C1);
340 robust.setThreshold(0.0000) ;
349 while (
vpMath::equal(r_1,r,threshold_displacement) ==
false )
366 getPlaneInfo(oN, c1Mo, N1, d1) ;
367 getPlaneInfo(oN, c2Mo, N2, d2) ;
371 for (
unsigned int i=0 ; i < nbpoint ; i++)
373 p2[0] = c2P[i].
get_x() ;
374 p2[1] = c2P[i].
get_y() ;
376 p1[0] = c1P[i].
get_x() ;
377 p1[1] = c1P[i].
get_y() ;
382 Hp2 = ((
vpMatrix)c1Rc2 + (c1Tc2*N2.
t())/d2)*p2 ;
383 Hp1 = ((
vpMatrix)c2Rc1 + (c2Tc1*N1.
t())/d1)*p1 ;
394 Z1 = (N1[0]*x+N1[1]*y+N1[2])/d1 ;
397 H2[0][0] = -Z1 ; H2[0][1] = 0 ; H2[0][2] = x*Z1 ;
398 H2[1][0] = 0 ; H2[1][1] = -Z1 ; H2[1][2] = y*Z1 ;
399 H2[0][3] = x*y ; H2[0][4] = -(1+x*x) ; H2[0][5] = y ;
400 H2[1][3] = 1+y*y ; H2[1][4] = -x*y ; H2[1][5] = -x ;
406 for (
unsigned int k_=0 ; k_ < 3 ; k_++)
407 for (
unsigned int l=0 ; l<3 ; l++)
409 c1CFc2[k_][l] = c1Rc2[k_][l] ;
410 c1CFc2[k_+3][l+3] = c1Rc2[k_][l] ;
411 c1CFc2[k_][l+3] = sTR[k_][l] ;
417 e2[0] = Hp2[0] - c1P[i].
get_x() ;
418 e2[1] = Hp2[1] - c1P[i].
get_y() ;
423 Z1 = (N2[0]*x+N2[1]*y+N2[2])/d2 ;
425 H1[0][0] = -Z1 ; H1[0][1] = 0 ; H1[0][2] = x*Z1 ;
426 H1[1][0] = 0 ; H1[1][1] = -Z1 ; H1[1][2] = y*Z1;
427 H1[0][3] = x*y ; H1[0][4] = -(1+x*x) ; H1[0][5] = y ;
428 H1[1][3] = 1+y*y ; H1[1][4] = -x*y ; H1[1][5] = -x ;
431 e1[0] = Hp1[0] - c2P[i].
get_x() ;
432 e1[1] = Hp1[1] - c2P[i].
get_y() ;
436 if (k == 0) { L = H2 ; e = e2 ; }
446 if (k == 0) { L = H1 ; e= e1 ; }
455 if (k == 0) {L = H2 ; e = e2 ; }
472 for (
unsigned int l=0 ; l < n ; l++)
479 for (
unsigned int l=0 ; l < n ; l++)
482 W[2*l+1][2*l+1] = w[l] ;
487 for (
unsigned int l=0 ; l < 2*n ; l++) W[l][l] = 1 ;
489 (W*L).pseudoInverse(Lp, 1e-16) ;
499 r =(W*e).sumSquare() ;
501 if (r < 1e-15) {break ; }
502 if (iter>1000){break ; }
503 if (r>r_1) { break ; }
507 return (W*e).sumSquare() ;
555 robust.setThreshold(0.0000) ;
564 while (
vpMath::equal(r_1,r,threshold_displacement) ==
false )
587 for (i=0 ; i < nbpoint ; i++)
589 getPlaneInfo(oN[i], c1Mo, N1, d1) ;
590 getPlaneInfo(oN[i], c2Mo, N2, d2) ;
591 p2[0] = c2P[i].
get_x() ;
592 p2[1] = c2P[i].
get_y() ;
594 p1[0] = c1P[i].
get_x() ;
595 p1[1] = c1P[i].
get_y() ;
600 Hp2 = ((
vpMatrix)c1Rc2 + (c1Tc2*N2.
t())/d2)*p2 ;
601 Hp1 = ((
vpMatrix)c2Rc1 + (c2Tc1*N1.
t())/d1)*p1 ;
612 Z1 = (N1[0]*x+N1[1]*y+N1[2])/d1 ;
615 H2[0][0] = -Z1 ; H2[0][1] = 0 ; H2[0][2] = x*Z1 ;
616 H2[1][0] = 0 ; H2[1][1] = -Z1 ; H2[1][2] = y*Z1 ;
617 H2[0][3] = x*y ; H2[0][4] = -(1+x*x) ; H2[0][5] = y ;
618 H2[1][3] = 1+y*y ; H2[1][4] = -x*y ; H2[1][5] = -x ;
624 for (
unsigned int k_=0 ; k_ < 3 ; k_++)
625 for (
unsigned int l=0 ; l<3 ; l++)
627 c1CFc2[k_][l] = c1Rc2[k_][l] ;
628 c1CFc2[k_+3][l+3] = c1Rc2[k_][l] ;
629 c1CFc2[k_][l+3] = sTR[k_][l] ;
635 e2[0] = Hp2[0] - c1P[i].
get_x() ;
636 e2[1] = Hp2[1] - c1P[i].
get_y() ;
641 Z1 = (N2[0]*x+N2[1]*y+N2[2])/d2 ;
643 H1[0][0] = -Z1 ; H1[0][1] = 0 ; H1[0][2] = x*Z1 ;
644 H1[1][0] = 0 ; H1[1][1] = -Z1 ; H1[1][2] = y*Z1;
645 H1[0][3] = x*y ; H1[0][4] = -(1+x*x) ; H1[0][5] = y ;
646 H1[1][3] = 1+y*y ; H1[1][4] = -x*y ; H1[1][5] = -x ;
649 e1[0] = Hp1[0] - c2P[i].
get_x() ;
650 e1[1] = Hp1[1] - c2P[i].
get_y() ;
655 if (k == 0) { L = H2 ; e = e2 ; }
665 if (k == 0) { L = H1 ; e= e1 ; }
674 if (k == 0) {L = H2 ; e = e2 ; }
691 for (
unsigned int k_=0 ; k_ < n ; k_++)
699 for (
unsigned int k_=0 ; k_ < n ; k_++)
701 W[2*k_][2*k_] = w[k_] ;
702 W[2*k_+1][2*k_+1] = w[k_] ;
707 for (
unsigned int k_=0 ; k_ < 2*n ; k_++) W[k_][k_] = 1 ;
709 (W*L).pseudoInverse(Lp, 1e-16) ;
719 r =(W*e).sumSquare() ;
723 if (r < 1e-15) {break ; }
724 if (iter>1000){break ; }
725 if (r>r_1) { break ; }
729 return (W*e).sumSquare() ;
733 #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)