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;
123 double lamb_cour[3] ;
133 M[j][i] = p[pts_ref[i]][j] ;
134 Md[j][i] = pd[pts_ref[i]][j] ;
142 if (pts_ref[3] > 0) {
145 lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
146 lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
152 M[i][j] = M[i][j]*lamb_cour[j] ;
153 Md[i][j] = Md[i][j]*lamb_des[j] ;
165 for (k=0;k<nb_pts;k++) {
166 if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
168 pn[cont_pts][i] = 0.0 ;
169 pnd[cont_pts][i] = 0.0 ;
171 pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j]*p[k][j] ;
172 pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j]*pd[k][j] ;
175 cont_pts = cont_pts + 1;
211 HLM2D(
unsigned int nb_pts,
219 unsigned int contZeros, vect;
227 for (j=0; j<nb_pts ;j++) {
231 M[3*j][3] = -points_des[j][0]*points_cour[j][2] ;
232 M[3*j][4] = -points_des[j][1]*points_cour[j][2] ;
233 M[3*j][5] = -points_des[j][2]*points_cour[j][2] ;
234 M[3*j][6] = points_des[j][0]*points_cour[j][1] ;
235 M[3*j][7] = points_des[j][1]*points_cour[j][1] ;
236 M[3*j][8] = points_des[j][2]*points_cour[j][1] ;
238 M[3*j+1][0] = points_des[j][0]*points_cour[j][2] ;
239 M[3*j+1][1] = points_des[j][1]*points_cour[j][2] ;
240 M[3*j+1][2] = points_des[j][2]*points_cour[j][2] ;
244 M[3*j+1][6] = -points_des[j][0]*points_cour[j][0] ;
245 M[3*j+1][7] = -points_des[j][1]*points_cour[j][0] ;
246 M[3*j+1][8] = -points_des[j][2]*points_cour[j][0] ;
248 M[3*j+2][0] = -points_des[j][0]*points_cour[j][1] ;
249 M[3*j+2][1] = -points_des[j][1]*points_cour[j][1] ;
250 M[3*j+2][2] = -points_des[j][2]*points_cour[j][1] ;
251 M[3*j+2][3] = points_des[j][0]*points_cour[j][0] ;
252 M[3*j+2][4] = points_des[j][1]*points_cour[j][0] ;
253 M[3*j+2][5] = points_des[j][2]*points_cour[j][0] ;
270 vals_inf = fabs(sv[0]) ;
273 if (fabs(sv[0]) < eps) {
274 contZeros = contZeros + 1 ;
276 for (j=1; j<9; j++) {
277 if (fabs(sv[j]) < vals_inf) {
278 vals_inf = fabs(sv[j]);
281 if (fabs(sv[j]) < eps) {
282 contZeros = contZeros + 1 ;
291 "matrix is rank deficient"));
296 for (i=0; i<3; i++) {
298 H[i][j] = V[3*i+j][vect];
330 HLM3D(
unsigned int nb_pts,
335 unsigned int i,j,k,ii,jj ;
336 unsigned int cont_pts;
339 unsigned int pts_ref[4];
381 changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
384 cont_pts = nb_pts - 3 ;
390 "Not enough point to compute the homography"));
400 for (i=0;i<nc;i++)
for (j=0;j<nc;j++) CtC[i][j] = 0.0;
417 for (i=0 ; i<nb_pts-5; i++) {
418 for (j = i+1 ; j<nb_pts-4; j++) {
419 for (k = j+1 ; k<nb_pts-3; k ++) {
421 C[0] = pn[i][2]*pn[j][2]*pn[k][1]*pnd[k][0]
422 * (pnd[j][0]*pnd[i][1] - pnd[j][1]*pnd[i][0])
423 + pn[i][2]*pn[k][2]*pn[j][1]*pnd[j][0]
424 *(pnd[i][0]*pnd[k][1] - pnd[i][1]*pnd[k][0])
425 + pn[j][2]*pn[k][2]*pn[i][1]*pnd[i][0]
426 *(pnd[k][0]*pnd[j][1] - pnd[k][1]*pnd[j][0]) ;
428 C[1] = pn[i][2]*pn[j][2]*pn[k][0]*pnd[k][1]
429 *(pnd[i][0]*pnd[j][1] - pnd[i][1]*pnd[j][0])
430 + pn[i][2]*pn[k][2]*pn[j][0]*pnd[j][1]
431 *(pnd[k][0]*pnd[i][1] - pnd[k][1]*pnd[i][0])
432 + pn[j][2]*pn[k][2]*pn[i][0]*pnd[i][1]
433 *(pnd[j][0]*pnd[k][1] - pnd[j][1]*pnd[k][0]) ;
435 C[2] = + pn[i][1]*pn[k][1]*pn[j][2]*pnd[j][0]
436 *(pnd[k][2]*pnd[i][0] - pnd[k][0]*pnd[i][2])
437 +pn[i][1]*pn[j][1]*pn[k][2]*pnd[k][0]
438 *(pnd[i][2]*pnd[j][0] - pnd[i][0]*pnd[j][2])
439 + pn[j][1]*pn[k][1]*pn[i][2]*pnd[i][0]
440 *(pnd[j][2]*pnd[k][0] - pnd[j][0]*pnd[k][2]) ;
445 C[3] = pn[i][0]*pn[j][0]*pn[k][2]*pnd[k][1]
446 *(pnd[i][2]*pnd[j][1] - pnd[i][1]*pnd[j][2])
447 + pn[i][0]*pn[k][0]*pn[j][2]*pnd[j][1]
448 *(pnd[k][2]*pnd[i][1] - pnd[k][1]*pnd[i][2])
449 + pn[j][0]*pn[k][0]*pn[i][2]*pnd[i][1]
450 *(pnd[j][2]*pnd[k][1] - pnd[j][1]*pnd[k][2]) ;
453 C[5] = pn[i][1]*pn[j][1]*pn[k][0]*pnd[k][2]
454 *(pnd[i][0]*pnd[j][2] - pnd[i][2]*pnd[j][0])
455 + pn[i][1]*pn[k][1]*pn[j][0]*pnd[j][2]
456 *(pnd[k][0]*pnd[i][2] - pnd[k][2]*pnd[i][0])
457 + pn[j][1]*pn[k][1]*pn[i][0]*pnd[i][2]
458 *(pnd[j][0]*pnd[k][2] - pnd[j][2]*pnd[k][0]) ;
460 C[6] = pn[i][0]*pn[j][0]*pn[k][1]*pnd[k][2]
461 *(pnd[i][1]*pnd[j][2] - pnd[i][2]*pnd[j][1])
462 + pn[i][0]*pn[k][0]*pn[j][1]*pnd[j][2]
463 *(pnd[k][1]*pnd[i][2] - pnd[k][2]*pnd[i][1])
464 + pn[j][0]*pn[k][0]*pn[i][1]*pnd[i][2]
465 *(pnd[j][1]*pnd[k][2] - pnd[j][2]*pnd[k][1]) ;
467 C[4] = pn[i][0]*pn[k][1]*pn[j][2]
468 *(pnd[k][0]*pnd[j][1]*pnd[i][2] - pnd[j][0]*pnd[i][1]*pnd[k][2])
469 + pn[k][0]*pn[i][1]*pn[j][2]
470 *(pnd[j][0]*pnd[k][1]*pnd[i][2] - pnd[i][0]*pnd[j][1]*pnd[k][2])
471 + pn[i][0]*pn[j][1]*pn[k][2]
472 *(pnd[k][0]*pnd[i][1]*pnd[j][2] - pnd[j][0]*pnd[k][1]*pnd[i][2])
473 + pn[j][0]*pn[i][1]*pn[k][2]
474 *(pnd[i][0]*pnd[k][1]*pnd[j][2] - pnd[k][0]*pnd[j][1]*pnd[i][2])
475 + pn[k][0]*pn[j][1]*pn[i][2]
476 *(pnd[j][0]*pnd[i][1]*pnd[k][2] - pnd[i][0]*pnd[k][1]*pnd[j][2])
477 + pn[j][0]*pn[k][1]*pn[i][2]
478 *(pnd[i][0]*pnd[j][1]*pnd[k][2] - pnd[k][0]*pnd[i][1]*pnd[j][2]) ;
482 for (ii=0;ii<nc;ii++) {
483 for (jj=ii;jj<nc;jj++) {
484 CtC[ii][jj] = CtC[ii][jj] + C[ii]*C[jj];
495 for (i=0; i<nc ;i++) {
496 for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
524 for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
529 for (i=1; i < nc ;i++) {
530 if (svSorted[i-1] > svSorted[i]) {
531 v_temp = svSorted[i-1] ;
532 svSorted[i-1] = svSorted[i] ;
533 svSorted[i] = v_temp ;
546 vect = 0 ; cont_zeros = 0 ; cont = 0 ;
547 for (j=0; j < nc; j++) {
549 if (std::fabs(sv[j]-svSorted[cont]) <= std::fabs(
vpMath::maximum(sv[j],svSorted[cont]))) vect = j ;
550 if (std::fabs(sv[j]/svSorted[nc-1]) < eps) cont_zeros = cont_zeros + 1 ;
553 if (cont_zeros > 5) {
555 HLM2D(nb_pts,pd,p,H);
578 c[0][0] = V[5][vect] ; c[0][1] = 0.0 ;
579 c[1][0] = V[6][vect] ; c[1][1] = 0.0 ;
580 c[2][0] = V[3][vect] ; c[2][1] = 0.0 ;
581 c[3][0] = V[4][vect] ; c[3][1] = 0.0
583 c[4][0] = 0.0 ; c[4][1] = V[6][vect] ;
584 c[5][0] = 0.0 ; c[5][1] = V[5][vect] ;
585 c[6][0] = 0.0 ; c[6][1] = V[2][vect] ;
586 c[7][0] = 0.0 ; c[7][1] = V[4][vect] ;
591 cp = c.pseudoInverse(1e-6) ;
598 H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
602 T[0][0] = -V[1][vect] ; T[0][1] = V[0][vect] ;
603 T[1][0] = V[4][vect] ; T[1][2] = -V[2][vect] ;
604 T[2][0] = -V[6][vect] ; T[2][1] = V[2][vect] ;
605 T[3][0] = V[6][vect] ; T[3][2] = -V[0][vect] ;
606 T[4][0] = -V[3][vect] ; T[4][1] = V[6][vect] ;
607 T[5][0] = V[3][vect] ; T[5][2] = -V[1][vect] ;
608 T[6][0] = -V[5][vect] ; T[6][1] = V[4][vect] ;
609 T[7][0] = V[5][vect] ; T[7][2] = -V[6][vect] ;
610 T[8][1] = -V[5][vect] ; T[8][2] = V[2][vect] ;
614 for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
625 HLM(
unsigned int q_cible,
626 const std::vector<double> &xm,
const std::vector<double> &ym,
627 const std::vector<double> &xmi,
const std::vector<double> &ymi,
630 unsigned int nbpt = (
unsigned int)xm.size();
639 for (
unsigned int i=0;i<nbpt;i++) {
670 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
694 const std::vector<double> &xa,
const std::vector<double> &ya,
698 unsigned int n = (
unsigned int) xb.size();
699 if (yb.size() != n || xa.size() != n || ya.size() != n)
701 "Bad dimension for HLM shomography estimation"));
708 unsigned int q_cible;
716 ::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.