51 #include <visp3/vision/vpHomography.h>
52 #include <visp3/core/vpDebug.h>
53 #include <visp3/core/vpMatrixException.h>
58 #ifndef DOXYGEN_SHOULD_SKIP_THIS
59 const double eps = 1e-6 ;
90 void changeFrame(
unsigned int *pts_ref,
95 void HLM2D(
unsigned int nb_pts,
99 void HLM3D(
unsigned int nb_pts,
103 void HLM(
unsigned int q_cible,
105 double *xm,
double *ym,
106 double *xmi,
double *ymi,
109 void HLM(
unsigned int q_cible,
110 const std::vector<double> &xm,
const std::vector<double> &ym,
111 const std::vector<double> &xmi,
const std::vector<double> &ymi,
114 void changeFrame(
unsigned int *pts_ref,
120 unsigned int i,j, k ;
121 unsigned int cont_pts;
129 M[j][i] = p[pts_ref[i]][j] ;
130 Md[j][i] = pd[pts_ref[i]][j] ;
138 if (pts_ref[3] > 0) {
144 lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
145 lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
151 M[i][j] = M[i][j]*lamb_cour[j] ;
152 Md[i][j] = Md[i][j]*lamb_des[j] ;
164 for (k=0;k<nb_pts;k++) {
165 if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
167 pn[cont_pts][i] = 0.0 ;
168 pnd[cont_pts][i] = 0.0 ;
170 pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j]*p[k][j] ;
171 pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j]*pd[k][j] ;
174 cont_pts = cont_pts + 1;
208 HLM2D(
unsigned int nb_pts,
216 unsigned int contZeros, vect;
224 for (j=0; j<nb_pts ;j++) {
228 M[3*j][3] = -points_des[j][0]*points_cour[j][2] ;
229 M[3*j][4] = -points_des[j][1]*points_cour[j][2] ;
230 M[3*j][5] = -points_des[j][2]*points_cour[j][2] ;
231 M[3*j][6] = points_des[j][0]*points_cour[j][1] ;
232 M[3*j][7] = points_des[j][1]*points_cour[j][1] ;
233 M[3*j][8] = points_des[j][2]*points_cour[j][1] ;
235 M[3*j+1][0] = points_des[j][0]*points_cour[j][2] ;
236 M[3*j+1][1] = points_des[j][1]*points_cour[j][2] ;
237 M[3*j+1][2] = points_des[j][2]*points_cour[j][2] ;
241 M[3*j+1][6] = -points_des[j][0]*points_cour[j][0] ;
242 M[3*j+1][7] = -points_des[j][1]*points_cour[j][0] ;
243 M[3*j+1][8] = -points_des[j][2]*points_cour[j][0] ;
245 M[3*j+2][0] = -points_des[j][0]*points_cour[j][1] ;
246 M[3*j+2][1] = -points_des[j][1]*points_cour[j][1] ;
247 M[3*j+2][2] = -points_des[j][2]*points_cour[j][1] ;
248 M[3*j+2][3] = points_des[j][0]*points_cour[j][0] ;
249 M[3*j+2][4] = points_des[j][1]*points_cour[j][0] ;
250 M[3*j+2][5] = points_des[j][2]*points_cour[j][0] ;
267 vals_inf = fabs(sv[0]) ;
270 if (fabs(sv[0]) < eps) {
271 contZeros = contZeros + 1 ;
273 for (j=1; j<9; j++) {
274 if (fabs(sv[j]) < vals_inf) {
275 vals_inf = fabs(sv[j]);
278 if (fabs(sv[j]) < eps) {
279 contZeros = contZeros + 1 ;
288 "matrix is rank deficient"));
293 for (i=0; i<3; i++) {
295 H[i][j] = V[3*i+j][vect];
327 HLM3D(
unsigned int nb_pts,
332 unsigned int i,j,k,ii,jj ;
333 unsigned int cont_pts;
336 unsigned int pts_ref[4];
378 changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
381 cont_pts = nb_pts - 3 ;
387 "Not enough point to compute the homography"));
397 for (i=0;i<nc;i++)
for (j=0;j<nc;j++) CtC[i][j] = 0.0;
414 for (i=0 ; i<nb_pts-5; i++) {
415 for (j = i+1 ; j<nb_pts-4; j++) {
416 for (k = j+1 ; k<nb_pts-3; k ++) {
418 C[0] = pn[i][2]*pn[j][2]*pn[k][1]*pnd[k][0]
419 * (pnd[j][0]*pnd[i][1] - pnd[j][1]*pnd[i][0])
420 + pn[i][2]*pn[k][2]*pn[j][1]*pnd[j][0]
421 *(pnd[i][0]*pnd[k][1] - pnd[i][1]*pnd[k][0])
422 + pn[j][2]*pn[k][2]*pn[i][1]*pnd[i][0]
423 *(pnd[k][0]*pnd[j][1] - pnd[k][1]*pnd[j][0]) ;
425 C[1] = pn[i][2]*pn[j][2]*pn[k][0]*pnd[k][1]
426 *(pnd[i][0]*pnd[j][1] - pnd[i][1]*pnd[j][0])
427 + pn[i][2]*pn[k][2]*pn[j][0]*pnd[j][1]
428 *(pnd[k][0]*pnd[i][1] - pnd[k][1]*pnd[i][0])
429 + pn[j][2]*pn[k][2]*pn[i][0]*pnd[i][1]
430 *(pnd[j][0]*pnd[k][1] - pnd[j][1]*pnd[k][0]) ;
432 C[2] = + pn[i][1]*pn[k][1]*pn[j][2]*pnd[j][0]
433 *(pnd[k][2]*pnd[i][0] - pnd[k][0]*pnd[i][2])
434 +pn[i][1]*pn[j][1]*pn[k][2]*pnd[k][0]
435 *(pnd[i][2]*pnd[j][0] - pnd[i][0]*pnd[j][2])
436 + pn[j][1]*pn[k][1]*pn[i][2]*pnd[i][0]
437 *(pnd[j][2]*pnd[k][0] - pnd[j][0]*pnd[k][2]) ;
442 C[3] = pn[i][0]*pn[j][0]*pn[k][2]*pnd[k][1]
443 *(pnd[i][2]*pnd[j][1] - pnd[i][1]*pnd[j][2])
444 + pn[i][0]*pn[k][0]*pn[j][2]*pnd[j][1]
445 *(pnd[k][2]*pnd[i][1] - pnd[k][1]*pnd[i][2])
446 + pn[j][0]*pn[k][0]*pn[i][2]*pnd[i][1]
447 *(pnd[j][2]*pnd[k][1] - pnd[j][1]*pnd[k][2]) ;
450 C[5] = pn[i][1]*pn[j][1]*pn[k][0]*pnd[k][2]
451 *(pnd[i][0]*pnd[j][2] - pnd[i][2]*pnd[j][0])
452 + pn[i][1]*pn[k][1]*pn[j][0]*pnd[j][2]
453 *(pnd[k][0]*pnd[i][2] - pnd[k][2]*pnd[i][0])
454 + pn[j][1]*pn[k][1]*pn[i][0]*pnd[i][2]
455 *(pnd[j][0]*pnd[k][2] - pnd[j][2]*pnd[k][0]) ;
457 C[6] = pn[i][0]*pn[j][0]*pn[k][1]*pnd[k][2]
458 *(pnd[i][1]*pnd[j][2] - pnd[i][2]*pnd[j][1])
459 + pn[i][0]*pn[k][0]*pn[j][1]*pnd[j][2]
460 *(pnd[k][1]*pnd[i][2] - pnd[k][2]*pnd[i][1])
461 + pn[j][0]*pn[k][0]*pn[i][1]*pnd[i][2]
462 *(pnd[j][1]*pnd[k][2] - pnd[j][2]*pnd[k][1]) ;
464 C[4] = pn[i][0]*pn[k][1]*pn[j][2]
465 *(pnd[k][0]*pnd[j][1]*pnd[i][2] - pnd[j][0]*pnd[i][1]*pnd[k][2])
466 + pn[k][0]*pn[i][1]*pn[j][2]
467 *(pnd[j][0]*pnd[k][1]*pnd[i][2] - pnd[i][0]*pnd[j][1]*pnd[k][2])
468 + pn[i][0]*pn[j][1]*pn[k][2]
469 *(pnd[k][0]*pnd[i][1]*pnd[j][2] - pnd[j][0]*pnd[k][1]*pnd[i][2])
470 + pn[j][0]*pn[i][1]*pn[k][2]
471 *(pnd[i][0]*pnd[k][1]*pnd[j][2] - pnd[k][0]*pnd[j][1]*pnd[i][2])
472 + pn[k][0]*pn[j][1]*pn[i][2]
473 *(pnd[j][0]*pnd[i][1]*pnd[k][2] - pnd[i][0]*pnd[k][1]*pnd[j][2])
474 + pn[j][0]*pn[k][1]*pn[i][2]
475 *(pnd[i][0]*pnd[j][1]*pnd[k][2] - pnd[k][0]*pnd[i][1]*pnd[j][2]) ;
479 for (ii=0;ii<nc;ii++) {
480 for (jj=ii;jj<nc;jj++) {
481 CtC[ii][jj] = CtC[ii][jj] + C[ii]*C[jj];
492 for (i=0; i<nc ;i++) {
493 for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
521 for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
526 for (i=1; i < nc ;i++) {
527 if (svSorted[i-1] > svSorted[i]) {
528 v_temp = svSorted[i-1] ;
529 svSorted[i-1] = svSorted[i] ;
530 svSorted[i] = v_temp ;
543 vect = 0 ; cont_zeros = 0 ; cont = 0 ;
544 for (j=0; j < nc; j++) {
546 if (std::fabs(sv[j]-svSorted[cont]) <= std::fabs(
vpMath::maximum(sv[j],svSorted[cont]))) vect = j ;
547 if (std::fabs(sv[j]/svSorted[nc-1]) < eps) cont_zeros = cont_zeros + 1 ;
550 if (cont_zeros > 5) {
552 HLM2D(nb_pts,pd,p,H);
575 c[0][0] = V[5][vect] ; c[0][1] = 0.0 ;
576 c[1][0] = V[6][vect] ; c[1][1] = 0.0 ;
577 c[2][0] = V[3][vect] ; c[2][1] = 0.0 ;
578 c[3][0] = V[4][vect] ; c[3][1] = 0.0
580 c[4][0] = 0.0 ; c[4][1] = V[6][vect] ;
581 c[5][0] = 0.0 ; c[5][1] = V[5][vect] ;
582 c[6][0] = 0.0 ; c[6][1] = V[2][vect] ;
583 c[7][0] = 0.0 ; c[7][1] = V[4][vect] ;
588 cp = c.pseudoInverse(1e-6) ;
595 H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
599 T[0][0] = -V[1][vect] ; T[0][1] = V[0][vect] ;
600 T[1][0] = V[4][vect] ; T[1][2] = -V[2][vect] ;
601 T[2][0] = -V[6][vect] ; T[2][1] = V[2][vect] ;
602 T[3][0] = V[6][vect] ; T[3][2] = -V[0][vect] ;
603 T[4][0] = -V[3][vect] ; T[4][1] = V[6][vect] ;
604 T[5][0] = V[3][vect] ; T[5][2] = -V[1][vect] ;
605 T[6][0] = -V[5][vect] ; T[6][1] = V[4][vect] ;
606 T[7][0] = V[5][vect] ; T[7][2] = -V[6][vect] ;
607 T[8][1] = -V[5][vect] ; T[8][2] = V[2][vect] ;
611 for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
622 HLM(
unsigned int q_cible,
623 const std::vector<double> &xm,
const std::vector<double> &ym,
624 const std::vector<double> &xmi,
const std::vector<double> &ymi,
627 unsigned int nbpt = (
unsigned int)xm.size();
636 for (
unsigned int i=0;i<nbpt;i++) {
667 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
691 const std::vector<double> &xa,
const std::vector<double> &ya,
695 unsigned int n = (
unsigned int) xb.size();
696 if (yb.size() != n || xa.size() != n || ya.size() != n)
698 "Bad dimension for HLM shomography estimation"));
705 unsigned int q_cible;
713 ::HLM(q_cible, xa, ya, xb, yb, H) ;
Implementation of a matrix and operations on matrices.
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=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)
Implementation of an homography and operations on homographies.
void svd(vpColVector &w, vpMatrix &v)
Implementation of column vector and the associated operations.
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.