Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpHomographyMalis.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 
123  /* Construction des matrices de changement de repere */
124  vpMatrix Md(3,3) ;
125  vpMatrix Mp(3,3) ;
126 
127  for (i=0;i<3;i++) {
128  for (j=0;j<3;j++) {
129  M[j][i] = p[pts_ref[i]][j] ;
130  Md[j][i] = pd[pts_ref[i]][j] ;
131  }
132  }
133 
134  /*calcul de la pseudo inverse */
135  Mp= M.pseudoInverse(1e-16) ;
136  Mdp = Md.pseudoInverse(1e-16) ;
137 
138  if (pts_ref[3] > 0) {
139  double lamb_des[3];
140  double lamb_cour[3];
141 
142  for (i=0;i<3;i++) {
143  for (j=0;j<3;j++) {
144  lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
145  lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
146  }
147  }
148 
149  for (i=0;i<3;i++) {
150  for (j=0;j<3;j++) {
151  M[i][j] = M[i][j]*lamb_cour[j] ;
152  Md[i][j] = Md[i][j]*lamb_des[j] ;
153  }
154  }
155 
156  Mdp = Md.pseudoInverse(1e-16);
157  }
158 
159 
160  /* changement de repere pour tous les points autres que
161  les trois points de reference */
162 
163  cont_pts = 0 ;
164  for (k=0;k<nb_pts;k++) {
165  if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
166  for (i=0;i<3;i++) {
167  pn[cont_pts][i] = 0.0 ;
168  pnd[cont_pts][i] = 0.0 ;
169  for (j=0;j<3;j++) {
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] ;
172  }
173  }
174  cont_pts = cont_pts + 1;
175  }
176  }
177 }
178 
179 
180 /**************************************************************************
181  * NOM :
182  * Homographie_CrvMafEstHomoPointsCible2D
183  *
184  * DESCRIPTION :
185  * Calcul de l'homographie entre une image courante et une image desiree dans le
186  * cas particulier d'une cible planaire de points (cible pi).
187  * Cette procedure est appellee par "Homographie_CrvMafCalculHomographie".
188  *
189  ****************************************************************************
190  * ENTREES :
191  * int Nb_pts : nombre de points
192  * double **pd : tableau des coordonnees des points desires
193  * couble **p : tableau des coordonnees des points courants
194  *
195  * SORTIES :
196  *
197  * double **H matrice d homographie
198  *
199  ****************************************************************************
200  * AUTEUR : BOSSARD Nicolas. INSA Rennes 5eme annee.
201  *
202  * DATE DE CREATION : 02/12/98
203  *
204  * DATES DE MISE A JOUR :
205  *
206  ****************************************************************************/
207 void
208 HLM2D(unsigned int nb_pts,
209  vpMatrix &points_des,
210  vpMatrix &points_cour,
211  vpMatrix &H)
212 {
213  unsigned int i,j ;
214 
215  double vals_inf ;
216  unsigned int contZeros, vect;
217 
219  vpMatrix M(3*nb_pts,9) ;
220  vpMatrix V(9,9) ;
221  vpColVector sv(9) ;
222 
224  for (j=0; j<nb_pts ;j++) {
225  M[3*j][0] = 0 ;
226  M[3*j][1] = 0 ;
227  M[3*j][2] = 0 ;
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] ;
234 
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] ;
238  M[3*j+1][3] = 0 ;
239  M[3*j+1][4] = 0 ;
240  M[3*j+1][5] = 0 ;
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] ;
244 
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] ;
251  M[3*j+2][6] = 0 ;
252  M[3*j+2][7] = 0 ;
253  M[3*j+2][8] = 0 ;
254  }
255 
257  M.svd(sv,V);
258 
259  /*****
260  La meilleure solution est le vecteur de V associe
261  a la valeur singuliere la plus petite en valeur absolu.
262  Pour cela on parcourt la matrice des valeurs singulieres
263  et on repere la plus petite valeur singuliere, on en profite
264  pour effectuer un controle sur le rang de la matrice : pas plus
265  de 2 valeurs singulieres quasi=0
266  *****/
267  vals_inf = fabs(sv[0]) ;
268  vect = 0 ;
269  contZeros = 0;
270  if (fabs(sv[0]) < eps) {
271  contZeros = contZeros + 1 ;
272  }
273  for (j=1; j<9; j++) {
274  if (fabs(sv[j]) < vals_inf) {
275  vals_inf = fabs(sv[j]);
276  vect = j ;
277  }
278  if (fabs(sv[j]) < eps) {
279  contZeros = contZeros + 1 ;
280  }
281  }
282 
283 
285  if (contZeros > 2) {
286  //vpERROR_TRACE("matrix is rank deficient");
288  "matrix is rank deficient"));
289  }
290 
291  H.resize(3,3) ;
293  for (i=0; i<3; i++) {
294  for (j=0; j<3; j++){
295  H[i][j] = V[3*i+j][vect];
296  }
297  }
298 
299 
300 }
301 
302 
303 /**************************************************************************
304  * NOM :
305  * Homographie_CrvMafEstHomoPointsC3DEzio
306  *
307  * DESCRIPTION :
308  * Calcul de l'homographie entre une image courante et une image desiree dans le
309  * cas particulier d'une cible non planaire de points (cible pi).
310  * Cette procedure est appellee par "Homographie_CrvMafCalculHomographie".
311  *
312  *
313  ****************************************************************************
314  * ENTREES :
315  * int Nb_pts : nombre de points
316  * double **pd : tableau des coordonnees des points desires
317  * couble **p : tableau des coordonnees des points courants
318  *
319  * SORTIES :
320  *
321  * double **H matrice d'homographie
322  * double epipole[3] epipole
323  *
324  ****************************************************************************
325  **/
326 void
327 HLM3D(unsigned int nb_pts,
328  vpMatrix &pd,
329  vpMatrix &p,
330  vpMatrix &H)
331 {
332  unsigned int i,j,k,ii,jj ;
333  unsigned int cont_pts; /* Pour compter le nombre de points dans l'image */
334  //unsigned int nl; /*** Nombre de lignes ***/
335  unsigned int nc ; /*** Nombre de colonnes ***/
336  unsigned int pts_ref[4]; /*** definit lesquels des points de
337  l'image sont les points de reference***/
338  /*** ***/
339  unsigned int perm; /*** Compte le nombre de permutations, quand le nombre
340  de permutations =0 arret de l'ordonnancement **/
341  int cont_zeros; /*** pour compter les valeurs quasi= a zero ***/
342  unsigned int cont;
343  unsigned int vect;
344 
345  //int prob;
346 
347  /***** Corps de la fonction *****/
348 
349  /* allocation des matrices utilisees uniquement dans la procedure */
350  //prob=0;
351 
352  vpMatrix M(3,3) ;
353  vpMatrix Mdp(3,3) ;
354  vpMatrix c(8,2) ; // matrice des coeff C
355 
356  vpColVector d(8) ;
357  vpMatrix cp(2,8) ; //matrice pseudo-inverse de C
358 
359 
360  vpMatrix H_int(3,3) ;
361  vpMatrix pn((nb_pts-3),3) ; //points courant nouveau repere
362 
363 
364  vpMatrix pnd((nb_pts-3),3) ; //points derives nouveau repere
365 
366  /* preparation du changement de repere */
367  /****
368  comme plan de reference on choisit pour le moment
369  arbitrairement le plan contenant les points 1,2,3 du cinq
370  ****/
371  pts_ref[0] = 0 ;
372  pts_ref[1] = 1 ;
373  pts_ref[2] = 2 ;
374  pts_ref[3] = 0 ;
375 
376  /* changement de repere pour tous les points autres que les trois points de reference */
377 
378  changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
379 
380 
381  cont_pts = nb_pts - 3 ;
382 
383  if (cont_pts < 5)
384  {
385  //vpERROR_TRACE(" not enough point to compute the homography ... ");
387  "Not enough point to compute the homography"));
388  }
389 
390  //nl = cont_pts*(cont_pts-1)*(cont_pts-2)/6 ;
391  nc = 7 ;
392 
393  /* Allocation matrice CtC */
394  vpMatrix CtC(nc,nc) ;
395 
396  /* Initialisation matrice CtC */
397  for (i=0;i<nc;i++) for (j=0;j<nc;j++) CtC[i][j] = 0.0;
398 
399 
400  /* Allocation matrice M */
401  vpColVector C(nc) ; //Matrice des coefficients
402 
403  /* construction de la matrice M des coefficients dans le cas general */
404  /****
405  inconnues du nouveau algorithme
406  x1 = a ; x2 = b ; x3 = c ;
407  x4 = ex ; x5 = ey ; x6 = ez ;
408  qui deviennent apres changement :
409  v1 = x1*x6 ; v2 = x1*x5 ;
410  v3 = x2*x4 ; v4 = x2*x6 ;
411  v5 = x3*x5 ; v6 = x3*x4 ;
412  ****/
413  cont = 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 ++) {
417  /* coeff a^2*b */
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]) ; //
424  /* coeff a*b^2 */
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]) ;//
431  /* coeff a^2 */
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]) ; //
438 
439 
440 
441  /* coeff b^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]) ; //
448 
449  /* coeff a */
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]) ;//
456  /* coeff b */
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]) ;//
463  /* coeff a*b */
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]) ;//
476 
477  cont = cont+1 ;
478  /* construction de la matrice CtC */
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];
482  }
483  }
484 
485  }
486  }
487  }
488 
489 
490 
491  /* calcul de CtC */
492  for (i=0; i<nc ;i++) {
493  for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
494  }
495 
496  //nl = cont ; /* nombre de lignes */
497  nc = 7 ; /* nombre de colonnes */
498 
499  /* Creation de matrice CtC termine */
500  /* Allocation matrice V */
501  vpMatrix V(nc,nc) ;
502  /*****
503  Preparation au calcul de la svd (pseudo-inverse)
504  pour obtenir une solution il faut au moins 5 equations independantes
505  donc il faut au moins la mise en correspondence de 3+5 points
506  *****/
507  vpColVector sv(nc) ; //Vecteur contenant les valeurs singulieres
508 
509  CtC.svd(sv,V) ;
510 
511  /*****
512  Il faut un controle sur le rang de la matrice !!
513  La meilleure solution est le vecteur de V associe
514  a la valeur singuliere la plus petite en valeur
515  absolu
516  *****/
517 
518  vpColVector svSorted(nc) ; // sorted singular value
519 
520  // sorting the singular value
521  for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
522  perm = 1 ;
523  double v_temp;
524  while (perm != 0) {
525  perm = 0;
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 ;
531  perm = perm + 1;
532  }
533  }
534  }
535 
536  /*****
537  Parcours de la matrice ordonnee des valeurs singulieres
538  On note "cont_zeros" le nbre de valeurs quasi= a 0.
539  On note "vect" le rang de la plus petite valeur singliere
540  en valeur absolu
541  *****/
542 
543  vect = 0 ; cont_zeros = 0 ; cont = 0 ;
544  for (j=0; j < nc; j++) {
545  //if (fabs(sv[j]) == svSorted[cont]) vect = 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 ;
548  }
549 
550  if (cont_zeros > 5) {
551  // printf("erreur dans le rang de la matrice: %d \r\n ",7-cont_zeros);
552  HLM2D(nb_pts,pd,p,H);
553  }
554  else
555  {
556 
557  // estimation de a = 1,b,c ; je cherche le min de somme(i=1:n) (0.5*(ei)^2)
558  // e1 = V[1][.] * b - V[3][.] = 0 ;
559  // e2 = V[2][.] * c - V[3][.] = 0 ;
560  // e3 = V[2][.] * b - V[3][.] * c = 0 ;
561  // e4 = V[4][.] * b - V[5][.] = 0 ;
562  // e5 = V[4][.] * c - V[6][.] = 0 ;
563  // e6 = V[6][.] * b - V[5][.] * c = 0 ;
564  // e7 = V[7][.] * b - V[8][.] = 0 ;
565  // e8 = V[7][.] * c - V[9][.] = 0 ;
566  d[0] = V[2][vect] ;
567  d[1] = V[4][vect] ;
568  d[2] = V[1][vect] ;
569  d[3] = V[0][vect] ;
570  d[4] = V[3][vect] ;
571  d[5] = V[4][vect] ;
572  d[6] = V[0][vect] ;
573  d[7] = V[1][vect] ;
574 
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
579  ;
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] ;
584 
585 
586 
588  cp = c.pseudoInverse(1e-6) ;
589 
590 
591  vpColVector H_nr(3), temp ; // Homographie diagonale
592  // Multiplication de la matrice H_nr par le vecteur cp
593  temp = cp * d;
594 
595  H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
596  H_nr[2] = 1.0 ;
597 
598  vpMatrix T(9,3) ; T =0 ;
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] ;
608 
609 
610  vpMatrix Hd(3,3) ; // diag(gu,gv,gw)
611  for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
612 
613  // H = M diag(gu,gv,gw) M*-1
614  H = M*Hd*Mdp ;
615 
616 
617 
618  }
619 }
620 
621 void
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,
625  vpMatrix &H)
626 {
627  unsigned int nbpt = (unsigned int)xm.size();
628 
629  /****
630  on regarde si il y a au moins un point mais pour l'homographie
631  il faut au moins quatre points
632  ****/
633  vpMatrix pd(nbpt,3) ;
634  vpMatrix p(nbpt,3) ;
635 
636  for (unsigned int i=0;i<nbpt;i++) {
637  /****
638  on assigne les points fournies par la structure robot
639  pour la commande globale
640  ****/
641  pd[i][0] = xmi[i];
642  pd[i][1] = ymi[i];
643  pd[i][2] = 1.0 ;
644  p[i][0] = xm[i];
645  p[i][1] = ym[i];
646  p[i][2] = 1.0 ;
647  }
648 
649  switch (q_cible) {
650  case (1):
651  case (2):
652  /* La cible est planaire de type points */
653 
654  HLM2D(nbpt,pd,p,H);
655 
656  break;
657  case (3) : /* cible non planaire : chateau */
658  /* cible non planaire de type points */
659  HLM3D(nbpt,pd,p,H);
660  break;
661  } /* fin switch */
662 
663 
664 
665 } /* fin procedure calcul_homogaphie */
666 
667 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
668 
690 void vpHomography::HLM(const std::vector<double> &xb, const std::vector<double> &yb,
691  const std::vector<double> &xa, const std::vector<double> &ya,
692  bool isplanar,
693  vpHomography &aHb)
694 {
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"));
699 
700  // 4 point are required
701  if(n<4)
702  throw(vpException(vpException::fatalError, "There must be at least 4 matched points"));
703 
704  // The reference plane is the plane build from the 3 first points.
705  unsigned int q_cible;
706  vpMatrix H; // matrice d'homographie en metre
707 
708  if (isplanar)
709  q_cible =1;
710  else
711  q_cible =3;
712 
713  ::HLM(q_cible, xa, ya, xb, yb, H) ;
714 
715  aHb = H;
716 }
717 
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
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:140
Implementation of an homography and operations on homographies.
Definition: vpHomography.h:179
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1631
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:1741