Visual Servoing Platform  version 3.1.0
vpPoseDementhon.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 modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Pose computation.
33  *
34  * Authors:
35  * Eric Marchand
36  * Francois Chaumette
37  *
38  *****************************************************************************/
39 
40 #include <visp3/core/vpMath.h>
41 #include <visp3/vision/vpPose.h>
42 
43 #define DEBUG_LEVEL1 0
44 #define DEBUG_LEVEL2 0
45 #define DEBUG_LEVEL3 0
46 
47 /* FC
48 #ifndef DEG
49 #define DEG (180.0/M_PI)
50 #endif
51 */
52 
61 {
62  double normI = 0., normJ = 0.;
63  double Z0 = 0.;
64  // double seuil=1.0;
65  double f = 1.;
66 
67  vpPoint p0 = listP.front();
68 
69  c3d.clear();
70  vpPoint P;
71  for (std::list<vpPoint>::const_iterator it = listP.begin(); it != listP.end(); ++it) {
72  P = (*it);
73  P.set_oX(P.get_oX() - p0.get_oX());
74  P.set_oY(P.get_oY() - p0.get_oY());
75  P.set_oZ(P.get_oZ() - p0.get_oZ());
76  c3d.push_back(P);
77  }
78 
79  vpMatrix a(npt, 3);
80 
81  for (unsigned int i = 0; i < npt; i++) {
82  a[i][0] = c3d[i].get_oX();
83  a[i][1] = c3d[i].get_oY();
84  a[i][2] = c3d[i].get_oZ();
85  }
86 
87  // std::cout << a << std::endl ;
88  // calcul a^T a
89  vpMatrix ata;
90  ata = a.t() * a;
91 
92  // calcul (a^T a)^-1 par decomposition LU
93  vpMatrix ata1;
94  ata1 = ata.pseudoInverse(1e-6); // InverseByLU() ;
95 
96  vpMatrix b;
97  b = (a * ata1).t();
98 
99 #if (DEBUG_LEVEL2)
100  {
101  std::cout << "a" << std::endl << a << std::endl;
102  std::cout << "ata" << std::endl << ata << std::endl;
103  std::cout << "ata1" << std::endl << ata1 << std::endl;
104  std::cout << " ata*ata1" << std::endl << ata * ata1;
105  std::cout << " b" << std::endl << (a * ata1).t();
106  }
107 #endif
108 
109  // calcul de la premiere solution
110 
111  vpColVector eps(npt);
112  eps = 0;
113 
114  int cpt = 0;
115  vpColVector I, J, k;
116  I.resize(3);
117  J.resize(3);
118  k.resize(3);
119 
120  while (cpt < 20) {
121  I = 0;
122  J = 0;
123 
124  vpColVector xprim(npt);
125  vpColVector yprim(npt);
126  for (unsigned int i = 0; i < npt; i++) {
127  xprim[i] = (1 + eps[i]) * c3d[i].get_x() - c3d[0].get_x();
128  yprim[i] = (1 + eps[i]) * c3d[i].get_y() - c3d[0].get_y();
129  }
130  I = b * xprim;
131  J = b * yprim;
132  normI = sqrt(I.sumSquare());
133  normJ = sqrt(J.sumSquare());
134  I = I / normI;
135  J = J / normJ;
136 
137  if (normI + normJ < 1e-10) {
138  // vpERROR_TRACE(" normI+normJ = 0, division par zero " ) ;
140  "Division by zero in Dementhon pose computation: normI+normJ = 0"));
141  }
142 
143  k = vpColVector::cross(I, J);
144  Z0 = 2 * f / (normI + normJ);
145  cpt = cpt + 1; // seuil=0.0;
146  for (unsigned int i = 0; i < npt; i++) {
147  // double epsi_1 = eps[i] ;
148  eps[i] = (c3d[i].get_oX() * k[0] + c3d[i].get_oY() * k[1] + c3d[i].get_oZ() * k[2]) / Z0;
149  // seuil+=fabs(eps[i]-epsi_1);
150  }
151  if (npt == 0) {
152  // vpERROR_TRACE( " npt = 0, division par zero ");
153  throw(vpException(vpException::divideByZeroError, "Division by zero in Dementhon pose computation: no points"));
154  }
155  // seuil/=npt;
156  }
157  k.normalize();
158  J = vpColVector::cross(k, I);
159  /*matrice de passage*/
160 
161  cMo[0][0] = I[0];
162  cMo[0][1] = I[1];
163  cMo[0][2] = I[2];
164  cMo[0][3] = c3d[0].get_x() * 2 / (normI + normJ);
165 
166  cMo[1][0] = J[0];
167  cMo[1][1] = J[1];
168  cMo[1][2] = J[2];
169  cMo[1][3] = c3d[0].get_y() * 2 / (normI + normJ);
170 
171  cMo[2][0] = k[0];
172  cMo[2][1] = k[1];
173  cMo[2][2] = k[2];
174  cMo[2][3] = Z0;
175 
176  cMo[0][3] -= (p0.get_oX() * cMo[0][0] + p0.get_oY() * cMo[0][1] + p0.get_oZ() * cMo[0][2]);
177  cMo[1][3] -= (p0.get_oX() * cMo[1][0] + p0.get_oY() * cMo[1][1] + p0.get_oZ() * cMo[1][2]);
178  cMo[2][3] -= (p0.get_oX() * cMo[2][0] + p0.get_oY() * cMo[2][1] + p0.get_oZ() * cMo[2][2]);
179 }
180 
181 #define DMIN 0.01 /* distance min entre la cible et la camera */
182 #define EPS 0.0000001
183 #define EPS_DEM 0.001
184 
185 static void calculRTheta(double s, double c, double &r, double &theta)
186 {
187  if ((fabs(c) > EPS_DEM) || (fabs(s) > EPS_DEM)) {
188  r = sqrt(sqrt(s * s + c * c));
189  theta = atan2(s, c) / 2.0;
190  } else {
191  if (fabs(c) > fabs(s)) {
192  r = fabs(c);
193  if (c >= 0.0)
194  theta = M_PI / 2;
195  else
196  theta = -M_PI / 2;
197  } else {
198  r = fabs(s);
199  if (s >= 0.0)
200  theta = M_PI / 4.0;
201  else
202  theta = -M_PI / 4.0;
203  }
204  }
205 }
206 
207 static void calculSolutionDementhon(double xi0, double yi0, vpColVector &I, vpColVector &J, vpHomogeneousMatrix &cMo)
208 {
209 
210 #if (DEBUG_LEVEL1)
211  std::cout << "begin (Dementhon.cc)CalculSolutionDementhon() " << std::endl;
212 #endif
213 
214  double normI, normJ, normk, Z0;
215  vpColVector k(3);
216 
217  // normalisation de I et J
218  normI = sqrt(I.sumSquare());
219  normJ = sqrt(J.sumSquare());
220 
221  I /= normI;
222  J /= normJ;
223 
224  k = vpColVector::cross(I, J); // k = I^I
225 
226  Z0 = 2.0 / (normI + normJ);
227 
228  normk = sqrt(k.sumSquare());
229  k /= normk;
230 
231  J = vpColVector::cross(k, I);
232 
233  // calcul de la matrice de passage
234  cMo[0][0] = I[0];
235  cMo[0][1] = I[1];
236  cMo[0][2] = I[2];
237  cMo[0][3] = xi0 * Z0;
238 
239  cMo[1][0] = J[0];
240  cMo[1][1] = J[1];
241  cMo[1][2] = J[2];
242  cMo[1][3] = yi0 * Z0;
243 
244  cMo[2][0] = k[0];
245  cMo[2][1] = k[1];
246  cMo[2][2] = k[2];
247  cMo[2][3] = Z0;
248 
249 #if (DEBUG_LEVEL1)
250  std::cout << "end (Dementhon.cc)CalculSolutionDementhon() " << std::endl;
251 #endif
252 }
253 
255 {
256 
257 #if (DEBUG_LEVEL1)
258  std::cout << "begin vpPose::CalculArbreDementhon() " << std::endl;
259 #endif
260 
261  int erreur = 0;
262  double smin;
263  vpHomogeneousMatrix cMo1, cMo2, cMo_old;
264 
265  unsigned int iter_max = 20;
266  vpMatrix eps(iter_max + 1, npt);
267 
268  // on test si tous les points sont devant la camera
269  for (unsigned int i = 0; i < npt; i++) {
270  double z;
271  z = cMo[2][0] * c3d[i].get_oX() + cMo[2][1] * c3d[i].get_oY() + cMo[2][2] * c3d[i].get_oZ() + cMo[2][3];
272  if (z <= 0.0)
273  erreur = -1;
274  }
275 
276  smin = sqrt(computeResidualDementhon(cMo) / npt);
277 
278  vpColVector xi(npt);
279  vpColVector yi(npt);
280 
281  if (erreur == 0) {
282  unsigned int k = 0;
283  for (unsigned int i = 0; i < npt; i++) {
284  xi[k] = c3d[i].get_x();
285  yi[k] = c3d[i].get_y();
286 
287  if (k != 0) { // On ne prend pas le 1er point
288  eps[0][k] =
289  (cMo[2][0] * c3d[i].get_oX() + cMo[2][1] * c3d[i].get_oY() + cMo[2][2] * c3d[i].get_oZ()) / cMo[2][3];
290  }
291  k++;
292  }
293 
294  vpColVector I0(3);
295  vpColVector J0(3);
296  vpColVector I(3);
297  vpColVector J(3);
298 
299  double smin_old = 2 * smin;
300 
301  unsigned int cpt = 0;
302  while ((cpt < 20) && (smin_old > 0.01) && (smin <= smin_old)) {
303  double r, theta, s1, s2;
304 
305 #if (DEBUG_LEVEL2)
306  {
307  std::cout << "cpt " << cpt << std::endl;
308  std::cout << "smin_old " << smin_old << std::endl;
309  std::cout << "smin " << smin << std::endl;
310  }
311 #endif
312 
313  smin_old = smin;
314  cMo_old = cMo;
315 
316  I0 = 0;
317  J0 = 0;
318 
319  for (unsigned int i = 1; i < npt; i++) {
320  double s = (1.0 + eps[cpt][i]) * xi[i] - xi[0];
321  I0[0] += b[0][i - 1] * s;
322  I0[1] += b[1][i - 1] * s;
323  I0[2] += b[2][i - 1] * s;
324  s = (1.0 + eps[cpt][i]) * yi[i] - yi[0];
325  J0[0] += b[0][i - 1] * s;
326  J0[1] += b[1][i - 1] * s;
327  J0[2] += b[2][i - 1] * s;
328  }
329 
330  double s = -2.0 * (vpColVector::dotProd(I0, J0));
331  double c = J0.sumSquare() - I0.sumSquare();
332 
333  calculRTheta(s, c, r, theta);
334  double co = cos(theta);
335  double si = sin(theta);
336 
337  /* 1ere branche */
338  I = I0 + U * r * co;
339  J = J0 + U * r * si;
340 
341 #if (DEBUG_LEVEL3)
342  {
343  std::cout << "I " << I.t();
344  std::cout << "J " << J.t();
345  }
346 #endif
347 
348  calculSolutionDementhon(xi[0], yi[0], I, J, cMo1);
349  s1 = sqrt(computeResidualDementhon(cMo1) / npt);
350 #if (DEBUG_LEVEL3)
351  std::cout << "cMo1 " << std::endl << cMo1 << std::endl;
352 #endif
353 
354  /* 2eme branche */
355  I = I0 - U * r * co;
356  J = J0 - U * r * si;
357 #if (DEBUG_LEVEL3)
358  {
359  std::cout << "I " << I.t();
360  std::cout << "J " << J.t();
361  }
362 #endif
363 
364  calculSolutionDementhon(xi[0], yi[0], I, J, cMo2);
365  s2 = sqrt(computeResidualDementhon(cMo2) / npt);
366 #if (DEBUG_LEVEL3)
367  std::cout << "cMo2 " << std::endl << cMo2 << std::endl;
368 #endif
369 
370  cpt++;
371  if (s1 <= s2) {
372  smin = s1;
373  k = 0;
374  for (unsigned int i = 0; i < npt; i++) {
375  if (k != 0) { // On ne prend pas le 1er point
376  eps[cpt][k] = (cMo1[2][0] * c3d[i].get_oX() + cMo1[2][1] * c3d[i].get_oY() + cMo1[2][2] * c3d[i].get_oZ()) /
377  cMo1[2][3];
378  }
379  k++;
380  }
381  cMo = cMo1;
382  } else {
383  smin = s2;
384  k = 0;
385  for (unsigned int i = 0; i < npt; i++) {
386  if (k != 0) { // On ne prend pas le 1er point
387  eps[cpt][k] = (cMo2[2][0] * c3d[i].get_oX() + cMo2[2][1] * c3d[i].get_oY() + cMo2[2][2] * c3d[i].get_oZ()) /
388  cMo2[2][3];
389  }
390  k++;
391  }
392  cMo = cMo2;
393  }
394 
395  if (smin > smin_old) {
396 #if (DEBUG_LEVEL2)
397  std::cout << "Divergence " << std::endl;
398 #endif
399 
400  cMo = cMo_old;
401  }
402 #if (DEBUG_LEVEL2)
403  {
404  std::cout << "s1 = " << s1 << std::endl;
405  std::cout << "s2 = " << s2 << std::endl;
406  std::cout << "smin = " << smin << std::endl;
407  std::cout << "smin_old = " << smin_old << std::endl;
408  }
409 #endif
410  }
411  }
412 #if (DEBUG_LEVEL1)
413  std::cout << "end vpPose::CalculArbreDementhon() return " << erreur << std::endl;
414 #endif
415 
416  return erreur;
417 }
418 
428 {
429 #if (DEBUG_LEVEL1)
430  std::cout << "begin CCalculPose::PoseDementhonPlan()" << std::endl;
431 #endif
432 
433  unsigned int i, j, k;
434 
435  vpPoint p0 = listP.front();
436 
437  vpPoint P;
438  c3d.clear();
439  for (std::list<vpPoint>::const_iterator it = listP.begin(); it != listP.end(); ++it) {
440  P = *it;
441  P.set_oX(P.get_oX() - p0.get_oX());
442  P.set_oY(P.get_oY() - p0.get_oY());
443  P.set_oZ(P.get_oZ() - p0.get_oZ());
444  c3d.push_back(P);
445  }
446 
447  vpMatrix a;
448  try {
449  a.resize(npt - 1, 3);
450  } catch (...) {
451  vpERROR_TRACE(" ");
452  throw;
453  }
454 
455  for (i = 1; i < npt; i++) {
456  a[i - 1][0] = c3d[i].get_oX();
457  a[i - 1][1] = c3d[i].get_oY();
458  a[i - 1][2] = c3d[i].get_oZ();
459  }
460 
461  // calcul a^T a
462  vpMatrix ata;
463  ata = a.t() * a;
464 
465  /* essai FC pour debug SVD */
466  /*
467  vpMatrix ata_old ;
468  ata_old = a.t()*a ;
469 
470  vpMatrix ata((ata_old.getRows()-1),(ata_old.getCols()-1)) ;
471  for (i=0;i<ata.getRows();i++)
472  for (j=0;j<ata.getCols();j++) ata[i][j] = ata_old[i][j];
473  */
474  vpMatrix ata_sav;
475  ata_sav = ata;
476 
477 #if (DEBUG_LEVEL2)
478  {
479  std::cout << "a" << std::endl << a << std::endl;
480  std::cout << "ata" << std::endl << ata << std::endl;
481  }
482 #endif
483 
484  // calcul (a^T a)^-1
485  vpMatrix ata1(ata.getRows(), ata.getCols());
486  vpMatrix v(ata.getRows(), ata.getCols());
487  vpColVector sv(ata.getRows());
488  // ata1 = ata.i() ;
489  unsigned int imin = 0;
490  double s = 0.0;
491 
492  // calcul de ata^-1
493  ata.svd(sv, v);
494 
495  unsigned int nc = sv.getRows();
496  for (i = 0; i < nc; i++)
497  if (sv[i] > s)
498  s = sv[i];
499 
500  s *= 0.0002;
501  int irank = 0;
502  for (i = 0; i < nc; i++)
503  if (sv[i] > s)
504  irank++;
505 
506  double svm = 100.0;
507  for (i = 0; i < nc; i++) {
508  if (sv[i] < svm) {
509  imin = i;
510  svm = sv[i];
511  }
512  }
513 
514 #if (DEBUG_LEVEL2)
515  {
516  std::cout << "rang: " << irank << std::endl;
517  ;
518  std::cout << "imin = " << imin << std::endl;
519  std::cout << "sv " << sv.t() << std::endl;
520  }
521 #endif
522 
523  for (i = 0; i < ata.getRows(); i++) {
524  for (j = 0; j < ata.getCols(); j++) {
525  ata1[i][j] = 0.0;
526  for (k = 0; k < nc; k++)
527  if (sv[k] > s)
528  ata1[i][j] += ((v[i][k] * ata[j][k]) / sv[k]);
529  }
530  }
531 
532  vpMatrix b; // b=(at a)^-1*at
533  b = ata1 * a.t();
534 
535  // calcul de U
536  vpColVector U(3);
537  U = ata.getCol(imin);
538 
539 #if (DEBUG_LEVEL2)
540  {
541  std::cout << "a" << std::endl << a << std::endl;
542  std::cout << "ata" << std::endl << ata_sav << std::endl;
543  std::cout << "ata1" << std::endl << ata1 << std::endl;
544  std::cout << "ata1*ata" << std::endl << ata1 * ata_sav;
545  std::cout << "b" << std::endl << b;
546  std::cout << "U " << U.t() << std::endl;
547  }
548 #endif
549 
550  vpColVector xi(npt);
551  vpColVector yi(npt);
552  // calcul de la premiere solution
553  for (i = 0; i < npt; i++) {
554  xi[i] = c3d[i].get_x();
555  yi[i] = c3d[i].get_y();
556  }
557 
558  vpColVector I0(3);
559  I0 = 0;
560  vpColVector J0(3);
561  J0 = 0;
562  vpColVector I(3);
563  vpColVector J(3);
564 
565  for (i = 1; i < npt; i++) {
566  I0[0] += b[0][i - 1] * (xi[i] - xi[0]);
567  I0[1] += b[1][i - 1] * (xi[i] - xi[0]);
568  I0[2] += b[2][i - 1] * (xi[i] - xi[0]);
569 
570  J0[0] += b[0][i - 1] * (yi[i] - yi[0]);
571  J0[1] += b[1][i - 1] * (yi[i] - yi[0]);
572  J0[2] += b[2][i - 1] * (yi[i] - yi[0]);
573  }
574 
575 #if (DEBUG_LEVEL2)
576  {
577  std::cout << "I0 " << I0.t();
578  std::cout << "J0 " << J0.t();
579  }
580 #endif
581 
582  s = -2.0 * vpColVector::dotProd(I0, J0);
583  double c = J0.sumSquare() - I0.sumSquare();
584 
585  double r, theta, si, co;
586  calculRTheta(s, c, r, theta);
587  co = cos(theta);
588  si = sin(theta);
589 
590  // calcul de la premiere solution
591  I = I0 + U * r * co;
592  J = J0 + U * r * si;
593 
594  vpHomogeneousMatrix cMo1f;
595  calculSolutionDementhon(xi[0], yi[0], I, J, cMo1f);
596 
597  int erreur1 = calculArbreDementhon(b, U, cMo1f);
598 
599  // calcul de la deuxieme solution
600  I = I0 - U * r * co;
601  J = J0 - U * r * si;
602 
603  vpHomogeneousMatrix cMo2f;
604  calculSolutionDementhon(xi[0], yi[0], I, J, cMo2f);
605 
606  int erreur2 = calculArbreDementhon(b, U, cMo2f);
607 
608  if ((erreur1 == 0) && (erreur2 == -1))
609  cMo = cMo1f;
610  if ((erreur1 == -1) && (erreur2 == 0))
611  cMo = cMo2f;
612  if ((erreur1 == 0) && (erreur2 == 0)) {
613  double s1 = sqrt(computeResidualDementhon(cMo1f) / npt);
614  double s2 = sqrt(computeResidualDementhon(cMo2f) / npt);
615 
616  if (s1 <= s2)
617  cMo = cMo1f;
618  else
619  cMo = cMo2f;
620  }
621 
622  cMo[0][3] -= p0.get_oX() * cMo[0][0] + p0.get_oY() * cMo[0][1] + p0.get_oZ() * cMo[0][2];
623  cMo[1][3] -= p0.get_oX() * cMo[1][0] + p0.get_oY() * cMo[1][1] + p0.get_oZ() * cMo[1][2];
624  cMo[2][3] -= p0.get_oX() * cMo[2][0] + p0.get_oY() * cMo[2][1] + p0.get_oZ() * cMo[2][2];
625 
626 #if (DEBUG_LEVEL1)
627  std::cout << "end CCalculPose::PoseDementhonPlan()" << std::endl;
628 #endif
629 }
630 
631 #undef DMIN
632 #undef EPS
633 #undef EPS_DEM
634 
644 {
645  double residual_ = 0;
646 
647  residual_ = 0;
648  for (unsigned int i = 0; i < npt; i++) {
649 
650  double X = c3d[i].get_oX() * cMo[0][0] + c3d[i].get_oY() * cMo[0][1] + c3d[i].get_oZ() * cMo[0][2] + cMo[0][3];
651  double Y = c3d[i].get_oX() * cMo[1][0] + c3d[i].get_oY() * cMo[1][1] + c3d[i].get_oZ() * cMo[1][2] + cMo[1][3];
652  double Z = c3d[i].get_oX() * cMo[2][0] + c3d[i].get_oY() * cMo[2][1] + c3d[i].get_oZ() * cMo[2][2] + cMo[2][3];
653 
654  double x = X / Z;
655  double y = Y / Z;
656 
657  residual_ += vpMath::sqr(x - c3d[i].get_x()) + vpMath::sqr(y - c3d[i].get_y());
658  }
659  return residual_;
660 }
661 
662 #undef DEBUG_LEVEL1
663 #undef DEBUG_LEVEL2
664 #undef DEBUG_LEVEL3
void svd(vpColVector &w, vpMatrix &V)
Definition: vpMatrix.cpp:1791
int calculArbreDementhon(vpMatrix &b, vpColVector &U, vpHomogeneousMatrix &cMo)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:104
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Definition: vpMatrix.cpp:1931
void set_oZ(const double oZ)
Set the point Z coordinate in the object frame.
Definition: vpPoint.cpp:465
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.cpp:422
static vpColVector cross(const vpColVector &a, const vpColVector &b)
Definition: vpColVector.h:280
Implementation of an homogeneous matrix and operations on such kind of matrices.
#define vpERROR_TRACE
Definition: vpDebug.h:393
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true, const bool recopy_=true)
Definition: vpArray2D.h:171
error that can be emited by ViSP classes.
Definition: vpException.h:71
unsigned int getRows() const
Definition: vpArray2D.h:156
vpRowVector t() const
std::list< vpPoint > listP
Array of point (use here class vpPoint)
Definition: vpPose.h:115
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.cpp:420
Class that defines what is a point.
Definition: vpPoint.h:58
unsigned int getCols() const
Definition: vpArray2D.h:146
vpMatrix t() const
Definition: vpMatrix.cpp:375
vpColVector & normalize()
static double sqr(double x)
Definition: vpMath.h:108
void set_oX(const double oX)
Set the point X coordinate in the object frame.
Definition: vpPoint.cpp:461
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.cpp:424
unsigned int npt
Number of point used in pose computation.
Definition: vpPose.h:114
void poseDementhonPlan(vpHomogeneousMatrix &cMo)
Compute the pose using Dementhon approach for planar objects this is a direct implementation of the a...
void poseDementhonNonPlan(vpHomogeneousMatrix &cMo)
Compute the pose using Dementhon approach for non planar objects this is a direct implementation of t...
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
static double dotProd(const vpColVector &a, const vpColVector &b)
void set_oY(const double oY)
Set the point Y coordinate in the object frame.
Definition: vpPoint.cpp:463
double sumSquare() const
vpColVector getCol(const unsigned int j) const
Definition: vpMatrix.cpp:3797
double computeResidualDementhon(const vpHomogeneousMatrix &cMo)
Compute and return the residual expressed in meter for the pose matrix &#39;pose&#39;.
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:241