Visual Servoing Platform  version 3.0.0
vpHomographyMalis.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Homography estimation.
32  *
33  * Authors:
34  * Eric Marchand
35  *
36  *****************************************************************************/
37 
38 
39 
51 #include <visp3/vision/vpHomography.h>
52 #include <visp3/core/vpDebug.h>
53 #include <visp3/core/vpMatrixException.h>
54 
55 #include <cmath> // std::fabs
56 #include <limits> // numeric_limits
57 
58 #ifndef DOXYGEN_SHOULD_SKIP_THIS
59 const double eps = 1e-6 ;
60 
61 /**************************************************************************
62  * NOM :
63  * changeFrame
64  *
65  * DESCRIPTION :
66  * Changement de repere Euclidien.
67  *
68  ****************************************************************************
69  * ENTREES :
70  * int pts_ref[4] : Definit quels sont les points de reference, ils ne
71  * seront pas affectes par le changement de repere
72  * int nb_pts : nombre de points a changer de repere
73  * double **pd : La matrice des coordonnees des points desires
74  * double **p : La matrice des coordonnees des points courants
75  *
76  *
77  * SORTIES :
78  *
79  * double **pt_des_nr : La matrice des coordonnees des points desires
80  * dans le nouveau repere.
81  * double **pt_cour_nr : La matrice des coordonnees des points courants
82  * dans le nouveau repere
83  * double **M : ??
84  * double **Mpd : pseudo inverse de M ..
85  *
86  *
87  ****************************************************************************
88  */
89 
90 void changeFrame(unsigned int *pts_ref,
91  unsigned int nb_pts,
92  vpMatrix &pd, vpMatrix &p,
93  vpMatrix &pnd, vpMatrix &pn,
94  vpMatrix &M, vpMatrix &Mdp);
95 void HLM2D(unsigned int nb_pts,
96  vpMatrix &points_des,
97  vpMatrix &points_cour,
98  vpMatrix &H);
99 void HLM3D(unsigned int nb_pts,
100  vpMatrix &pd,
101  vpMatrix &p,
102  vpMatrix &H);
103 void HLM(unsigned int q_cible,
104  unsigned int nbpt,
105  double *xm, double *ym,
106  double *xmi, double *ymi,
107  vpMatrix &H);
108 
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,
112  vpMatrix &H);
113 
114 void changeFrame(unsigned int *pts_ref,
115  unsigned int nb_pts,
116  vpMatrix &pd, vpMatrix &p,
117  vpMatrix &pnd, vpMatrix &pn,
118  vpMatrix &M, vpMatrix &Mdp)
119 {
120  unsigned int i,j, k ;
121  unsigned int cont_pts; /* */
122  double lamb_des[3]; /* */
123  double lamb_cour[3] ; /* */
124 
125 
126 
127  /* Construction des matrices de changement de repere */
128  vpMatrix Md(3,3) ;
129  vpMatrix Mp(3,3) ;
130 
131  for (i=0;i<3;i++) {
132  for (j=0;j<3;j++) {
133  M[j][i] = p[pts_ref[i]][j] ;
134  Md[j][i] = pd[pts_ref[i]][j] ;
135  }
136  }
137 
138  /*calcul de la pseudo inverse */
139  Mp= M.pseudoInverse(1e-16) ;
140  Mdp = Md.pseudoInverse(1e-16) ;
141 
142  if (pts_ref[3] > 0) {
143  for (i=0;i<3;i++) {
144  for (j=0;j<3;j++) {
145  lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
146  lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
147  }
148  }
149 
150  for (i=0;i<3;i++) {
151  for (j=0;j<3;j++) {
152  M[i][j] = M[i][j]*lamb_cour[j] ;
153  Md[i][j] = Md[i][j]*lamb_des[j] ;
154  }
155  }
156 
157  Mdp = Md.pseudoInverse(1e-16);
158  }
159 
160 
161  /* changement de repere pour tous les points autres que
162  les trois points de reference */
163 
164  cont_pts = 0 ;
165  for (k=0;k<nb_pts;k++) {
166  if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
167  for (i=0;i<3;i++) {
168  pn[cont_pts][i] = 0.0 ;
169  pnd[cont_pts][i] = 0.0 ;
170  for (j=0;j<3;j++) {
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] ;
173  }
174  }
175  cont_pts = cont_pts + 1;
176  }
177  }
178 
179 
180 }
181 
182 
183 /**************************************************************************
184  * NOM :
185  * Homographie_CrvMafEstHomoPointsCible2D
186  *
187  * DESCRIPTION :
188  * Calcul de l'homographie entre une image courante et une image desiree dans le
189  * cas particulier d'une cible planaire de points (cible pi).
190  * Cette procedure est appellee par "Homographie_CrvMafCalculHomographie".
191  *
192  ****************************************************************************
193  * ENTREES :
194  * int Nb_pts : nombre de points
195  * double **pd : tableau des coordonnees des points desires
196  * couble **p : tableau des coordonnees des points courants
197  *
198  * SORTIES :
199  *
200  * double **H matrice d homographie
201  *
202  ****************************************************************************
203  * AUTEUR : BOSSARD Nicolas. INSA Rennes 5eme annee.
204  *
205  * DATE DE CREATION : 02/12/98
206  *
207  * DATES DE MISE A JOUR :
208  *
209  ****************************************************************************/
210 void
211 HLM2D(unsigned int nb_pts,
212  vpMatrix &points_des,
213  vpMatrix &points_cour,
214  vpMatrix &H)
215 {
216  unsigned int i,j ;
217 
218  double vals_inf ;
219  unsigned int contZeros, vect;
220 
222  vpMatrix M(3*nb_pts,9) ;
223  vpMatrix V(9,9) ;
224  vpColVector sv(9) ;
225 
227  for (j=0; j<nb_pts ;j++) {
228  M[3*j][0] = 0 ;
229  M[3*j][1] = 0 ;
230  M[3*j][2] = 0 ;
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] ;
237 
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] ;
241  M[3*j+1][3] = 0 ;
242  M[3*j+1][4] = 0 ;
243  M[3*j+1][5] = 0 ;
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] ;
247 
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] ;
254  M[3*j+2][6] = 0 ;
255  M[3*j+2][7] = 0 ;
256  M[3*j+2][8] = 0 ;
257  }
258 
260  M.svd(sv,V);
261 
262  /*****
263  La meilleure solution est le vecteur de V associe
264  a la valeur singuliere la plus petite en valeur absolu.
265  Pour cela on parcourt la matrice des valeurs singulieres
266  et on repere la plus petite valeur singuliere, on en profite
267  pour effectuer un controle sur le rang de la matrice : pas plus
268  de 2 valeurs singulieres quasi=0
269  *****/
270  vals_inf = fabs(sv[0]) ;
271  vect = 0 ;
272  contZeros = 0;
273  if (fabs(sv[0]) < eps) {
274  contZeros = contZeros + 1 ;
275  }
276  for (j=1; j<9; j++) {
277  if (fabs(sv[j]) < vals_inf) {
278  vals_inf = fabs(sv[j]);
279  vect = j ;
280  }
281  if (fabs(sv[j]) < eps) {
282  contZeros = contZeros + 1 ;
283  }
284  }
285 
286 
288  if (contZeros > 2) {
289  //vpERROR_TRACE("matrix is rank deficient");
291  "matrix is rank deficient"));
292  }
293 
294  H.resize(3,3) ;
296  for (i=0; i<3; i++) {
297  for (j=0; j<3; j++){
298  H[i][j] = V[3*i+j][vect];
299  }
300  }
301 
302 
303 }
304 
305 
306 /**************************************************************************
307  * NOM :
308  * Homographie_CrvMafEstHomoPointsC3DEzio
309  *
310  * DESCRIPTION :
311  * Calcul de l'homographie entre une image courante et une image desiree dans le
312  * cas particulier d'une cible non planaire de points (cible pi).
313  * Cette procedure est appellee par "Homographie_CrvMafCalculHomographie".
314  *
315  *
316  ****************************************************************************
317  * ENTREES :
318  * int Nb_pts : nombre de points
319  * double **pd : tableau des coordonnees des points desires
320  * couble **p : tableau des coordonnees des points courants
321  *
322  * SORTIES :
323  *
324  * double **H matrice d'homographie
325  * double epipole[3] epipole
326  *
327  ****************************************************************************
328  **/
329 void
330 HLM3D(unsigned int nb_pts,
331  vpMatrix &pd,
332  vpMatrix &p,
333  vpMatrix &H)
334 {
335  unsigned int i,j,k,ii,jj ;
336  unsigned int cont_pts; /* Pour compter le nombre de points dans l'image */
337  //unsigned int nl; /*** Nombre de lignes ***/
338  unsigned int nc ; /*** Nombre de colonnes ***/
339  unsigned int pts_ref[4]; /*** definit lesquels des points de
340  l'image sont les points de reference***/
341  /*** ***/
342  unsigned int perm; /*** Compte le nombre de permutations, quand le nombre
343  de permutations =0 arret de l'ordonnancement **/
344  int cont_zeros; /*** pour compter les valeurs quasi= a zero ***/
345  unsigned int cont;
346  unsigned int vect;
347 
348  //int prob;
349 
350  /***** Corps de la fonction *****/
351 
352  /* allocation des matrices utilisees uniquement dans la procedure */
353  //prob=0;
354 
355  vpMatrix M(3,3) ;
356  vpMatrix Mdp(3,3) ;
357  vpMatrix c(8,2) ; // matrice des coeff C
358 
359  vpColVector d(8) ;
360  vpMatrix cp(2,8) ; //matrice pseudo-inverse de C
361 
362 
363  vpMatrix H_int(3,3) ;
364  vpMatrix pn((nb_pts-3),3) ; //points courant nouveau repere
365 
366 
367  vpMatrix pnd((nb_pts-3),3) ; //points derives nouveau repere
368 
369  /* preparation du changement de repere */
370  /****
371  comme plan de reference on choisit pour le moment
372  arbitrairement le plan contenant les points 1,2,3 du cinq
373  ****/
374  pts_ref[0] = 0 ;
375  pts_ref[1] = 1 ;
376  pts_ref[2] = 2 ;
377  pts_ref[3] = 0 ;
378 
379  /* changement de repere pour tous les points autres que les trois points de reference */
380 
381  changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
382 
383 
384  cont_pts = nb_pts - 3 ;
385 
386  if (cont_pts < 5)
387  {
388  //vpERROR_TRACE(" not enough point to compute the homography ... ");
390  "Not enough point to compute the homography"));
391  }
392 
393  //nl = cont_pts*(cont_pts-1)*(cont_pts-2)/6 ;
394  nc = 7 ;
395 
396  /* Allocation matrice CtC */
397  vpMatrix CtC(nc,nc) ;
398 
399  /* Initialisation matrice CtC */
400  for (i=0;i<nc;i++) for (j=0;j<nc;j++) CtC[i][j] = 0.0;
401 
402 
403  /* Allocation matrice M */
404  vpColVector C(nc) ; //Matrice des coefficients
405 
406  /* construction de la matrice M des coefficients dans le cas general */
407  /****
408  inconnues du nouveau algorithme
409  x1 = a ; x2 = b ; x3 = c ;
410  x4 = ex ; x5 = ey ; x6 = ez ;
411  qui deviennent apres changement :
412  v1 = x1*x6 ; v2 = x1*x5 ;
413  v3 = x2*x4 ; v4 = x2*x6 ;
414  v5 = x3*x5 ; v6 = x3*x4 ;
415  ****/
416  cont = 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 ++) {
420  /* coeff a^2*b */
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]) ; //
427  /* coeff a*b^2 */
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]) ;//
434  /* coeff a^2 */
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]) ; //
441 
442 
443 
444  /* coeff b^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]) ; //
451 
452  /* coeff a */
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]) ;//
459  /* coeff b */
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]) ;//
466  /* coeff a*b */
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]) ;//
479 
480  cont = cont+1 ;
481  /* construction de la matrice CtC */
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];
485  }
486  }
487 
488  }
489  }
490  }
491 
492 
493 
494  /* calcul de CtC */
495  for (i=0; i<nc ;i++) {
496  for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
497  }
498 
499  //nl = cont ; /* nombre de lignes */
500  nc = 7 ; /* nombre de colonnes */
501 
502  /* Creation de matrice CtC termine */
503  /* Allocation matrice V */
504  vpMatrix V(nc,nc) ;
505  /*****
506  Preparation au calcul de la svd (pseudo-inverse)
507  pour obtenir une solution il faut au moins 5 equations independantes
508  donc il faut au moins la mise en correspondence de 3+5 points
509  *****/
510  vpColVector sv(nc) ; //Vecteur contenant les valeurs singulieres
511 
512  CtC.svd(sv,V) ;
513 
514  /*****
515  Il faut un controle sur le rang de la matrice !!
516  La meilleure solution est le vecteur de V associe
517  a la valeur singuliere la plus petite en valeur
518  absolu
519  *****/
520 
521  vpColVector svSorted(nc) ; // sorted singular value
522 
523  // sorting the singular value
524  for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
525  perm = 1 ;
526  double v_temp;
527  while (perm != 0) {
528  perm = 0;
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 ;
534  perm = perm + 1;
535  }
536  }
537  }
538 
539  /*****
540  Parcours de la matrice ordonnee des valeurs singulieres
541  On note "cont_zeros" le nbre de valeurs quasi= a 0.
542  On note "vect" le rang de la plus petite valeur singliere
543  en valeur absolu
544  *****/
545 
546  vect = 0 ; cont_zeros = 0 ; cont = 0 ;
547  for (j=0; j < nc; j++) {
548  //if (fabs(sv[j]) == svSorted[cont]) vect = 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 ;
551  }
552 
553  if (cont_zeros > 5) {
554  // printf("erreur dans le rang de la matrice: %d \r\n ",7-cont_zeros);
555  HLM2D(nb_pts,pd,p,H);
556  }
557  else
558  {
559 
560  // estimation de a = 1,b,c ; je cherche le min de somme(i=1:n) (0.5*(ei)^2)
561  // e1 = V[1][.] * b - V[3][.] = 0 ;
562  // e2 = V[2][.] * c - V[3][.] = 0 ;
563  // e3 = V[2][.] * b - V[3][.] * c = 0 ;
564  // e4 = V[4][.] * b - V[5][.] = 0 ;
565  // e5 = V[4][.] * c - V[6][.] = 0 ;
566  // e6 = V[6][.] * b - V[5][.] * c = 0 ;
567  // e7 = V[7][.] * b - V[8][.] = 0 ;
568  // e8 = V[7][.] * c - V[9][.] = 0 ;
569  d[0] = V[2][vect] ;
570  d[1] = V[4][vect] ;
571  d[2] = V[1][vect] ;
572  d[3] = V[0][vect] ;
573  d[4] = V[3][vect] ;
574  d[5] = V[4][vect] ;
575  d[6] = V[0][vect] ;
576  d[7] = V[1][vect] ;
577 
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
582  ;
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] ;
587 
588 
589 
591  cp = c.pseudoInverse(1e-6) ;
592 
593 
594  vpColVector H_nr(3), temp ; // Homographie diagonale
595  // Multiplication de la matrice H_nr par le vecteur cp
596  temp = cp * d;
597 
598  H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
599  H_nr[2] = 1.0 ;
600 
601  vpMatrix T(9,3) ; T =0 ;
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] ;
611 
612 
613  vpMatrix Hd(3,3) ; // diag(gu,gv,gw)
614  for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
615 
616  // H = M diag(gu,gv,gw) M*-1
617  H = M*Hd*Mdp ;
618 
619 
620 
621  }
622 }
623 
624 void
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,
628  vpMatrix &H)
629 {
630  unsigned int nbpt = (unsigned int)xm.size();
631 
632  /****
633  on regarde si il y a au moins un point mais pour l'homographie
634  il faut au moins quatre points
635  ****/
636  vpMatrix pd(nbpt,3) ;
637  vpMatrix p(nbpt,3) ;
638 
639  for (unsigned int i=0;i<nbpt;i++) {
640  /****
641  on assigne les points fournies par la structure robot
642  pour la commande globale
643  ****/
644  pd[i][0] = xmi[i];
645  pd[i][1] = ymi[i];
646  pd[i][2] = 1.0 ;
647  p[i][0] = xm[i];
648  p[i][1] = ym[i];
649  p[i][2] = 1.0 ;
650  }
651 
652  switch (q_cible) {
653  case (1):
654  case (2):
655  /* La cible est planaire de type points */
656 
657  HLM2D(nbpt,pd,p,H);
658 
659  break;
660  case (3) : /* cible non planaire : chateau */
661  /* cible non planaire de type points */
662  HLM3D(nbpt,pd,p,H);
663  break;
664  } /* fin switch */
665 
666 
667 
668 } /* fin procedure calcul_homogaphie */
669 
670 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
671 
693 void vpHomography::HLM(const std::vector<double> &xb, const std::vector<double> &yb,
694  const std::vector<double> &xa, const std::vector<double> &ya,
695  bool isplanar,
696  vpHomography &aHb)
697 {
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"));
702 
703  // 4 point are required
704  if(n<4)
705  throw(vpException(vpException::fatalError, "There must be at least 4 matched points"));
706 
707  // The reference plane is the plane build from the 3 first points.
708  unsigned int q_cible;
709  vpMatrix H; // matrice d'homographie en metre
710 
711  if (isplanar)
712  q_cible =1;
713  else
714  q_cible =3;
715 
716  ::HLM(q_cible, xa, ya, xb, yb, H) ;
717 
718  aHb = H;
719 }
720 
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:92
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
error that can be emited by ViSP classes.
Definition: vpException.h:73
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)
Definition: vpMath.h:141
Implementation of an homography and operations on homographies.
Definition: vpHomography.h:179
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1646
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
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.
Definition: vpMatrix.cpp:1756