55 #include <visp/vpHomography.h>
56 #include <visp/vpDebug.h>
57 #include <visp/vpMatrixException.h>
62 #ifndef DOXYGEN_SHOULD_SKIP_THIS
63 const double eps = 1e-6 ;
94 void changeFrame(
unsigned int *pts_ref,
99 void HLM2D(
unsigned int nb_pts,
103 void HLM3D(
unsigned int nb_pts,
107 void HLM(
unsigned int q_cible,
109 double *xm,
double *ym,
110 double *xmi,
double *ymi,
113 void HLM(
unsigned int q_cible,
114 const std::vector<double> &xm,
const std::vector<double> &ym,
115 const std::vector<double> &xmi,
const std::vector<double> &ymi,
118 void changeFrame(
unsigned int *pts_ref,
124 unsigned int i,j, k ;
125 unsigned int cont_pts;
127 double lamb_cour[3] ;
137 M[j][i] = p[pts_ref[i]][j] ;
138 Md[j][i] = pd[pts_ref[i]][j] ;
146 if (pts_ref[3] > 0) {
149 lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
150 lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
156 M[i][j] = M[i][j]*lamb_cour[j] ;
157 Md[i][j] = Md[i][j]*lamb_des[j] ;
169 for (k=0;k<nb_pts;k++) {
170 if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
172 pn[cont_pts][i] = 0.0 ;
173 pnd[cont_pts][i] = 0.0 ;
175 pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j]*p[k][j] ;
176 pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j]*pd[k][j] ;
179 cont_pts = cont_pts + 1;
215 HLM2D(
unsigned int nb_pts,
223 unsigned int contZeros, vect;
231 for (j=0; j<nb_pts ;j++) {
235 M[3*j][3] = -points_des[j][0]*points_cour[j][2] ;
236 M[3*j][4] = -points_des[j][1]*points_cour[j][2] ;
237 M[3*j][5] = -points_des[j][2]*points_cour[j][2] ;
238 M[3*j][6] = points_des[j][0]*points_cour[j][1] ;
239 M[3*j][7] = points_des[j][1]*points_cour[j][1] ;
240 M[3*j][8] = points_des[j][2]*points_cour[j][1] ;
242 M[3*j+1][0] = points_des[j][0]*points_cour[j][2] ;
243 M[3*j+1][1] = points_des[j][1]*points_cour[j][2] ;
244 M[3*j+1][2] = points_des[j][2]*points_cour[j][2] ;
248 M[3*j+1][6] = -points_des[j][0]*points_cour[j][0] ;
249 M[3*j+1][7] = -points_des[j][1]*points_cour[j][0] ;
250 M[3*j+1][8] = -points_des[j][2]*points_cour[j][0] ;
252 M[3*j+2][0] = -points_des[j][0]*points_cour[j][1] ;
253 M[3*j+2][1] = -points_des[j][1]*points_cour[j][1] ;
254 M[3*j+2][2] = -points_des[j][2]*points_cour[j][1] ;
255 M[3*j+2][3] = points_des[j][0]*points_cour[j][0] ;
256 M[3*j+2][4] = points_des[j][1]*points_cour[j][0] ;
257 M[3*j+2][5] = points_des[j][2]*points_cour[j][0] ;
274 vals_inf = fabs(sv[0]) ;
277 if (fabs(sv[0]) < eps) {
278 contZeros = contZeros + 1 ;
280 for (j=1; j<9; j++) {
281 if (fabs(sv[j]) < vals_inf) {
282 vals_inf = fabs(sv[j]);
285 if (fabs(sv[j]) < eps) {
286 contZeros = contZeros + 1 ;
295 "matrix is rank deficient"));
300 for (i=0; i<3; i++) {
302 H[i][j] = V[3*i+j][vect];
334 HLM3D(
unsigned int nb_pts,
339 unsigned int i,j,k,ii,jj ;
340 unsigned int cont_pts;
343 unsigned int pts_ref[4];
385 changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
388 cont_pts = nb_pts - 3 ;
394 "Not enough point to compute the homography"));
404 for (i=0;i<nc;i++)
for (j=0;j<nc;j++) CtC[i][j] = 0.0;
421 for (i=0 ; i<nb_pts-5; i++) {
422 for (j = i+1 ; j<nb_pts-4; j++) {
423 for (k = j+1 ; k<nb_pts-3; k ++) {
425 C[0] = pn[i][2]*pn[j][2]*pn[k][1]*pnd[k][0]
426 * (pnd[j][0]*pnd[i][1] - pnd[j][1]*pnd[i][0])
427 + pn[i][2]*pn[k][2]*pn[j][1]*pnd[j][0]
428 *(pnd[i][0]*pnd[k][1] - pnd[i][1]*pnd[k][0])
429 + pn[j][2]*pn[k][2]*pn[i][1]*pnd[i][0]
430 *(pnd[k][0]*pnd[j][1] - pnd[k][1]*pnd[j][0]) ;
432 C[1] = pn[i][2]*pn[j][2]*pn[k][0]*pnd[k][1]
433 *(pnd[i][0]*pnd[j][1] - pnd[i][1]*pnd[j][0])
434 + pn[i][2]*pn[k][2]*pn[j][0]*pnd[j][1]
435 *(pnd[k][0]*pnd[i][1] - pnd[k][1]*pnd[i][0])
436 + pn[j][2]*pn[k][2]*pn[i][0]*pnd[i][1]
437 *(pnd[j][0]*pnd[k][1] - pnd[j][1]*pnd[k][0]) ;
439 C[2] = + pn[i][1]*pn[k][1]*pn[j][2]*pnd[j][0]
440 *(pnd[k][2]*pnd[i][0] - pnd[k][0]*pnd[i][2])
441 +pn[i][1]*pn[j][1]*pn[k][2]*pnd[k][0]
442 *(pnd[i][2]*pnd[j][0] - pnd[i][0]*pnd[j][2])
443 + pn[j][1]*pn[k][1]*pn[i][2]*pnd[i][0]
444 *(pnd[j][2]*pnd[k][0] - pnd[j][0]*pnd[k][2]) ;
449 C[3] = pn[i][0]*pn[j][0]*pn[k][2]*pnd[k][1]
450 *(pnd[i][2]*pnd[j][1] - pnd[i][1]*pnd[j][2])
451 + pn[i][0]*pn[k][0]*pn[j][2]*pnd[j][1]
452 *(pnd[k][2]*pnd[i][1] - pnd[k][1]*pnd[i][2])
453 + pn[j][0]*pn[k][0]*pn[i][2]*pnd[i][1]
454 *(pnd[j][2]*pnd[k][1] - pnd[j][1]*pnd[k][2]) ;
457 C[5] = pn[i][1]*pn[j][1]*pn[k][0]*pnd[k][2]
458 *(pnd[i][0]*pnd[j][2] - pnd[i][2]*pnd[j][0])
459 + pn[i][1]*pn[k][1]*pn[j][0]*pnd[j][2]
460 *(pnd[k][0]*pnd[i][2] - pnd[k][2]*pnd[i][0])
461 + pn[j][1]*pn[k][1]*pn[i][0]*pnd[i][2]
462 *(pnd[j][0]*pnd[k][2] - pnd[j][2]*pnd[k][0]) ;
464 C[6] = pn[i][0]*pn[j][0]*pn[k][1]*pnd[k][2]
465 *(pnd[i][1]*pnd[j][2] - pnd[i][2]*pnd[j][1])
466 + pn[i][0]*pn[k][0]*pn[j][1]*pnd[j][2]
467 *(pnd[k][1]*pnd[i][2] - pnd[k][2]*pnd[i][1])
468 + pn[j][0]*pn[k][0]*pn[i][1]*pnd[i][2]
469 *(pnd[j][1]*pnd[k][2] - pnd[j][2]*pnd[k][1]) ;
471 C[4] = pn[i][0]*pn[k][1]*pn[j][2]
472 *(pnd[k][0]*pnd[j][1]*pnd[i][2] - pnd[j][0]*pnd[i][1]*pnd[k][2])
473 + pn[k][0]*pn[i][1]*pn[j][2]
474 *(pnd[j][0]*pnd[k][1]*pnd[i][2] - pnd[i][0]*pnd[j][1]*pnd[k][2])
475 + pn[i][0]*pn[j][1]*pn[k][2]
476 *(pnd[k][0]*pnd[i][1]*pnd[j][2] - pnd[j][0]*pnd[k][1]*pnd[i][2])
477 + pn[j][0]*pn[i][1]*pn[k][2]
478 *(pnd[i][0]*pnd[k][1]*pnd[j][2] - pnd[k][0]*pnd[j][1]*pnd[i][2])
479 + pn[k][0]*pn[j][1]*pn[i][2]
480 *(pnd[j][0]*pnd[i][1]*pnd[k][2] - pnd[i][0]*pnd[k][1]*pnd[j][2])
481 + pn[j][0]*pn[k][1]*pn[i][2]
482 *(pnd[i][0]*pnd[j][1]*pnd[k][2] - pnd[k][0]*pnd[i][1]*pnd[j][2]) ;
486 for (ii=0;ii<nc;ii++) {
487 for (jj=ii;jj<nc;jj++) {
488 CtC[ii][jj] = CtC[ii][jj] + C[ii]*C[jj];
499 for (i=0; i<nc ;i++) {
500 for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
528 for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
533 for (i=1; i < nc ;i++) {
534 if (svSorted[i-1] > svSorted[i]) {
535 v_temp = svSorted[i-1] ;
536 svSorted[i-1] = svSorted[i] ;
537 svSorted[i] = v_temp ;
550 vect = 0 ; cont_zeros = 0 ; cont = 0 ;
551 for (j=0; j < nc; j++) {
553 if (std::fabs(sv[j]-svSorted[cont]) <= std::fabs(
vpMath::maximum(sv[j],svSorted[cont]))) vect = j ;
554 if (std::fabs(sv[j]/svSorted[nc-1]) < eps) cont_zeros = cont_zeros + 1 ;
557 if (cont_zeros > 5) {
559 HLM2D(nb_pts,pd,p,H);
582 c[0][0] = V[5][vect] ; c[0][1] = 0.0 ;
583 c[1][0] = V[6][vect] ; c[1][1] = 0.0 ;
584 c[2][0] = V[3][vect] ; c[2][1] = 0.0 ;
585 c[3][0] = V[4][vect] ; c[3][1] = 0.0
587 c[4][0] = 0.0 ; c[4][1] = V[6][vect] ;
588 c[5][0] = 0.0 ; c[5][1] = V[5][vect] ;
589 c[6][0] = 0.0 ; c[6][1] = V[2][vect] ;
590 c[7][0] = 0.0 ; c[7][1] = V[4][vect] ;
595 cp = c.pseudoInverse(1e-6) ;
602 H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
606 T[0][0] = -V[1][vect] ; T[0][1] = V[0][vect] ;
607 T[1][0] = V[4][vect] ; T[1][2] = -V[2][vect] ;
608 T[2][0] = -V[6][vect] ; T[2][1] = V[2][vect] ;
609 T[3][0] = V[6][vect] ; T[3][2] = -V[0][vect] ;
610 T[4][0] = -V[3][vect] ; T[4][1] = V[6][vect] ;
611 T[5][0] = V[3][vect] ; T[5][2] = -V[1][vect] ;
612 T[6][0] = -V[5][vect] ; T[6][1] = V[4][vect] ;
613 T[7][0] = V[5][vect] ; T[7][2] = -V[6][vect] ;
614 T[8][1] = -V[5][vect] ; T[8][2] = V[2][vect] ;
618 for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
628 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
668 HLM(
unsigned int q_cible,
670 double *xm,
double *ym,
671 double *xmi,
double *ymi,
683 for (i=0;i<nbpt;i++) {
714 #endif // #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
717 HLM(
unsigned int q_cible,
718 const std::vector<double> &xm,
const std::vector<double> &ym,
719 const std::vector<double> &xmi,
const std::vector<double> &ymi,
722 unsigned int nbpt = (
unsigned int)xm.size();
731 for (
unsigned int i=0;i<nbpt;i++) {
762 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
764 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
784 double *xb,
double *yb,
785 double *xa,
double *ya ,
790 unsigned int q_cible;
798 ::HLM(q_cible,n, xa,ya,xb,yb,H) ;
805 #endif //#ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
829 const std::vector<double> &xa,
const std::vector<double> &ya,
833 unsigned int n = (
unsigned int) xb.size();
834 if (yb.size() != n || xa.size() != n || ya.size() != n)
836 "Bad dimension for HLM shomography estimation"));
843 unsigned int q_cible;
851 ::HLM(q_cible, xa, ya, xb, yb, H) ;
Definition of the vpMatrix class.
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
error that can be emited by ViSP classes.
static void HLM(const std::vector< double > &xb, const std::vector< double > &yb, const std::vector< double > &xa, const std::vector< double > &ya, bool isplanar, vpHomography &aHb)
static Type maximum(const Type &a, const Type &b)
This class aims to compute the homography wrt.two images.
void svd(vpColVector &w, vpMatrix &v)
Class that provides a data structure for the column vectors as well as a set of operations on these v...
error that can be emited by the vpMatrix class and its derivates
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.