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