81 #include <visp/vpHomography.h>
82 #include <visp/vpDebug.h>
83 #include <visp/vpMatrixException.h>
88 #ifndef DOXYGEN_SHOULD_SKIP_THIS
89 const double eps = 1e-6 ;
121 void changeFrame(
unsigned int *pts_ref,
130 unsigned int i,j, k ;
131 unsigned int cont_pts;
133 double lamb_cour[3] ;
143 M[j][i] = p[pts_ref[i]][j] ;
144 Md[j][i] = pd[pts_ref[i]][j] ;
152 if (pts_ref[3] > 0) {
155 lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
156 lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
162 M[i][j] = M[i][j]*lamb_cour[j] ;
163 Md[i][j] = Md[i][j]*lamb_des[j] ;
175 for (k=0;k<nb_pts;k++) {
176 if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
178 pn[cont_pts][i] = 0.0 ;
179 pnd[cont_pts][i] = 0.0 ;
181 pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j]*p[k][j] ;
182 pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j]*pd[k][j] ;
185 cont_pts = cont_pts + 1;
221 HLM2D(
unsigned int nb_pts,
229 unsigned int contZeros, vect;
237 for (j=0; j<nb_pts ;j++) {
241 M[3*j][3] = -points_des[j][0]*points_cour[j][2] ;
242 M[3*j][4] = -points_des[j][1]*points_cour[j][2] ;
243 M[3*j][5] = -points_des[j][2]*points_cour[j][2] ;
244 M[3*j][6] = points_des[j][0]*points_cour[j][1] ;
245 M[3*j][7] = points_des[j][1]*points_cour[j][1] ;
246 M[3*j][8] = points_des[j][2]*points_cour[j][1] ;
248 M[3*j+1][0] = points_des[j][0]*points_cour[j][2] ;
249 M[3*j+1][1] = points_des[j][1]*points_cour[j][2] ;
250 M[3*j+1][2] = points_des[j][2]*points_cour[j][2] ;
254 M[3*j+1][6] = -points_des[j][0]*points_cour[j][0] ;
255 M[3*j+1][7] = -points_des[j][1]*points_cour[j][0] ;
256 M[3*j+1][8] = -points_des[j][2]*points_cour[j][0] ;
258 M[3*j+2][0] = -points_des[j][0]*points_cour[j][1] ;
259 M[3*j+2][1] = -points_des[j][1]*points_cour[j][1] ;
260 M[3*j+2][2] = -points_des[j][2]*points_cour[j][1] ;
261 M[3*j+2][3] = points_des[j][0]*points_cour[j][0] ;
262 M[3*j+2][4] = points_des[j][1]*points_cour[j][0] ;
263 M[3*j+2][5] = points_des[j][2]*points_cour[j][0] ;
280 vals_inf = fabs(sv[0]) ;
283 if (fabs(sv[0]) < eps) {
284 contZeros = contZeros + 1 ;
286 for (j=1; j<9; j++) {
287 if (fabs(sv[j]) < vals_inf) {
288 vals_inf = fabs(sv[j]);
291 if (fabs(sv[j]) < eps) {
292 contZeros = contZeros + 1 ;
301 "matrix is rank deficient"));
306 for (i=0; i<3; i++) {
308 H[i][j] = V[3*i+j][vect];
340 HLM3D(
unsigned int nb_pts,
345 unsigned int i,j,k,ii,jj ;
346 unsigned int cont_pts;
349 unsigned int pts_ref[4];
391 changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
394 cont_pts = nb_pts - 3 ;
400 "Not enough point to compute the homography"));
410 for (i=0;i<nc;i++)
for (j=0;j<nc;j++) CtC[i][j] = 0.0;
427 for (i=0 ; i<nb_pts-5; i++) {
428 for (j = i+1 ; j<nb_pts-4; j++) {
429 for (k = j+1 ; k<nb_pts-3; k ++) {
431 C[0] = pn[i][2]*pn[j][2]*pn[k][1]*pnd[k][0]
432 * (pnd[j][0]*pnd[i][1] - pnd[j][1]*pnd[i][0])
433 + pn[i][2]*pn[k][2]*pn[j][1]*pnd[j][0]
434 *(pnd[i][0]*pnd[k][1] - pnd[i][1]*pnd[k][0])
435 + pn[j][2]*pn[k][2]*pn[i][1]*pnd[i][0]
436 *(pnd[k][0]*pnd[j][1] - pnd[k][1]*pnd[j][0]) ;
438 C[1] = pn[i][2]*pn[j][2]*pn[k][0]*pnd[k][1]
439 *(pnd[i][0]*pnd[j][1] - pnd[i][1]*pnd[j][0])
440 + pn[i][2]*pn[k][2]*pn[j][0]*pnd[j][1]
441 *(pnd[k][0]*pnd[i][1] - pnd[k][1]*pnd[i][0])
442 + pn[j][2]*pn[k][2]*pn[i][0]*pnd[i][1]
443 *(pnd[j][0]*pnd[k][1] - pnd[j][1]*pnd[k][0]) ;
445 C[2] = + pn[i][1]*pn[k][1]*pn[j][2]*pnd[j][0]
446 *(pnd[k][2]*pnd[i][0] - pnd[k][0]*pnd[i][2])
447 +pn[i][1]*pn[j][1]*pn[k][2]*pnd[k][0]
448 *(pnd[i][2]*pnd[j][0] - pnd[i][0]*pnd[j][2])
449 + pn[j][1]*pn[k][1]*pn[i][2]*pnd[i][0]
450 *(pnd[j][2]*pnd[k][0] - pnd[j][0]*pnd[k][2]) ;
455 C[3] = pn[i][0]*pn[j][0]*pn[k][2]*pnd[k][1]
456 *(pnd[i][2]*pnd[j][1] - pnd[i][1]*pnd[j][2])
457 + pn[i][0]*pn[k][0]*pn[j][2]*pnd[j][1]
458 *(pnd[k][2]*pnd[i][1] - pnd[k][1]*pnd[i][2])
459 + pn[j][0]*pn[k][0]*pn[i][2]*pnd[i][1]
460 *(pnd[j][2]*pnd[k][1] - pnd[j][1]*pnd[k][2]) ;
463 C[5] = pn[i][1]*pn[j][1]*pn[k][0]*pnd[k][2]
464 *(pnd[i][0]*pnd[j][2] - pnd[i][2]*pnd[j][0])
465 + pn[i][1]*pn[k][1]*pn[j][0]*pnd[j][2]
466 *(pnd[k][0]*pnd[i][2] - pnd[k][2]*pnd[i][0])
467 + pn[j][1]*pn[k][1]*pn[i][0]*pnd[i][2]
468 *(pnd[j][0]*pnd[k][2] - pnd[j][2]*pnd[k][0]) ;
470 C[6] = pn[i][0]*pn[j][0]*pn[k][1]*pnd[k][2]
471 *(pnd[i][1]*pnd[j][2] - pnd[i][2]*pnd[j][1])
472 + pn[i][0]*pn[k][0]*pn[j][1]*pnd[j][2]
473 *(pnd[k][1]*pnd[i][2] - pnd[k][2]*pnd[i][1])
474 + pn[j][0]*pn[k][0]*pn[i][1]*pnd[i][2]
475 *(pnd[j][1]*pnd[k][2] - pnd[j][2]*pnd[k][1]) ;
477 C[4] = pn[i][0]*pn[k][1]*pn[j][2]
478 *(pnd[k][0]*pnd[j][1]*pnd[i][2] - pnd[j][0]*pnd[i][1]*pnd[k][2])
479 + pn[k][0]*pn[i][1]*pn[j][2]
480 *(pnd[j][0]*pnd[k][1]*pnd[i][2] - pnd[i][0]*pnd[j][1]*pnd[k][2])
481 + pn[i][0]*pn[j][1]*pn[k][2]
482 *(pnd[k][0]*pnd[i][1]*pnd[j][2] - pnd[j][0]*pnd[k][1]*pnd[i][2])
483 + pn[j][0]*pn[i][1]*pn[k][2]
484 *(pnd[i][0]*pnd[k][1]*pnd[j][2] - pnd[k][0]*pnd[j][1]*pnd[i][2])
485 + pn[k][0]*pn[j][1]*pn[i][2]
486 *(pnd[j][0]*pnd[i][1]*pnd[k][2] - pnd[i][0]*pnd[k][1]*pnd[j][2])
487 + pn[j][0]*pn[k][1]*pn[i][2]
488 *(pnd[i][0]*pnd[j][1]*pnd[k][2] - pnd[k][0]*pnd[i][1]*pnd[j][2]) ;
492 for (ii=0;ii<nc;ii++) {
493 for (jj=ii;jj<nc;jj++) {
494 CtC[ii][jj] = CtC[ii][jj] + C[ii]*C[jj];
505 for (i=0; i<nc ;i++) {
506 for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
534 for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
539 for (i=1; i < nc ;i++) {
540 if (svSorted[i-1] > svSorted[i]) {
541 v_temp = svSorted[i-1] ;
542 svSorted[i-1] = svSorted[i] ;
543 svSorted[i] = v_temp ;
556 vect = 0 ; cont_zeros = 0 ; cont = 0 ;
557 for (j=0; j < nc; j++) {
559 if (std::fabs(sv[j]-svSorted[cont]) <= std::fabs(
vpMath::maximum(sv[j],svSorted[cont]))) vect = j ;
560 if (std::fabs(sv[j]/svSorted[nc-1]) < eps) cont_zeros = cont_zeros + 1 ;
563 if (cont_zeros > 5) {
565 HLM2D(nb_pts,pd,p,H);
588 c[0][0] = V[5][vect] ; c[0][1] = 0.0 ;
589 c[1][0] = V[6][vect] ; c[1][1] = 0.0 ;
590 c[2][0] = V[3][vect] ; c[2][1] = 0.0 ;
591 c[3][0] = V[4][vect] ; c[3][1] = 0.0
593 c[4][0] = 0.0 ; c[4][1] = V[6][vect] ;
594 c[5][0] = 0.0 ; c[5][1] = V[5][vect] ;
595 c[6][0] = 0.0 ; c[6][1] = V[2][vect] ;
596 c[7][0] = 0.0 ; c[7][1] = V[4][vect] ;
601 cp = c.pseudoInverse(1e-6) ;
608 H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
612 T[0][0] = -V[1][vect] ; T[0][1] = V[0][vect] ;
613 T[1][0] = V[4][vect] ; T[1][2] = -V[2][vect] ;
614 T[2][0] = -V[6][vect] ; T[2][1] = V[2][vect] ;
615 T[3][0] = V[6][vect] ; T[3][2] = -V[0][vect] ;
616 T[4][0] = -V[3][vect] ; T[4][1] = V[6][vect] ;
617 T[5][0] = V[3][vect] ; T[5][2] = -V[1][vect] ;
618 T[6][0] = -V[5][vect] ; T[6][1] = V[4][vect] ;
619 T[7][0] = V[5][vect] ; T[7][2] = -V[6][vect] ;
620 T[8][1] = -V[5][vect] ; T[8][2] = V[2][vect] ;
624 for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
673 HLM(
unsigned int q_cible,
675 double *xm,
double *ym,
676 double *xmi,
double *ymi,
688 for (i=0;i<nbpt;i++) {
774 double *xb,
double *yb,
775 double *xa,
double *ya ,
779 #ifndef DOXYGEN_SHOULD_SKIP_THIS
782 unsigned int q_cible;
793 ::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.