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