44 #include <visp/vpRobust.h>
45 #include <visp/vpHomogeneousMatrix.h>
46 #include <visp/vpHomography.h>
47 #include <visp/vpMath.h>
48 #include <visp/vpMatrix.h>
49 #include <visp/vpPoint.h>
50 #include <visp/vpPlane.h>
52 #include <visp/vpExponentialMap.h>
55 const double vpHomography::threshold_rotation = 1e-7;
56 const double vpHomography::threshold_displacement = 1e-18;
58 #ifndef DOXYGEN_SHOULD_SKIP_THIS
65 double sinu,cosi,mcosi,u[3], s;
69 s = sqrt(dx[0]*dx[0] + dx[1]*dx[1] + dx[2]*dx[2]);
73 for (i=0;i<3;i++) u[i] = dx[i]/s;
77 rd[0][0] = cosi + mcosi*u[0]*u[0];
78 rd[0][1] = -sinu*u[2] + mcosi*u[0]*u[1];
79 rd[0][2] = sinu*u[1] + mcosi*u[0]*u[2];
80 rd[1][0] = sinu*u[2] + mcosi*u[1]*u[0];
81 rd[1][1] = cosi + mcosi*u[1]*u[1];
82 rd[1][2] = -sinu*u[0] + mcosi*u[1]*u[2];
83 rd[2][0] = -sinu*u[1] + mcosi*u[2]*u[0];
84 rd[2][1] = sinu*u[0] + mcosi*u[2]*u[1];
85 rd[2][2] = cosi + mcosi*u[2]*u[2];
91 for (j=0;j<3;j++) rd[i][j] = 0.0;
100 mati = Delta.
inverse() * mati ;
104 vpHomography::computeRotation(
unsigned int nbpoint,
129 for (
unsigned int i=0 ; i < nbpoint ; i++) {
131 if ( (std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.)))
133 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.))) )
139 if ( (! only_1) && (! only_2) )
146 robust.setThreshold(0.0000) ;
158 for (
unsigned int i=0 ; i < 3 ; i++)
159 for (
unsigned int j=0 ; j < 3 ; j++)
160 c2Rc1[i][j] = c2Mc1[i][j] ;
164 for (
unsigned int i=0 ; i < nbpoint ; i++) {
166 if ( (std::fabs(c2P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c2P[i].get_x(), 1.)))
168 (std::fabs(c1P[i].get_x() + 1) > std::fabs(
vpMath::maximum(c1P[i].get_x(), 1.))) )
170 p2[0] = c2P[i].
get_x() ;
171 p2[1] = c2P[i].
get_y() ;
173 p1[0] = c1P[i].
get_x() ;
174 p1[1] = c1P[i].
get_y() ;
188 H2[0][0] = x*y ; H2[0][1] = -(1+x*x) ; H2[0][2] = y ;
189 H2[1][0] = 1+y*y ; H2[1][1] = -x*y ; H2[1][2] = -x ;
194 e2[0] = Hp2[0] - c1P[i].
get_x() ;
195 e2[1] = Hp2[1] - c1P[i].
get_y() ;
201 H1[0][0] = x*y ; H1[0][1] = -(1+x*x) ; H1[0][2] = y ;
202 H1[1][0] = 1+y*y ; H1[1][1] = -x*y ; H1[1][2] = -x ;
205 e1[0] = Hp1[0] - c2P[i].
get_x() ;
206 e1[1] = Hp1[1] - c2P[i].
get_y() ;
210 if (k == 0) { L = H2 ; e = e2 ; }
220 if (k == 0) { L = H1 ; e= e1 ; }
229 if (k == 0) {L = H2 ; e = e2 ; }
247 for (
unsigned int l=0 ; l < n ; l++)
255 for (
unsigned int l=0 ; l < n ; l++)
258 W[2*l+1][2*l+1] = w[l] ;
263 for (
unsigned int l=0 ; l < 2*n ; l++) W[l][l] = 1 ;
266 (L).pseudoInverse(Lp, 1e-6) ;
271 for (
unsigned int i=0 ; i < 3 ; i++) v[i+3] = c2rc1[i] ;
275 updatePoseRotation(c2rc1, c2Mc1) ;
278 if ((W*e).sumSquare() < 1e-10) break ;
285 return (W*e).sumSquare() ;
292 double A1 = cMo[0][0]*oN.
getA()+ cMo[0][1]*oN.
getB() + cMo[0][2]*oN.
getC();
293 double B1 = cMo[1][0]*oN.
getA()+ cMo[1][1]*oN.
getB() + cMo[1][2]*oN.
getC();
294 double C1 = cMo[2][0]*oN.
getA()+ cMo[2][1]*oN.
getB() + cMo[2][2]*oN.
getC();
295 double D1 = oN.
getD() - (cMo[0][3]*A1 + cMo[1][3]*B1 + cMo[2][3]*C1);
336 if ( (! only_1) && (! only_2) )
343 robust.setThreshold(0.0000) ;
352 while (
vpMath::equal(r_1,r,threshold_displacement) ==
false )
369 getPlaneInfo(oN, c1Mo, N1, d1) ;
370 getPlaneInfo(oN, c2Mo, N2, d2) ;
374 for (
unsigned int i=0 ; i < nbpoint ; i++)
376 p2[0] = c2P[i].
get_x() ;
377 p2[1] = c2P[i].
get_y() ;
379 p1[0] = c1P[i].
get_x() ;
380 p1[1] = c1P[i].
get_y() ;
397 Z1 = (N1[0]*x+N1[1]*y+N1[2])/d1 ;
400 H2[0][0] = -Z1 ; H2[0][1] = 0 ; H2[0][2] = x*Z1 ;
401 H2[1][0] = 0 ; H2[1][1] = -Z1 ; H2[1][2] = y*Z1 ;
402 H2[0][3] = x*y ; H2[0][4] = -(1+x*x) ; H2[0][5] = y ;
403 H2[1][3] = 1+y*y ; H2[1][4] = -x*y ; H2[1][5] = -x ;
409 for (
unsigned int k_=0 ; k_ < 3 ; k_++)
410 for (
unsigned int l=0 ; l<3 ; l++)
412 c1CFc2[k_][l] = c1Rc2[k_][l] ;
413 c1CFc2[k_+3][l+3] = c1Rc2[k_][l] ;
414 c1CFc2[k_][l+3] = sTR[k_][l] ;
420 e2[0] = Hp2[0] - c1P[i].
get_x() ;
421 e2[1] = Hp2[1] - c1P[i].
get_y() ;
426 Z1 = (N2[0]*x+N2[1]*y+N2[2])/d2 ;
428 H1[0][0] = -Z1 ; H1[0][1] = 0 ; H1[0][2] = x*Z1 ;
429 H1[1][0] = 0 ; H1[1][1] = -Z1 ; H1[1][2] = y*Z1;
430 H1[0][3] = x*y ; H1[0][4] = -(1+x*x) ; H1[0][5] = y ;
431 H1[1][3] = 1+y*y ; H1[1][4] = -x*y ; H1[1][5] = -x ;
434 e1[0] = Hp1[0] - c2P[i].
get_x() ;
435 e1[1] = Hp1[1] - c2P[i].
get_y() ;
439 if (k == 0) { L = H2 ; e = e2 ; }
449 if (k == 0) { L = H1 ; e= e1 ; }
458 if (k == 0) {L = H2 ; e = e2 ; }
475 for (
unsigned int l=0 ; l < n ; l++)
482 for (
unsigned int l=0 ; l < n ; l++)
485 W[2*l+1][2*l+1] = w[l] ;
490 for (
unsigned int l=0 ; l < 2*n ; l++) W[l][l] = 1 ;
492 (W*L).pseudoInverse(Lp, 1e-16) ;
502 r =(W*e).sumSquare() ;
504 if (r < 1e-15) {break ; }
505 if (iter>1000){break ; }
506 if (r>r_1) { break ; }
550 if ( (! only_1) && (! only_2) )
557 robust.setThreshold(0.0000) ;
566 while (
vpMath::equal(r_1,r,threshold_displacement) ==
false )
589 for (i=0 ; i < nbpoint ; i++)
591 getPlaneInfo(oN[i], c1Mo, N1, d1) ;
592 getPlaneInfo(oN[i], c2Mo, N2, d2) ;
593 p2[0] = c2P[i].
get_x() ;
594 p2[1] = c2P[i].
get_y() ;
596 p1[0] = c1P[i].
get_x() ;
597 p1[1] = c1P[i].
get_y() ;
614 Z1 = (N1[0]*x+N1[1]*y+N1[2])/d1 ;
617 H2[0][0] = -Z1 ; H2[0][1] = 0 ; H2[0][2] = x*Z1 ;
618 H2[1][0] = 0 ; H2[1][1] = -Z1 ; H2[1][2] = y*Z1 ;
619 H2[0][3] = x*y ; H2[0][4] = -(1+x*x) ; H2[0][5] = y ;
620 H2[1][3] = 1+y*y ; H2[1][4] = -x*y ; H2[1][5] = -x ;
626 for (
unsigned int k_=0 ; k_ < 3 ; k_++)
627 for (
unsigned int l=0 ; l<3 ; l++)
629 c1CFc2[k_][l] = c1Rc2[k_][l] ;
630 c1CFc2[k_+3][l+3] = c1Rc2[k_][l] ;
631 c1CFc2[k_][l+3] = sTR[k_][l] ;
637 e2[0] = Hp2[0] - c1P[i].
get_x() ;
638 e2[1] = Hp2[1] - c1P[i].
get_y() ;
643 Z1 = (N2[0]*x+N2[1]*y+N2[2])/d2 ;
645 H1[0][0] = -Z1 ; H1[0][1] = 0 ; H1[0][2] = x*Z1 ;
646 H1[1][0] = 0 ; H1[1][1] = -Z1 ; H1[1][2] = y*Z1;
647 H1[0][3] = x*y ; H1[0][4] = -(1+x*x) ; H1[0][5] = y ;
648 H1[1][3] = 1+y*y ; H1[1][4] = -x*y ; H1[1][5] = -x ;
651 e1[0] = Hp1[0] - c2P[i].
get_x() ;
652 e1[1] = Hp1[1] - c2P[i].
get_y() ;
657 if (k == 0) { L = H2 ; e = e2 ; }
667 if (k == 0) { L = H1 ; e= e1 ; }
676 if (k == 0) {L = H2 ; e = e2 ; }
693 for (
unsigned int k_=0 ; k_ < n ; k_++)
701 for (
unsigned int k_=0 ; k_ < n ; k_++)
703 W[2*k_][2*k_] = w[k_] ;
704 W[2*k_+1][2*k_+1] = w[k_] ;
709 for (
unsigned int k_=0 ; k_ < 2*n ; k_++) W[k_][k_] = 1 ;
711 (W*L).pseudoInverse(Lp, 1e-16) ;
721 r =(W*e).sumSquare() ;
725 if (r < 1e-15) {break ; }
726 if (iter>1000){break ; }
727 if (r>r_1) { break ; }
735 #endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS
Definition of the vpMatrix class.
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
static bool equal(double x, double y, double s=0.001)
double get_y() const
Get the point y coordinate in the image plane.
double sumSquare() const
return sum of the Aij^2 (for all i, for all j)
void computeDisplacement(vpRotationMatrix &aRb, vpTranslationVector &atb, vpColVector &n)
Class that defines what is a point.
static Type maximum(const Type &a, const Type &b)
The vpRotationMatrix considers the particular case of a rotation matrix.
void insert(const vpRotationMatrix &R)
static double sqr(double x)
vpRowVector t() const
transpose of Vector
void extract(vpRotationMatrix &R) const
double get_x() const
Get the point x coordinate in the image plane.
void stackMatrices(const vpMatrix &A)
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)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
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)