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 ;
95 void changeFrame(
unsigned int *pts_ref,
104 unsigned int i,j, k ;
105 unsigned int cont_pts;
107 double lamb_cour[3] ;
117 M[j][i] = p[pts_ref[i]][j] ;
118 Md[j][i] = pd[pts_ref[i]][j] ;
126 if (pts_ref[3] > 0) {
129 lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
130 lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
136 M[i][j] = M[i][j]*lamb_cour[j] ;
137 Md[i][j] = Md[i][j]*lamb_des[j] ;
149 for (k=0;k<nb_pts;k++) {
150 if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
152 pn[cont_pts][i] = 0.0 ;
153 pnd[cont_pts][i] = 0.0 ;
155 pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j]*p[k][j] ;
156 pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j]*pd[k][j] ;
159 cont_pts = cont_pts + 1;
195 HLM2D(
unsigned int nb_pts,
203 unsigned int contZeros, vect;
211 for (j=0; j<nb_pts ;j++) {
215 M[3*j][3] = -points_des[j][0]*points_cour[j][2] ;
216 M[3*j][4] = -points_des[j][1]*points_cour[j][2] ;
217 M[3*j][5] = -points_des[j][2]*points_cour[j][2] ;
218 M[3*j][6] = points_des[j][0]*points_cour[j][1] ;
219 M[3*j][7] = points_des[j][1]*points_cour[j][1] ;
220 M[3*j][8] = points_des[j][2]*points_cour[j][1] ;
222 M[3*j+1][0] = points_des[j][0]*points_cour[j][2] ;
223 M[3*j+1][1] = points_des[j][1]*points_cour[j][2] ;
224 M[3*j+1][2] = points_des[j][2]*points_cour[j][2] ;
228 M[3*j+1][6] = -points_des[j][0]*points_cour[j][0] ;
229 M[3*j+1][7] = -points_des[j][1]*points_cour[j][0] ;
230 M[3*j+1][8] = -points_des[j][2]*points_cour[j][0] ;
232 M[3*j+2][0] = -points_des[j][0]*points_cour[j][1] ;
233 M[3*j+2][1] = -points_des[j][1]*points_cour[j][1] ;
234 M[3*j+2][2] = -points_des[j][2]*points_cour[j][1] ;
235 M[3*j+2][3] = points_des[j][0]*points_cour[j][0] ;
236 M[3*j+2][4] = points_des[j][1]*points_cour[j][0] ;
237 M[3*j+2][5] = points_des[j][2]*points_cour[j][0] ;
254 vals_inf = fabs(sv[0]) ;
257 if (fabs(sv[0]) < eps) {
258 contZeros = contZeros + 1 ;
260 for (j=1; j<9; j++) {
261 if (fabs(sv[j]) < vals_inf) {
262 vals_inf = fabs(sv[j]);
265 if (fabs(sv[j]) < eps) {
266 contZeros = contZeros + 1 ;
275 "matrix is rank deficient"));
280 for (i=0; i<3; i++) {
282 H[i][j] = V[3*i+j][vect];
314 HLM3D(
unsigned int nb_pts,
319 unsigned int i,j,k,ii,jj ;
320 unsigned int cont_pts;
323 unsigned int pts_ref[4];
365 changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
368 cont_pts = nb_pts - 3 ;
374 "Not enough point to compute the homography"));
384 for (i=0;i<nc;i++)
for (j=0;j<nc;j++) CtC[i][j] = 0.0;
401 for (i=0 ; i<nb_pts-5; i++) {
402 for (j = i+1 ; j<nb_pts-4; j++) {
403 for (k = j+1 ; k<nb_pts-3; k ++) {
405 C[0] = pn[i][2]*pn[j][2]*pn[k][1]*pnd[k][0]
406 * (pnd[j][0]*pnd[i][1] - pnd[j][1]*pnd[i][0])
407 + pn[i][2]*pn[k][2]*pn[j][1]*pnd[j][0]
408 *(pnd[i][0]*pnd[k][1] - pnd[i][1]*pnd[k][0])
409 + pn[j][2]*pn[k][2]*pn[i][1]*pnd[i][0]
410 *(pnd[k][0]*pnd[j][1] - pnd[k][1]*pnd[j][0]) ;
412 C[1] = pn[i][2]*pn[j][2]*pn[k][0]*pnd[k][1]
413 *(pnd[i][0]*pnd[j][1] - pnd[i][1]*pnd[j][0])
414 + pn[i][2]*pn[k][2]*pn[j][0]*pnd[j][1]
415 *(pnd[k][0]*pnd[i][1] - pnd[k][1]*pnd[i][0])
416 + pn[j][2]*pn[k][2]*pn[i][0]*pnd[i][1]
417 *(pnd[j][0]*pnd[k][1] - pnd[j][1]*pnd[k][0]) ;
419 C[2] = + pn[i][1]*pn[k][1]*pn[j][2]*pnd[j][0]
420 *(pnd[k][2]*pnd[i][0] - pnd[k][0]*pnd[i][2])
421 +pn[i][1]*pn[j][1]*pn[k][2]*pnd[k][0]
422 *(pnd[i][2]*pnd[j][0] - pnd[i][0]*pnd[j][2])
423 + pn[j][1]*pn[k][1]*pn[i][2]*pnd[i][0]
424 *(pnd[j][2]*pnd[k][0] - pnd[j][0]*pnd[k][2]) ;
429 C[3] = pn[i][0]*pn[j][0]*pn[k][2]*pnd[k][1]
430 *(pnd[i][2]*pnd[j][1] - pnd[i][1]*pnd[j][2])
431 + pn[i][0]*pn[k][0]*pn[j][2]*pnd[j][1]
432 *(pnd[k][2]*pnd[i][1] - pnd[k][1]*pnd[i][2])
433 + pn[j][0]*pn[k][0]*pn[i][2]*pnd[i][1]
434 *(pnd[j][2]*pnd[k][1] - pnd[j][1]*pnd[k][2]) ;
437 C[5] = pn[i][1]*pn[j][1]*pn[k][0]*pnd[k][2]
438 *(pnd[i][0]*pnd[j][2] - pnd[i][2]*pnd[j][0])
439 + pn[i][1]*pn[k][1]*pn[j][0]*pnd[j][2]
440 *(pnd[k][0]*pnd[i][2] - pnd[k][2]*pnd[i][0])
441 + pn[j][1]*pn[k][1]*pn[i][0]*pnd[i][2]
442 *(pnd[j][0]*pnd[k][2] - pnd[j][2]*pnd[k][0]) ;
444 C[6] = pn[i][0]*pn[j][0]*pn[k][1]*pnd[k][2]
445 *(pnd[i][1]*pnd[j][2] - pnd[i][2]*pnd[j][1])
446 + pn[i][0]*pn[k][0]*pn[j][1]*pnd[j][2]
447 *(pnd[k][1]*pnd[i][2] - pnd[k][2]*pnd[i][1])
448 + pn[j][0]*pn[k][0]*pn[i][1]*pnd[i][2]
449 *(pnd[j][1]*pnd[k][2] - pnd[j][2]*pnd[k][1]) ;
451 C[4] = pn[i][0]*pn[k][1]*pn[j][2]
452 *(pnd[k][0]*pnd[j][1]*pnd[i][2] - pnd[j][0]*pnd[i][1]*pnd[k][2])
453 + pn[k][0]*pn[i][1]*pn[j][2]
454 *(pnd[j][0]*pnd[k][1]*pnd[i][2] - pnd[i][0]*pnd[j][1]*pnd[k][2])
455 + pn[i][0]*pn[j][1]*pn[k][2]
456 *(pnd[k][0]*pnd[i][1]*pnd[j][2] - pnd[j][0]*pnd[k][1]*pnd[i][2])
457 + pn[j][0]*pn[i][1]*pn[k][2]
458 *(pnd[i][0]*pnd[k][1]*pnd[j][2] - pnd[k][0]*pnd[j][1]*pnd[i][2])
459 + pn[k][0]*pn[j][1]*pn[i][2]
460 *(pnd[j][0]*pnd[i][1]*pnd[k][2] - pnd[i][0]*pnd[k][1]*pnd[j][2])
461 + pn[j][0]*pn[k][1]*pn[i][2]
462 *(pnd[i][0]*pnd[j][1]*pnd[k][2] - pnd[k][0]*pnd[i][1]*pnd[j][2]) ;
466 for (ii=0;ii<nc;ii++) {
467 for (jj=ii;jj<nc;jj++) {
468 CtC[ii][jj] = CtC[ii][jj] + C[ii]*C[jj];
479 for (i=0; i<nc ;i++) {
480 for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
508 for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
513 for (i=1; i < nc ;i++) {
514 if (svSorted[i-1] > svSorted[i]) {
515 v_temp = svSorted[i-1] ;
516 svSorted[i-1] = svSorted[i] ;
517 svSorted[i] = v_temp ;
530 vect = 0 ; cont_zeros = 0 ; cont = 0 ;
531 for (j=0; j < nc; j++) {
533 if (std::fabs(sv[j]-svSorted[cont]) <= std::fabs(
vpMath::maximum(sv[j],svSorted[cont]))) vect = j ;
534 if (std::fabs(sv[j]/svSorted[nc-1]) < eps) cont_zeros = cont_zeros + 1 ;
537 if (cont_zeros > 5) {
539 HLM2D(nb_pts,pd,p,H);
562 c[0][0] = V[5][vect] ; c[0][1] = 0.0 ;
563 c[1][0] = V[6][vect] ; c[1][1] = 0.0 ;
564 c[2][0] = V[3][vect] ; c[2][1] = 0.0 ;
565 c[3][0] = V[4][vect] ; c[3][1] = 0.0
567 c[4][0] = 0.0 ; c[4][1] = V[6][vect] ;
568 c[5][0] = 0.0 ; c[5][1] = V[5][vect] ;
569 c[6][0] = 0.0 ; c[6][1] = V[2][vect] ;
570 c[7][0] = 0.0 ; c[7][1] = V[4][vect] ;
575 cp = c.pseudoInverse(1e-6) ;
582 H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
586 T[0][0] = -V[1][vect] ; T[0][1] = V[0][vect] ;
587 T[1][0] = V[4][vect] ; T[1][2] = -V[2][vect] ;
588 T[2][0] = -V[6][vect] ; T[2][1] = V[2][vect] ;
589 T[3][0] = V[6][vect] ; T[3][2] = -V[0][vect] ;
590 T[4][0] = -V[3][vect] ; T[4][1] = V[6][vect] ;
591 T[5][0] = V[3][vect] ; T[5][2] = -V[1][vect] ;
592 T[6][0] = -V[5][vect] ; T[6][1] = V[4][vect] ;
593 T[7][0] = V[5][vect] ; T[7][2] = -V[6][vect] ;
594 T[8][1] = -V[5][vect] ; T[8][2] = V[2][vect] ;
598 for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
647 HLM(
unsigned int q_cible,
649 double *xm,
double *ym,
650 double *xmi,
double *ymi,
662 for (i=0;i<nbpt;i++) {
715 double *xb,
double *yb,
716 double *xa,
double *ya ,
720 #ifndef DOXYGEN_SHOULD_SKIP_THIS
723 unsigned int q_cible;
734 ::HLM(q_cible,n, xa,ya,xb,yb,H) ;
Definition of the vpMatrix class.
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
static Type maximum(const Type &a, const Type &b)
This class aims to compute the homography wrt.two images.
void setIdentity(const double &val=1.0)
void svd(vpColVector &w, vpMatrix &v)
static void HLM(unsigned int n, double *xb, double *yb, double *xa, double *ya, bool isplan, vpHomography &aHb)
Computes the homography matrix from planar or non planar points using Ezio Malis linear method (HLM)...
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.