ViSP  2.8.0
vpHomographyMalis.cpp
1 /****************************************************************************
2  *
3  * $Id: vpHomographyMalis.cpp 4276 2013-06-25 12:36:48Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Homography estimation.
36  *
37  * Authors:
38  * Eric Marchand
39  *
40  *****************************************************************************/
41 
42 
43 
55 #include <visp/vpHomography.h>
56 #include <visp/vpDebug.h>
57 #include <visp/vpMatrixException.h>
58 
59 #include <cmath> // std::fabs
60 #include <limits> // numeric_limits
61 
62 #ifndef DOXYGEN_SHOULD_SKIP_THIS
63 const double eps = 1e-6 ;
64 
65 /**************************************************************************
66  * NOM :
67  * changeFrame
68  *
69  * DESCRIPTION :
70  * Changement de repere Euclidien.
71  *
72  ****************************************************************************
73  * ENTREES :
74  * int pts_ref[4] : Definit quels sont les points de reference, ils ne
75  * seront pas affectes par le changement de repere
76  * int nb_pts : nombre de points a changer de repere
77  * double **pd : La matrice des coordonnees des points desires
78  * double **p : La matrice des coordonnees des points courants
79  *
80  *
81  * SORTIES :
82  *
83  * double **pt_des_nr : La matrice des coordonnees des points desires
84  * dans le nouveau repere.
85  * double **pt_cour_nr : La matrice des coordonnees des points courants
86  * dans le nouveau repere
87  * double **M : ??
88  * double **Mpd : pseudo inverse de M ..
89  *
90  *
91  ****************************************************************************
92  */
93 
94 
95 void changeFrame(unsigned int *pts_ref,
96  unsigned int nb_pts,
97  vpMatrix &pd, vpMatrix &p,
98  vpMatrix &pnd, vpMatrix &pn,
99  vpMatrix &M, vpMatrix &Mdp)
100 {
101 
102 
103 
104  unsigned int i,j, k ;
105  unsigned int cont_pts; /* */
106  double lamb_des[3]; /* */
107  double lamb_cour[3] ; /* */
108 
109 
110 
111  /* Construction des matrices de changement de repere */
112  vpMatrix Md(3,3) ;
113  vpMatrix Mp(3,3) ;
114 
115  for (i=0;i<3;i++) {
116  for (j=0;j<3;j++) {
117  M[j][i] = p[pts_ref[i]][j] ;
118  Md[j][i] = pd[pts_ref[i]][j] ;
119  }
120  }
121 
122  /*calcul de la pseudo inverse */
123  Mp= M.pseudoInverse(1e-16) ;
124  Mdp = Md.pseudoInverse(1e-16) ;
125 
126  if (pts_ref[3] > 0) {
127  for (i=0;i<3;i++) {
128  for (j=0;j<3;j++) {
129  lamb_cour[i] = Mp[i][j]*p[pts_ref[3]][j] ;
130  lamb_des[i] = Mdp[i][j]*pd[pts_ref[3]][j] ;
131  }
132  }
133 
134  for (i=0;i<3;i++) {
135  for (j=0;j<3;j++) {
136  M[i][j] = M[i][j]*lamb_cour[j] ;
137  Md[i][j] = Md[i][j]*lamb_des[j] ;
138  }
139  }
140 
141  Mdp = Md.pseudoInverse(1e-16);
142  }
143 
144 
145  /* changement de repere pour tous les points autres que
146  les trois points de reference */
147 
148  cont_pts = 0 ;
149  for (k=0;k<nb_pts;k++) {
150  if ((pts_ref[0] != k) && (pts_ref[1] != k) && (pts_ref[2] != k)) {
151  for (i=0;i<3;i++) {
152  pn[cont_pts][i] = 0.0 ;
153  pnd[cont_pts][i] = 0.0 ;
154  for (j=0;j<3;j++) {
155  pn[cont_pts][i] = pn[cont_pts][i] + Mp[i][j]*p[k][j] ;
156  pnd[cont_pts][i] = pnd[cont_pts][i] + Mdp[i][j]*pd[k][j] ;
157  }
158  }
159  cont_pts = cont_pts + 1;
160  }
161  }
162 
163 
164 }
165 
166 
167 /**************************************************************************
168  * NOM :
169  * Homographie_CrvMafEstHomoPointsCible2D
170  *
171  * DESCRIPTION :
172  * Calcul de l'homographie entre une image courante et une image desiree dans le
173  * cas particulier d'une cible planaire de points (cible pi).
174  * Cette procedure est appellee par "Homographie_CrvMafCalculHomographie".
175  *
176  ****************************************************************************
177  * ENTREES :
178  * int Nb_pts : nombre de points
179  * double **pd : tableau des coordonnees des points desires
180  * couble **p : tableau des coordonnees des points courants
181  *
182  * SORTIES :
183  *
184  * double **H matrice d homographie
185  *
186  ****************************************************************************
187  * AUTEUR : BOSSARD Nicolas. INSA Rennes 5eme annee.
188  *
189  * DATE DE CREATION : 02/12/98
190  *
191  * DATES DE MISE A JOUR :
192  *
193  ****************************************************************************/
194 void
195 HLM2D(unsigned int nb_pts,
196  vpMatrix &points_des,
197  vpMatrix &points_cour,
198  vpMatrix &H)
199 {
200  unsigned int i,j ;
201 
202  double vals_inf ;
203  unsigned int contZeros, vect;
204 
206  vpMatrix M(3*nb_pts,9) ;
207  vpMatrix V(9,9) ;
208  vpColVector sv(9) ;
209 
211  for (j=0; j<nb_pts ;j++) {
212  M[3*j][0] = 0 ;
213  M[3*j][1] = 0 ;
214  M[3*j][2] = 0 ;
215  M[3*j][3] = -points_des[j][0]*points_cour[j][2] ;
216  M[3*j][4] = -points_des[j][1]*points_cour[j][2] ;
217  M[3*j][5] = -points_des[j][2]*points_cour[j][2] ;
218  M[3*j][6] = points_des[j][0]*points_cour[j][1] ;
219  M[3*j][7] = points_des[j][1]*points_cour[j][1] ;
220  M[3*j][8] = points_des[j][2]*points_cour[j][1] ;
221 
222  M[3*j+1][0] = points_des[j][0]*points_cour[j][2] ;
223  M[3*j+1][1] = points_des[j][1]*points_cour[j][2] ;
224  M[3*j+1][2] = points_des[j][2]*points_cour[j][2] ;
225  M[3*j+1][3] = 0 ;
226  M[3*j+1][4] = 0 ;
227  M[3*j+1][5] = 0 ;
228  M[3*j+1][6] = -points_des[j][0]*points_cour[j][0] ;
229  M[3*j+1][7] = -points_des[j][1]*points_cour[j][0] ;
230  M[3*j+1][8] = -points_des[j][2]*points_cour[j][0] ;
231 
232  M[3*j+2][0] = -points_des[j][0]*points_cour[j][1] ;
233  M[3*j+2][1] = -points_des[j][1]*points_cour[j][1] ;
234  M[3*j+2][2] = -points_des[j][2]*points_cour[j][1] ;
235  M[3*j+2][3] = points_des[j][0]*points_cour[j][0] ;
236  M[3*j+2][4] = points_des[j][1]*points_cour[j][0] ;
237  M[3*j+2][5] = points_des[j][2]*points_cour[j][0] ;
238  M[3*j+2][6] = 0 ;
239  M[3*j+2][7] = 0 ;
240  M[3*j+2][8] = 0 ;
241  }
242 
244  M.svd(sv,V);
245 
246  /*****
247  La meilleure solution est le vecteur de V associe
248  a la valeur singuliere la plus petite en valeur absolu.
249  Pour cela on parcourt la matrice des valeurs singulieres
250  et on repère la plus petite valeur singulière, on en profite
251  pour effectuer un controle sur le rang de la matrice : pas plus
252  de 2 valeurs singulières quasi=0
253  *****/
254  vals_inf = fabs(sv[0]) ;
255  vect = 0 ;
256  contZeros = 0;
257  if (fabs(sv[0]) < eps) {
258  contZeros = contZeros + 1 ;
259  }
260  for (j=1; j<9; j++) {
261  if (fabs(sv[j]) < vals_inf) {
262  vals_inf = fabs(sv[j]);
263  vect = j ;
264  }
265  if (fabs(sv[j]) < eps) {
266  contZeros = contZeros + 1 ;
267  }
268  }
269 
270 
272  if (contZeros > 2) {
273  //vpERROR_TRACE("matrix is rank deficient");
275  "matrix is rank deficient"));
276  }
277 
278  H.resize(3,3) ;
280  for (i=0; i<3; i++) {
281  for (j=0; j<3; j++){
282  H[i][j] = V[3*i+j][vect];
283  }
284  }
285 
286 
287 }
288 
289 
290 /**************************************************************************
291  * NOM :
292  * Homographie_CrvMafEstHomoPointsC3DEzio
293  *
294  * DESCRIPTION :
295  * Calcul de l'homographie entre une image courante et une image desiree dans le
296  * cas particulier d'une cible non planaire de points (cible pi).
297  * Cette procedure est appellee par "Homographie_CrvMafCalculHomographie".
298  *
299  *
300  ****************************************************************************
301  * ENTREES :
302  * int Nb_pts : nombre de points
303  * double **pd : tableau des coordonnees des points desires
304  * couble **p : tableau des coordonnees des points courants
305  *
306  * SORTIES :
307  *
308  * double **H matrice d'homographie
309  * double epipole[3] epipole
310  *
311  ****************************************************************************
312  **/
313 void
314 HLM3D(unsigned int nb_pts,
315  vpMatrix &pd,
316  vpMatrix &p,
317  vpMatrix &H)
318 {
319  unsigned int i,j,k,ii,jj ;
320  unsigned int cont_pts; /* Pour compter le nombre de points dans l'image */
321  //unsigned int nl; /*** Nombre de lignes ***/
322  unsigned int nc ; /*** Nombre de colonnes ***/
323  unsigned int pts_ref[4]; /*** définit lesquels des points de
324  l'image sont les points de référence***/
325  /*** ***/
326  int perm; /*** Compte le nombre de permutations, quand le nombre
327  de permutations =0 arret de l'ordonnancement **/
328  int cont_zeros; /*** pour compter les valeurs quasi= a zero ***/
329  unsigned int cont;
330  unsigned int vect;
331 
332  //int prob;
333 
334  /***** Corps de la fonction *****/
335 
336  /* allocation des matrices utilisees uniquement dans la procedure */
337  //prob=0;
338 
339  vpMatrix M(3,3) ;
340  vpMatrix Mdp(3,3) ;
341  vpMatrix c(8,2) ; // matrice des coeff C
342 
343  vpColVector d(8) ;
344  vpMatrix cp(2,8) ; //matrice pseudo-inverse de C
345 
346 
347  vpMatrix H_int(3,3) ;
348  vpMatrix pn((nb_pts-3),3) ; //points courant nouveau repère
349 
350 
351  vpMatrix pnd((nb_pts-3),3) ; //points dérivés nouveau repère
352 
353  /* preparation du changement de repere */
354  /****
355  comme plan de reference on choisit pour le moment
356  arbitrairement le plan contenant les points 1,2,3 du cinq
357  ****/
358  pts_ref[0] = 0 ;
359  pts_ref[1] = 1 ;
360  pts_ref[2] = 2 ;
361  pts_ref[3] = 0 ;
362 
363  /* changement de repere pour tous les points autres que les trois points de reference */
364 
365  changeFrame(pts_ref,nb_pts,pd,p,pnd,pn,M,Mdp);
366 
367 
368  cont_pts = nb_pts - 3 ;
369 
370  if (cont_pts < 5)
371  {
372  //vpERROR_TRACE(" not enough point to compute the homography ... ");
374  "Not enough point to compute the homography"));
375  }
376 
377  //nl = cont_pts*(cont_pts-1)*(cont_pts-2)/6 ;
378  nc = 7 ;
379 
380  /* Allocation matrice CtC */
381  vpMatrix CtC(nc,nc) ;
382 
383  /* Initialisation matrice CtC */
384  for (i=0;i<nc;i++) for (j=0;j<nc;j++) CtC[i][j] = 0.0;
385 
386 
387  /* Allocation matrice M */
388  vpColVector C(nc) ; //Matrice des coefficients
389 
390  /* construction de la matrice M des coefficients dans le cas general */
391  /****
392  inconnues du nouveau algorithme
393  x1 = a ; x2 = b ; x3 = c ;
394  x4 = ex ; x5 = ey ; x6 = ez ;
395  qui deviennent apres changement :
396  v1 = x1*x6 ; v2 = x1*x5 ;
397  v3 = x2*x4 ; v4 = x2*x6 ;
398  v5 = x3*x5 ; v6 = x3*x4 ;
399  ****/
400  cont = 0 ;
401  for (i=0 ; i<nb_pts-5; i++) {
402  for (j = i+1 ; j<nb_pts-4; j++) {
403  for (k = j+1 ; k<nb_pts-3; k ++) {
404  /* coeff a^2*b */
405  C[0] = pn[i][2]*pn[j][2]*pn[k][1]*pnd[k][0] //
406  * (pnd[j][0]*pnd[i][1] - pnd[j][1]*pnd[i][0])//
407  + pn[i][2]*pn[k][2]*pn[j][1]*pnd[j][0]//
408  *(pnd[i][0]*pnd[k][1] - pnd[i][1]*pnd[k][0])//
409  + pn[j][2]*pn[k][2]*pn[i][1]*pnd[i][0] //
410  *(pnd[k][0]*pnd[j][1] - pnd[k][1]*pnd[j][0]) ; //
411  /* coeff a*b^2 */
412  C[1] = pn[i][2]*pn[j][2]*pn[k][0]*pnd[k][1]//
413  *(pnd[i][0]*pnd[j][1] - pnd[i][1]*pnd[j][0])//
414  + pn[i][2]*pn[k][2]*pn[j][0]*pnd[j][1]//
415  *(pnd[k][0]*pnd[i][1] - pnd[k][1]*pnd[i][0])//
416  + pn[j][2]*pn[k][2]*pn[i][0]*pnd[i][1]//
417  *(pnd[j][0]*pnd[k][1] - pnd[j][1]*pnd[k][0]) ;//
418  /* coeff a^2 */
419  C[2] = + pn[i][1]*pn[k][1]*pn[j][2]*pnd[j][0]//
420  *(pnd[k][2]*pnd[i][0] - pnd[k][0]*pnd[i][2])//
421  +pn[i][1]*pn[j][1]*pn[k][2]*pnd[k][0] //
422  *(pnd[i][2]*pnd[j][0] - pnd[i][0]*pnd[j][2])
423  + pn[j][1]*pn[k][1]*pn[i][2]*pnd[i][0] //
424  *(pnd[j][2]*pnd[k][0] - pnd[j][0]*pnd[k][2]) ; //
425 
426 
427 
428  /* coeff b^2 */
429  C[3] = pn[i][0]*pn[j][0]*pn[k][2]*pnd[k][1] //
430  *(pnd[i][2]*pnd[j][1] - pnd[i][1]*pnd[j][2]) //
431  + pn[i][0]*pn[k][0]*pn[j][2]*pnd[j][1] //
432  *(pnd[k][2]*pnd[i][1] - pnd[k][1]*pnd[i][2]) //
433  + pn[j][0]*pn[k][0]*pn[i][2]*pnd[i][1] //
434  *(pnd[j][2]*pnd[k][1] - pnd[j][1]*pnd[k][2]) ; //
435 
436  /* coeff a */
437  C[5] = pn[i][1]*pn[j][1]*pn[k][0]*pnd[k][2]//
438  *(pnd[i][0]*pnd[j][2] - pnd[i][2]*pnd[j][0])//
439  + pn[i][1]*pn[k][1]*pn[j][0]*pnd[j][2] //
440  *(pnd[k][0]*pnd[i][2] - pnd[k][2]*pnd[i][0])//
441  + pn[j][1]*pn[k][1]*pn[i][0]*pnd[i][2]//
442  *(pnd[j][0]*pnd[k][2] - pnd[j][2]*pnd[k][0]) ;//
443  /* coeff b */
444  C[6] = pn[i][0]*pn[j][0]*pn[k][1]*pnd[k][2] //
445  *(pnd[i][1]*pnd[j][2] - pnd[i][2]*pnd[j][1])//
446  + pn[i][0]*pn[k][0]*pn[j][1]*pnd[j][2]//
447  *(pnd[k][1]*pnd[i][2] - pnd[k][2]*pnd[i][1])//
448  + pn[j][0]*pn[k][0]*pn[i][1]*pnd[i][2]//
449  *(pnd[j][1]*pnd[k][2] - pnd[j][2]*pnd[k][1]) ;//
450  /* coeff a*b */
451  C[4] = pn[i][0]*pn[k][1]*pn[j][2] //
452  *(pnd[k][0]*pnd[j][1]*pnd[i][2] - pnd[j][0]*pnd[i][1]*pnd[k][2])//
453  + pn[k][0]*pn[i][1]*pn[j][2]//
454  *(pnd[j][0]*pnd[k][1]*pnd[i][2] - pnd[i][0]*pnd[j][1]*pnd[k][2])//
455  + pn[i][0]*pn[j][1]*pn[k][2]//
456  *(pnd[k][0]*pnd[i][1]*pnd[j][2] - pnd[j][0]*pnd[k][1]*pnd[i][2])//
457  + pn[j][0]*pn[i][1]*pn[k][2]//
458  *(pnd[i][0]*pnd[k][1]*pnd[j][2] - pnd[k][0]*pnd[j][1]*pnd[i][2])//
459  + pn[k][0]*pn[j][1]*pn[i][2]//
460  *(pnd[j][0]*pnd[i][1]*pnd[k][2] - pnd[i][0]*pnd[k][1]*pnd[j][2])//
461  + pn[j][0]*pn[k][1]*pn[i][2]//
462  *(pnd[i][0]*pnd[j][1]*pnd[k][2] - pnd[k][0]*pnd[i][1]*pnd[j][2]) ;//
463 
464  cont = cont+1 ;
465  /* construction de la matrice CtC */
466  for (ii=0;ii<nc;ii++) {
467  for (jj=ii;jj<nc;jj++) {
468  CtC[ii][jj] = CtC[ii][jj] + C[ii]*C[jj];
469  }
470  }
471 
472  }
473  }
474  }
475 
476 
477 
478  /* calcul de CtC */
479  for (i=0; i<nc ;i++) {
480  for (j=i+1; j<nc ;j++) CtC[j][i] = CtC[i][j];
481  }
482 
483  //nl = cont ; /* nombre de lignes */
484  nc = 7 ; /* nombre de colonnes */
485 
486  /* Creation de matrice CtC termine */
487  /* Allocation matrice V */
488  vpMatrix V(nc,nc) ;
489  /*****
490  Preparation au calcul de la svd (pseudo-inverse)
491  pour obtenir une solution il faut au moins 5 equations independantes
492  donc il faut au moins la mise en correspondence de 3+5 points
493  *****/
494  vpColVector sv(nc) ; //Vecteur contenant les valeurs singulières
495 
496  CtC.svd(sv,V) ;
497 
498  /*****
499  Il faut un controle sur le rang de la matrice !!
500  La meilleure solution est le vecteur de V associe
501  a la valeur singuliere la plus petite en valeur
502  absolu
503  *****/
504 
505  vpColVector svSorted(nc) ; // sorted singular value
506 
507  // sorting the singular value
508  for (i=0; i < nc ;i++) svSorted[i] = sv[i] ;
509  perm = 1 ;
510  double v_temp;
511  while (perm != 0) {
512  perm = 0;
513  for (i=1; i < nc ;i++) {
514  if (svSorted[i-1] > svSorted[i]) {
515  v_temp = svSorted[i-1] ;
516  svSorted[i-1] = svSorted[i] ;
517  svSorted[i] = v_temp ;
518  perm = perm + 1;
519  }
520  }
521  }
522 
523  /*****
524  Parcours de la matrice ordonnée des valeurs singulières
525  On note "cont_zeros" le nbre de valeurs quasi= à 0.
526  On note "vect" le rang de la plus petite valeur singlière
527  en valeur absolu
528  *****/
529 
530  vect = 0 ; cont_zeros = 0 ; cont = 0 ;
531  for (j=0; j < nc; j++) {
532  //if (fabs(sv[j]) == svSorted[cont]) vect = j ;
533  if (std::fabs(sv[j]-svSorted[cont]) <= std::fabs(vpMath::maximum(sv[j],svSorted[cont]))) vect = j ;
534  if (std::fabs(sv[j]/svSorted[nc-1]) < eps) cont_zeros = cont_zeros + 1 ;
535  }
536 
537  if (cont_zeros > 5) {
538  // printf("erreur dans le rang de la matrice: %d \r\n ",7-cont_zeros);
539  HLM2D(nb_pts,pd,p,H);
540  }
541  else
542  {
543 
544  // estimation de a = 1,b,c ; je cherche le min de somme(i=1:n) (0.5*(ei)^2)
545  // e1 = V[1][.] * b - V[3][.] = 0 ;
546  // e2 = V[2][.] * c - V[3][.] = 0 ;
547  // e3 = V[2][.] * b - V[3][.] * c = 0 ;
548  // e4 = V[4][.] * b - V[5][.] = 0 ;
549  // e5 = V[4][.] * c - V[6][.] = 0 ;
550  // e6 = V[6][.] * b - V[5][.] * c = 0 ;
551  // e7 = V[7][.] * b - V[8][.] = 0 ;
552  // e8 = V[7][.] * c - V[9][.] = 0 ;
553  d[0] = V[2][vect] ;
554  d[1] = V[4][vect] ;
555  d[2] = V[1][vect] ;
556  d[3] = V[0][vect] ;
557  d[4] = V[3][vect] ;
558  d[5] = V[4][vect] ;
559  d[6] = V[0][vect] ;
560  d[7] = V[1][vect] ;
561 
562  c[0][0] = V[5][vect] ; c[0][1] = 0.0 ;
563  c[1][0] = V[6][vect] ; c[1][1] = 0.0 ;
564  c[2][0] = V[3][vect] ; c[2][1] = 0.0 ;
565  c[3][0] = V[4][vect] ; c[3][1] = 0.0
566  ;
567  c[4][0] = 0.0 ; c[4][1] = V[6][vect] ;
568  c[5][0] = 0.0 ; c[5][1] = V[5][vect] ;
569  c[6][0] = 0.0 ; c[6][1] = V[2][vect] ;
570  c[7][0] = 0.0 ; c[7][1] = V[4][vect] ;
571 
572 
573 
575  cp = c.pseudoInverse(1e-6) ;
576 
577 
578  vpColVector H_nr(3), temp ; // Homographie diagonale
579  // Multiplication de la matrice H_nr par le vecteur cp
580  temp = cp * d;
581 
582  H_nr[0] = temp[0] ; H_nr[1] = temp[1] ;
583  H_nr[2] = 1.0 ;
584 
585  vpMatrix T(9,3) ; T =0 ;
586  T[0][0] = -V[1][vect] ; T[0][1] = V[0][vect] ;
587  T[1][0] = V[4][vect] ; T[1][2] = -V[2][vect] ;
588  T[2][0] = -V[6][vect] ; T[2][1] = V[2][vect] ;
589  T[3][0] = V[6][vect] ; T[3][2] = -V[0][vect] ;
590  T[4][0] = -V[3][vect] ; T[4][1] = V[6][vect] ;
591  T[5][0] = V[3][vect] ; T[5][2] = -V[1][vect] ;
592  T[6][0] = -V[5][vect] ; T[6][1] = V[4][vect] ;
593  T[7][0] = V[5][vect] ; T[7][2] = -V[6][vect] ;
594  T[8][1] = -V[5][vect] ; T[8][2] = V[2][vect] ;
595 
596 
597  vpMatrix Hd(3,3) ; // diag(gu,gv,gw)
598  for (i=0 ; i < 3 ; i++) Hd[i][i] = H_nr[i] ;
599 
600  // H = M diag(gu,gv,gw) M*-1
601  H = M*Hd*Mdp ;
602 
603 
604 
605  }
606 }
607 
608 
609 /**************************************************************************
610  * NOM :
611  * Homographie_CrvMafCalculHomographie
612  *
613  * DESCRIPTION :
614  * Calcul de l'homographie, en fonction de la cible désirée et de la cible
615  * en cours. C'est une estimation linéaire.
616  * Cette procédure n'effectue pas elle-même le calcul de l'homographie :
617  * elle se contente d'appeler la bonne sous-procédure.
618  * Cette procédure est appellée par "crv_maf_calcul_tomographie".
619  *
620  ****************************************************************************
621  * ENTREES :
622  * STR_CIBLE_ASSER *cible_asser Pointeur sur structure contenant les
623  * commandes du robot, les données de la
624  * carte...
625  * Voir "cvda/edixaa/param/robot.h"
626  * STR_VITESSE_ROBOT *data_common Pointeur sur la structure décrivant la
627  * cible d'asservissement.
628  * Voir "cvda/edixia/param/param.h"
629  * STR_MACH_DIV *machine_div Pointeur sur structure contenant divers
630  * paramètres de configuration du robot.
631  * Voir "cvda/edixia/param/param.h"
632  *
633  * SORTIES :
634  *
635  * double **H matrice d'homographie
636 
637  *
638  ****************************************************************************
639  * AUTEUR : BOSSARD Nicolas. INSA Rennes 5ème année.
640  *
641  * DATE DE CREATION : 01/12/98
642  *
643  * DATES DE MISE A JOUR :
644  *
645  ****************************************************************************/
646 void
647 HLM(unsigned int q_cible,
648  unsigned int nbpt,
649  double *xm, double *ym,
650  double *xmi, double *ymi,
651  vpMatrix &H)
652 {
653  unsigned int i;
654 
655  /****
656  on regarde si il y a au moins un point mais pour l'homographie
657  il faut au moins quatre points
658  ****/
659  vpMatrix pd(nbpt,3) ;
660  vpMatrix p(nbpt,3) ;
661 
662  for (i=0;i<nbpt;i++) {
663  /****
664  on assigne les points fournies par la structure robot
665  pour la commande globale
666  ****/
667  pd[i][0] = xmi[i];
668  pd[i][1] = ymi[i];
669  pd[i][2] = 1.0 ;
670  p[i][0] = xm[i];
671  p[i][1] = ym[i];
672  p[i][2] = 1.0 ;
673  }
674 
675 
676  switch (q_cible) {
677  case (1):
678  case (2):
679  /* La cible est planaire de type points */
680 
681  HLM2D(nbpt,pd,p,H);
682 
683  break;
684  case (3) : /* cible non planaire : chateau */
685  /* cible non planaire de type points */
686  HLM3D(nbpt,pd,p,H);
687  break;
688  } /* fin switch */
689 
690 
691 
692 } /* fin procedure calcul_homogaphie */
693 
694 
695 #endif
696 
714 void vpHomography::HLM(unsigned int n,
715  double *xb, double *yb,
716  double *xa, double *ya ,
717  bool isplanar,
718  vpHomography &aHb)
719 {
720 #ifndef DOXYGEN_SHOULD_SKIP_THIS
721 
722  unsigned int i,j;
723  unsigned int q_cible;
724  vpMatrix H; // matrice d'homographie en metre
725 
726  aHb.setIdentity();
727 
728 
729  if (isplanar)
730  q_cible =1;
731  else
732  q_cible =3;
733 
734  ::HLM(q_cible,n, xa,ya,xb,yb,H) ;
735 
736  for(i=0;i<3;i++)
737  for(j=0;j<3;j++)
738  aHb[i][j] = H[i][j];
739 
740 #endif
741 }
742 
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:174
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
This class aims to compute the homography wrt.two images.
Definition: vpHomography.h:173
void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:1110
void svd(vpColVector &w, vpMatrix &v)
Definition: vpMatrix.cpp:1702
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...
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:1812