Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpPoseFeatures.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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  * Pose computation from any features.
32  */
33 
34 #include <visp3/core/vpDebug.h>
35 #include <visp3/vision/vpPoseFeatures.h>
36 
37 #if defined(VISP_HAVE_MODULE_VISUAL_FEATURES) && (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
38 
39 BEGIN_VISP_NAMESPACE
40 
41 vpPoseFeatures::vpPoseFeatures()
42  : m_maxSize(0), m_totalSize(0), m_vvsIterMax(200), m_lambda(1.0), m_verbose(false), m_computeCovariance(false),
43  m_covarianceMatrix(), m_featurePoint_Point_list(), m_featurePoint3D_Point_list(), m_featureVanishingPoint_Point_list(),
44  m_featureVanishingPoint_DuoLine_list(), m_featureEllipse_Sphere_list(), m_featureEllipse_Circle_list(),
45  m_featureLine_Line_list(), m_featureLine_DuoLineInt_List(), m_featureSegment_DuoPoints_list()
46 { }
47 
48 vpPoseFeatures::~vpPoseFeatures() { clear(); }
49 
50 void vpPoseFeatures::clear()
51 {
52  for (int i = (int)m_featurePoint_Point_list.size() - 1; i >= 0; i--)
53  delete m_featurePoint_Point_list[(unsigned int)i].desiredFeature;
54  m_featurePoint_Point_list.clear();
55 
56  for (int i = (int)m_featurePoint3D_Point_list.size() - 1; i >= 0; i--)
57  delete m_featurePoint3D_Point_list[(unsigned int)i].desiredFeature;
58  m_featurePoint3D_Point_list.clear();
59 
60  for (int i = (int)m_featureVanishingPoint_Point_list.size() - 1; i >= 0; i--)
61  delete m_featureVanishingPoint_Point_list[(unsigned int)i].desiredFeature;
62  m_featureVanishingPoint_Point_list.clear();
63 
64  for (int i = (int)m_featureVanishingPoint_DuoLine_list.size() - 1; i >= 0; i--)
65  delete m_featureVanishingPoint_DuoLine_list[(unsigned int)i].desiredFeature;
66  m_featureVanishingPoint_DuoLine_list.clear();
67 
68  for (int i = (int)m_featureEllipse_Sphere_list.size() - 1; i >= 0; i--)
69  delete m_featureEllipse_Sphere_list[(unsigned int)i].desiredFeature;
70  m_featureEllipse_Sphere_list.clear();
71 
72  for (int i = (int)m_featureEllipse_Circle_list.size() - 1; i >= 0; i--)
73  delete m_featureEllipse_Circle_list[(unsigned int)i].desiredFeature;
74  m_featureEllipse_Circle_list.clear();
75 
76  for (int i = (int)m_featureLine_Line_list.size() - 1; i >= 0; i--)
77  delete m_featureLine_Line_list[(unsigned int)i].desiredFeature;
78  m_featureLine_Line_list.clear();
79 
80  for (int i = (int)m_featureLine_DuoLineInt_List.size() - 1; i >= 0; i--)
81  delete m_featureLine_DuoLineInt_List[(unsigned int)i].desiredFeature;
82  m_featureLine_DuoLineInt_List.clear();
83 
84  for (int i = (int)m_featureSegment_DuoPoints_list.size() - 1; i >= 0; i--)
85  delete m_featureSegment_DuoPoints_list[(unsigned int)i].desiredFeature;
86  m_featureSegment_DuoPoints_list.clear();
87 
88  for (int i = (int)m_featureSpecific_list.size() - 1; i >= 0; i--)
89  delete m_featureSpecific_list[(unsigned int)i];
90  m_featureSpecific_list.clear();
91 
92  m_maxSize = 0;
93  m_totalSize = 0;
94 }
95 
96 void vpPoseFeatures::addFeaturePoint(const vpPoint &p)
97 {
98  m_featurePoint_Point_list.push_back(vpDuo<vpFeaturePoint, vpPoint>());
99  m_featurePoint_Point_list.back().firstParam = p;
100  m_featurePoint_Point_list.back().desiredFeature = new vpFeaturePoint();
101  vpFeatureBuilder::create(*m_featurePoint_Point_list.back().desiredFeature, p);
102 
103  m_totalSize++;
104  if (m_featurePoint_Point_list.size() > m_maxSize)
105  m_maxSize = (unsigned int)m_featurePoint_Point_list.size();
106 }
107 
108 void vpPoseFeatures::addFeaturePoint3D(const vpPoint &p)
109 {
110  m_featurePoint3D_Point_list.push_back(vpDuo<vpFeaturePoint3D, vpPoint>());
111  m_featurePoint3D_Point_list.back().firstParam = p;
112  m_featurePoint3D_Point_list.back().desiredFeature = new vpFeaturePoint3D();
113  vpFeatureBuilder::create(*m_featurePoint3D_Point_list.back().desiredFeature, p);
114 
115  m_totalSize++;
116  if (m_featurePoint3D_Point_list.size() > m_maxSize)
117  m_maxSize = (unsigned int)m_featurePoint3D_Point_list.size();
118 }
119 
120 void vpPoseFeatures::addFeatureVanishingPoint(const vpPoint &p)
121 {
122  m_featureVanishingPoint_Point_list.push_back(vpDuo<vpFeatureVanishingPoint, vpPoint>());
123  m_featureVanishingPoint_Point_list.back().firstParam = p;
124  m_featureVanishingPoint_Point_list.back().desiredFeature = new vpFeatureVanishingPoint();
125  vpFeatureBuilder::create(*m_featureVanishingPoint_Point_list.back().desiredFeature, p);
126 
127  m_totalSize++;
128  if (m_featureVanishingPoint_Point_list.size() > m_maxSize)
129  m_maxSize = (unsigned int)m_featureVanishingPoint_Point_list.size();
130 }
131 
132 void vpPoseFeatures::addFeatureVanishingPoint(const vpLine &l1, const vpLine &l2)
133 {
134  m_featureVanishingPoint_DuoLine_list.push_back(vpTrio<vpFeatureVanishingPoint, vpLine, vpLine>());
135  m_featureVanishingPoint_DuoLine_list.back().firstParam = l1;
136  m_featureVanishingPoint_DuoLine_list.back().secondParam = l2;
137  m_featureVanishingPoint_DuoLine_list.back().desiredFeature = new vpFeatureVanishingPoint();
138  vpFeatureBuilder::create(*m_featureVanishingPoint_DuoLine_list.back().desiredFeature, l1, l2);
139 
140  m_totalSize++;
141  if (m_featureVanishingPoint_DuoLine_list.size() > m_maxSize)
142  m_maxSize = (unsigned int)m_featureVanishingPoint_DuoLine_list.size();
143 }
144 
145 void vpPoseFeatures::addFeatureEllipse(const vpSphere &s)
146 {
147  m_featureEllipse_Sphere_list.push_back(vpDuo<vpFeatureEllipse, vpSphere>());
148  m_featureEllipse_Sphere_list.back().firstParam = s;
149  m_featureEllipse_Sphere_list.back().desiredFeature = new vpFeatureEllipse();
150  vpFeatureBuilder::create(*m_featureEllipse_Sphere_list.back().desiredFeature, s);
151 
152  m_totalSize++;
153  if (m_featureEllipse_Sphere_list.size() > m_maxSize)
154  m_maxSize = (unsigned int)m_featureEllipse_Sphere_list.size();
155 }
156 
157 void vpPoseFeatures::addFeatureEllipse(const vpCircle &c)
158 {
159  m_featureEllipse_Circle_list.push_back(vpDuo<vpFeatureEllipse, vpCircle>());
160  m_featureEllipse_Circle_list.back().firstParam = c;
161  m_featureEllipse_Circle_list.back().desiredFeature = new vpFeatureEllipse();
162  vpFeatureBuilder::create(*m_featureEllipse_Circle_list.back().desiredFeature, c);
163 
164  m_totalSize++;
165  if (m_featureEllipse_Circle_list.size() > m_maxSize)
166  m_maxSize = (unsigned int)m_featureEllipse_Circle_list.size();
167 }
168 
169 void vpPoseFeatures::addFeatureLine(const vpLine &l)
170 {
171  m_featureLine_Line_list.push_back(vpDuo<vpFeatureLine, vpLine>());
172  m_featureLine_Line_list.back().firstParam = l;
173  m_featureLine_Line_list.back().desiredFeature = new vpFeatureLine();
174  vpFeatureBuilder::create(*m_featureLine_Line_list.back().desiredFeature, l);
175 
176  m_totalSize++;
177  if (m_featureLine_Line_list.size() > m_maxSize)
178  m_maxSize = (unsigned int)m_featureLine_Line_list.size();
179 }
180 
181 void vpPoseFeatures::addFeatureLine(const vpCylinder &c, const int &line)
182 {
183  m_featureLine_DuoLineInt_List.push_back(vpTrio<vpFeatureLine, vpCylinder, int>());
184  m_featureLine_DuoLineInt_List.back().firstParam = c;
185  m_featureLine_DuoLineInt_List.back().secondParam = line;
186  m_featureLine_DuoLineInt_List.back().desiredFeature = new vpFeatureLine();
187  vpFeatureBuilder::create(*m_featureLine_DuoLineInt_List.back().desiredFeature, c, line);
188 
189  m_totalSize++;
190  if (m_featureLine_DuoLineInt_List.size() > m_maxSize)
191  m_maxSize = (unsigned int)m_featureLine_DuoLineInt_List.size();
192 }
193 
194 void vpPoseFeatures::addFeatureSegment(vpPoint &P1, vpPoint &P2)
195 {
196  m_featureSegment_DuoPoints_list.push_back(vpTrio<vpFeatureSegment, vpPoint, vpPoint>());
197  m_featureSegment_DuoPoints_list.back().firstParam = P1;
198  m_featureSegment_DuoPoints_list.back().secondParam = P2;
199  m_featureSegment_DuoPoints_list.back().desiredFeature = new vpFeatureSegment();
200  vpFeatureBuilder::create(*m_featureSegment_DuoPoints_list.back().desiredFeature, P1, P2);
201 
202  m_totalSize++;
203  if (m_featureSegment_DuoPoints_list.size() > m_maxSize)
204  m_maxSize = (unsigned int)m_featureSegment_DuoPoints_list.size();
205 }
206 
207 void vpPoseFeatures::error_and_interaction(vpHomogeneousMatrix &cMo, vpColVector &err, vpMatrix &L)
208 {
209  err = vpColVector();
210  L = vpMatrix();
211 
212  for (unsigned int i = 0; i < m_maxSize; i++) {
213  //--------------vpFeaturePoint--------------
214  // From vpPoint
215  if (i < m_featurePoint_Point_list.size()) {
216  vpFeaturePoint fp;
217  vpPoint p(m_featurePoint_Point_list[i].firstParam);
218  p.track(cMo);
220  err.stack(fp.error(*(m_featurePoint_Point_list[i].desiredFeature)));
221  L.stack(fp.interaction());
222  }
223 
224  //--------------vpFeaturePoint3D--------------
225  // From vpPoint
226  if (i < m_featurePoint3D_Point_list.size()) {
227  vpFeaturePoint3D fp3D;
228  vpPoint p(m_featurePoint3D_Point_list[i].firstParam);
229  p.track(cMo);
230  vpFeatureBuilder::create(fp3D, p);
231  err.stack(fp3D.error(*(m_featurePoint3D_Point_list[i].desiredFeature)));
232  L.stack(fp3D.interaction());
233  }
234 
235  //--------------vpFeatureVanishingPoint--------------
236  // From vpPoint
237  if (i < m_featureVanishingPoint_Point_list.size()) {
239  vpPoint p(m_featureVanishingPoint_Point_list[i].firstParam);
240  p.track(cMo);
241  vpFeatureBuilder::create(fvp, p);
242  err.stack(fvp.error(*(m_featureVanishingPoint_Point_list[i].desiredFeature)));
243  L.stack(fvp.interaction());
244  }
245  // From Duo of vpLines
246  if (i < m_featureVanishingPoint_DuoLine_list.size()) {
248  vpLine l1(m_featureVanishingPoint_DuoLine_list[i].firstParam);
249  vpLine l2(m_featureVanishingPoint_DuoLine_list[i].secondParam);
250  l1.track(cMo);
251  l2.track(cMo);
252  vpFeatureBuilder::create(fvp, l1, l2);
253  err.stack(fvp.error(*(m_featureVanishingPoint_DuoLine_list[i].desiredFeature)));
254  L.stack(fvp.interaction());
255  }
256 
257  //--------------vpFeatureEllipse--------------
258  // From vpSphere
259  if (i < m_featureEllipse_Sphere_list.size()) {
260  vpFeatureEllipse fe;
261  vpSphere s(m_featureEllipse_Sphere_list[i].firstParam);
262  s.track(cMo);
264  err.stack(fe.error(*(m_featureEllipse_Sphere_list[i].desiredFeature)));
265  L.stack(fe.interaction());
266  }
267  // From vpCircle
268  if (i < m_featureEllipse_Circle_list.size()) {
269  vpFeatureEllipse fe;
270  vpCircle c(m_featureEllipse_Circle_list[i].firstParam);
271  c.track(cMo);
273  err.stack(fe.error(*(m_featureEllipse_Circle_list[i].desiredFeature)));
274  L.stack(fe.interaction());
275  }
276 
277  //--------------vpFeatureLine--------------
278  // From vpLine
279  if (i < m_featureLine_Line_list.size()) {
280  vpFeatureLine fl;
281  vpLine l(m_featureLine_Line_list[i].firstParam);
282  l.track(cMo);
284  err.stack(fl.error(*(m_featureLine_Line_list[i].desiredFeature)));
285  L.stack(fl.interaction());
286  }
287  // From Duo of vpCylinder / Integer
288  if (i < m_featureLine_DuoLineInt_List.size()) {
289  vpFeatureLine fl;
290  vpCylinder c(m_featureLine_DuoLineInt_List[i].firstParam);
291  c.track(cMo);
292  vpFeatureBuilder::create(fl, c, m_featureLine_DuoLineInt_List[i].secondParam);
293  err.stack(fl.error(*(m_featureLine_DuoLineInt_List[i].desiredFeature)));
294  L.stack(fl.interaction());
295  }
296 
297  //--------------vpFeatureSegment--------------
298  // From Duo of vpPoints
299  if (i < m_featureSegment_DuoPoints_list.size()) {
300  vpFeatureSegment fs;
301  vpPoint p1(m_featureSegment_DuoPoints_list[i].firstParam);
302  vpPoint p2(m_featureSegment_DuoPoints_list[i].secondParam);
303  p1.track(cMo);
304  p2.track(cMo);
305  vpFeatureBuilder::create(fs, p1, p2);
306  err.stack(fs.error(*(m_featureSegment_DuoPoints_list[i].desiredFeature)));
307  L.stack(fs.interaction());
308  }
309 
310  //--------------Specific Feature--------------
311  if (i < m_featureSpecific_list.size()) {
312  m_featureSpecific_list[i]->createCurrent(cMo);
313  err.stack(m_featureSpecific_list[i]->error());
314  L.stack(m_featureSpecific_list[i]->currentInteraction());
315  }
316  }
317 }
318 
319 void vpPoseFeatures::computePose(vpHomogeneousMatrix &cMo, const vpPoseFeaturesMethodType &type)
320 {
321  switch (type) {
322  case VIRTUAL_VS:
323  computePoseVVS(cMo);
324  break;
325  case ROBUST_VIRTUAL_VS:
326  computePoseRobustVVS(cMo);
327  break;
328  default:
329  break;
330  }
331 }
332 
333 void vpPoseFeatures::computePoseVVS(vpHomogeneousMatrix &cMo)
334 {
335  try {
336  double residu_1 = 1e8;
337  double r = 1e8 - 1;
338  // we stop the minimization when the error is bellow 1e-8
339 
340  vpMatrix L;
341  vpColVector err;
342  vpColVector v;
343  unsigned int rank_max = 0;
344  unsigned int iter = 0;
345 
346  // while((int)((residu_1 - r)*1e12) != 0 )
347  while (std::fabs((residu_1 - r) * 1e12) > std::numeric_limits<double>::epsilon()) {
348  residu_1 = r;
349 
350  // Compute the interaction matrix and the error
351  error_and_interaction(cMo, err, L);
352 
353  // compute the residual
354  r = err.sumSquare();
355 
356  // compute the pseudo inverse of the interaction matrix
357  vpMatrix Lp;
358  unsigned int rank = L.pseudoInverse(Lp, 1e-6); // modif FC 1e-16
359 
360  if (rank_max < rank)
361  rank_max = rank;
362 
363  // compute the VVS control law
364  v = -m_lambda * Lp * err;
365 
366  cMo = vpExponentialMap::direct(v).inverse() * cMo;
367  if (iter++ > m_vvsIterMax) {
368  vpTRACE("Max iteration reached");
369  break;
370  }
371  }
372  if (rank_max < 6) {
373  if (m_verbose) {
374  vpTRACE("Only %d pose parameters can be estimated.", rank_max);
375  }
376  }
377 
378  if (m_computeCovariance)
379  m_covarianceMatrix = vpMatrix::computeCovarianceMatrix(L, v, -m_lambda * err);
380 
381  }
382  catch (...) {
383  vpERROR_TRACE("vpPoseFeatures::computePoseVVS");
384  throw;
385  }
386 }
387 
388 void vpPoseFeatures::computePoseRobustVVS(vpHomogeneousMatrix &cMo)
389 {
390  try {
391  double residu_1 = 1e8;
392  double r = 1e8 - 1;
393 
394  // we stop the minimization when the error is bellow 1e-8
395  vpMatrix L, W;
396  vpColVector w, res;
397  vpColVector v;
398  vpColVector error; // error vector
399 
400  vpRobust robust;
401  robust.setMinMedianAbsoluteDeviation(0.00001);
402 
403  unsigned int rank_max = 0;
404  unsigned int iter = 0;
405 
406  // while((int)((residu_1 - r)*1e12) !=0)
407  while (std::fabs((residu_1 - r) * 1e12) > std::numeric_limits<double>::epsilon()) {
408  residu_1 = r;
409 
410  // Compute the interaction matrix and the error
411  error_and_interaction(cMo, error, L);
412 
413  // compute the residual
414  r = error.sumSquare();
415 
416  if (iter == 0) {
417  res.resize(error.getRows() / 2);
418  w.resize(error.getRows() / 2);
419  W.resize(error.getRows(), error.getRows());
420  w = 1;
421  }
422 
423  for (unsigned int k = 0; k < error.getRows() / 2; k++) {
424  res[k] = vpMath::sqr(error[2 * k]) + vpMath::sqr(error[2 * k + 1]);
425  }
426  robust.MEstimator(vpRobust::TUKEY, res, w);
427 
428  // compute the pseudo inverse of the interaction matrix
429  for (unsigned int k = 0; k < error.getRows() / 2; k++) {
430  W[2 * k][2 * k] = w[k];
431  W[2 * k + 1][2 * k + 1] = w[k];
432  }
433  // compute the pseudo inverse of the interaction matrix
434  vpMatrix Lp;
435  vpMatrix LRank;
436  (W * L).pseudoInverse(Lp, 1e-6);
437  unsigned int rank = L.pseudoInverse(LRank, 1e-6);
438 
439  if (rank_max < rank)
440  rank_max = rank;
441 
442  // compute the VVS control law
443  v = -m_lambda * Lp * W * error;
444 
445  cMo = vpExponentialMap::direct(v).inverse() * cMo;
446  if (iter++ > m_vvsIterMax) {
447  vpTRACE("Max iteration reached");
448  break;
449  }
450  }
451 
452  if (rank_max < 6) {
453  if (m_verbose) {
454  vpTRACE("Only %d pose parameters can be estimated.", rank_max);
455  }
456  }
457 
458  if (m_computeCovariance)
459  m_covarianceMatrix =
460  vpMatrix::computeCovarianceMatrix(L, v, -m_lambda * error, W * W); // Remark: W*W = W*W.t() since the
461  // matrix is diagonal, but using W*W
462  // is more efficient.
463  }
464  catch (...) {
465  vpERROR_TRACE("vpPoseFeatures::computePoseRobustVVS");
466  throw;
467  }
468 }
469 
470 END_VISP_NAMESPACE
471 
472 #elif !defined(VISP_BUILD_SHARED_LIBS)
473 // Work around to avoid warning: libvisp_vision.a(vpPoseFeatures.cpp.o) has no symbols
474 void dummy_vpPoseFeatures() { };
475 #endif
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:362
unsigned int getRows() const
Definition: vpArray2D.h:347
Class that defines a 3D circle in the object frame and allows forward projection of a 3D circle in th...
Definition: vpCircle.h:87
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
double sumSquare() const
void stack(double d)
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
Class that defines a 3D cylinder in the object frame and allows forward projection of a 3D cylinder i...
Definition: vpCylinder.h:101
static vpHomogeneousMatrix direct(const vpColVector &v)
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpImagePoint &t)
Class that defines 2D ellipse visual feature.
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
compute the interaction matrix from a subset a the possible features
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
Class that defines a 2D line visual feature which is composed by two parameters that are and ,...
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
Class that defines the 3D point visual feature.
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
Class that defines a 2D point visual feature which is composed by two parameters that are the cartes...
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
Class that defines a 2D segment visual features. This class allow to consider two sets of visual feat...
vpColVector error(const vpBasicFeature &s_star, unsigned int select=FEATURE_ALL) VP_OVERRIDE
vpMatrix interaction(unsigned int select=FEATURE_ALL) VP_OVERRIDE
vpColVector error(const vpBasicFeature &s_star, unsigned int select=(vpFeatureVanishingPoint::selectX()|vpFeatureVanishingPoint::selectY())) VP_OVERRIDE
vpMatrix interaction(unsigned int select=(vpFeatureVanishingPoint::selectX()|vpFeatureVanishingPoint::selectY())) VP_OVERRIDE
void track(const vpHomogeneousMatrix &cMo)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix inverse() const
Class that defines a 3D line in the object frame and allows forward projection of the line in the cam...
Definition: vpLine.h:103
static double sqr(double x)
Definition: vpMath.h:203
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
static vpMatrix computeCovarianceMatrix(const vpMatrix &A, const vpColVector &x, const vpColVector &b)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:79
Contains an M-estimator and various influence function.
Definition: vpRobust.h:84
@ TUKEY
Tukey influence function.
Definition: vpRobust.h:89
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Definition: vpRobust.cpp:130
void setMinMedianAbsoluteDeviation(double mad_min)
Definition: vpRobust.h:136
Class that defines a 3D sphere in the object frame and allows forward projection of a 3D sphere in th...
Definition: vpSphere.h:80