ViSP  2.8.0
vpPoseFeatures.cpp
1 /****************************************************************************
2  *
3  * $Id: vpPoseFeatures.cpp 4303 2013-07-04 14:14:00Z 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  * Pose computation from any features.
36  *
37  * Authors:
38  * Aurelien Yol
39  *
40  *****************************************************************************/
41 #include <visp/vpPoseFeatures.h>
42 
47 {
48  lambda = 1.0;
49  vvsIterMax = 200;
50  totalSize = 0;
51  maxSize = 0;
52 
53  verbose = false;
54 }
55 
60 {
61  clear();
62 }
63 
68 {
69  for(int i = (int)featurePoint_Point_list.size()-1 ; i >= 0 ; i--)
70  delete featurePoint_Point_list[(unsigned int)i].desiredFeature;
71  featurePoint_Point_list.clear();
72 
73  for(int i = (int)featurePoint3D_Point_list.size()-1 ; i >= 0 ; i--)
74  delete featurePoint3D_Point_list[(unsigned int)i].desiredFeature;
75  featurePoint3D_Point_list.clear();
76 
77  for(int i = (int)featureVanishingPoint_Point_list.size()-1 ; i >= 0 ; i--)
78  delete featureVanishingPoint_Point_list[(unsigned int)i].desiredFeature;
79  featureVanishingPoint_Point_list.clear();
80 
81  for(int i = (int)featureVanishingPoint_DuoLine_list.size()-1 ; i >= 0 ; i--)
82  delete featureVanishingPoint_DuoLine_list[(unsigned int)i].desiredFeature;
83  featureVanishingPoint_DuoLine_list.clear();
84 
85  for(int i = (int)featureEllipse_Sphere_list.size()-1 ; i >= 0 ; i--)
86  delete featureEllipse_Sphere_list[(unsigned int)i].desiredFeature;
87  featureEllipse_Sphere_list.clear();
88 
89  for(int i = (int)featureEllipse_Circle_list.size()-1 ; i >= 0 ; i--)
90  delete featureEllipse_Circle_list[(unsigned int)i].desiredFeature;
91  featureEllipse_Circle_list.clear();
92 
93  for(int i = (int)featureLine_Line_list.size()-1 ; i >= 0 ; i--)
94  delete featureLine_Line_list[(unsigned int)i].desiredFeature;
95  featureLine_Line_list.clear();
96 
97  for(int i = (int)featureLine_DuoLineInt_List.size()-1 ; i >= 0 ; i--)
98  delete featureLine_DuoLineInt_List[(unsigned int)i].desiredFeature;
99  featureLine_DuoLineInt_List.clear();
100 
101  for(int i = (int)featureSegment_DuoPoints_list.size()-1 ; i >= 0 ; i--)
102  delete featureSegment_DuoPoints_list[(unsigned int)i].desiredFeature;
103  featureSegment_DuoPoints_list.clear();
104 
105 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
106  for(int i = (int)featureSpecific_list.size()-1 ; i >= 0 ; i--)
107  delete featureSpecific_list[(unsigned int)i];
108  featureSpecific_list.clear();
109 #endif
110 
111  maxSize = 0;
112  totalSize = 0;
113 }
114 
121 {
122  featurePoint_Point_list.push_back(vpDuo<vpFeaturePoint,vpPoint>());
123  featurePoint_Point_list.back().firstParam = p;
124  featurePoint_Point_list.back().desiredFeature = new vpFeaturePoint();
125  vpFeatureBuilder::create(*featurePoint_Point_list.back().desiredFeature,p);
126 
127  totalSize++;
128  if(featurePoint_Point_list.size() > maxSize)
129  maxSize = (unsigned int)featurePoint_Point_list.size();
130 }
131 
138 {
139  featurePoint3D_Point_list.push_back(vpDuo<vpFeaturePoint3D,vpPoint>());
140  featurePoint3D_Point_list.back().firstParam = p;
141  featurePoint3D_Point_list.back().desiredFeature = new vpFeaturePoint3D();
142  vpFeatureBuilder::create(*featurePoint3D_Point_list.back().desiredFeature,p);
143 
144  totalSize++;
145  if(featurePoint3D_Point_list.size() > maxSize)
146  maxSize = (unsigned int)featurePoint3D_Point_list.size();
147 }
148 
155 {
156  featureVanishingPoint_Point_list.push_back(vpDuo<vpFeatureVanishingPoint,vpPoint>());
157  featureVanishingPoint_Point_list.back().firstParam = p;
158  featureVanishingPoint_Point_list.back().desiredFeature = new vpFeatureVanishingPoint();
159  vpFeatureBuilder::create(*featureVanishingPoint_Point_list.back().desiredFeature,p);
160 
161  totalSize++;
162  if(featureVanishingPoint_Point_list.size() > maxSize)
163  maxSize = (unsigned int)featureVanishingPoint_Point_list.size();
164 }
165 
173 {
174  featureVanishingPoint_DuoLine_list.push_back(vpTrio<vpFeatureVanishingPoint,vpLine,vpLine>());
175  featureVanishingPoint_DuoLine_list.back().firstParam = l1;
176  featureVanishingPoint_DuoLine_list.back().secondParam = l2;
177  featureVanishingPoint_DuoLine_list.back().desiredFeature = new vpFeatureVanishingPoint();
178  vpFeatureBuilder::create(*featureVanishingPoint_DuoLine_list.back().desiredFeature,l1,l2);
179 
180  totalSize++;
181  if(featureVanishingPoint_DuoLine_list.size() > maxSize)
182  maxSize = (unsigned int)featureVanishingPoint_DuoLine_list.size();
183 }
184 
191 {
192  featureEllipse_Sphere_list.push_back(vpDuo<vpFeatureEllipse,vpSphere>());
193  featureEllipse_Sphere_list.back().firstParam = s;
194  featureEllipse_Sphere_list.back().desiredFeature = new vpFeatureEllipse();
195  vpFeatureBuilder::create(*featureEllipse_Sphere_list.back().desiredFeature,s);
196 
197  totalSize++;
198  if(featureEllipse_Sphere_list.size() > maxSize)
199  maxSize = (unsigned int)featureEllipse_Sphere_list.size();
200 }
201 
208 {
209  featureEllipse_Circle_list.push_back(vpDuo<vpFeatureEllipse,vpCircle>());
210  featureEllipse_Circle_list.back().firstParam = c;
211  featureEllipse_Circle_list.back().desiredFeature = new vpFeatureEllipse();
212  vpFeatureBuilder::create(*featureEllipse_Circle_list.back().desiredFeature,c);
213 
214  totalSize++;
215  if(featureEllipse_Circle_list.size() > maxSize)
216  maxSize = (unsigned int)featureEllipse_Circle_list.size();
217 }
218 
225 {
226  featureLine_Line_list.push_back(vpDuo<vpFeatureLine,vpLine>());
227  featureLine_Line_list.back().firstParam = l;
228  featureLine_Line_list.back().desiredFeature = new vpFeatureLine();
229  vpFeatureBuilder::create(*featureLine_Line_list.back().desiredFeature,l);
230 
231  totalSize++;
232  if(featureLine_Line_list.size() > maxSize)
233  maxSize = (unsigned int)featureLine_Line_list.size();
234 }
235 
243 void vpPoseFeatures::addFeatureLine(const vpCylinder &c, const int &line)
244 {
245  featureLine_DuoLineInt_List.push_back(vpTrio<vpFeatureLine,vpCylinder,int>());
246  featureLine_DuoLineInt_List.back().firstParam = c;
247  featureLine_DuoLineInt_List.back().secondParam = line;
248  featureLine_DuoLineInt_List.back().desiredFeature = new vpFeatureLine();
249  vpFeatureBuilder::create(*featureLine_DuoLineInt_List.back().desiredFeature,c,line);
250 
251  totalSize++;
252  if(featureLine_DuoLineInt_List.size() > maxSize)
253  maxSize = (unsigned int)featureLine_DuoLineInt_List.size();
254 }
255 
263 {
264  featureSegment_DuoPoints_list.push_back(vpTrio<vpFeatureSegment,vpPoint,vpPoint>());
265  featureSegment_DuoPoints_list.back().firstParam = P1;
266  featureSegment_DuoPoints_list.back().secondParam = P2;
267  featureSegment_DuoPoints_list.back().desiredFeature = new vpFeatureSegment();
268  vpFeatureBuilder::create(*featureSegment_DuoPoints_list.back().desiredFeature,P1,P2);
269 
270  totalSize++;
271  if(featureSegment_DuoPoints_list.size() > maxSize)
272  maxSize = (unsigned int)featureSegment_DuoPoints_list.size();
273 }
274 
282 void vpPoseFeatures::error_and_interaction(vpHomogeneousMatrix & cMo, vpColVector &err, vpMatrix &L)
283 {
284  err = vpColVector();
285  L = vpMatrix();
286 
287  for(unsigned int i = 0 ; i < maxSize ; i++)
288  {
289  //--------------vpFeaturePoint--------------
290  //From vpPoint
291  if( i < featurePoint_Point_list.size() ){
292  vpFeaturePoint fp;
293  vpPoint p(featurePoint_Point_list[i].firstParam);
294  p.track(cMo);
296  err.stackMatrices(fp.error(*(featurePoint_Point_list[i].desiredFeature)));
297  L.stackMatrices(fp.interaction());
298  }
299 
300  //--------------vpFeaturePoint3D--------------
301  //From vpPoint
302  if( i < featurePoint3D_Point_list.size() ){
303  vpFeaturePoint3D fp3D;
304  vpPoint p(featurePoint3D_Point_list[i].firstParam);
305  p.track(cMo);
306  vpFeatureBuilder::create(fp3D, p);
307  err.stackMatrices(fp3D.error(*(featurePoint3D_Point_list[i].desiredFeature)));
308  L.stackMatrices(fp3D.interaction());
309  }
310 
311  //--------------vpFeatureVanishingPoint--------------
312  //From vpPoint
313  if( i < featureVanishingPoint_Point_list.size() ){
315  vpPoint p(featureVanishingPoint_Point_list[i].firstParam);
316  p.track(cMo);
317  vpFeatureBuilder::create(fvp, p);
318  err.stackMatrices(fvp.error(*(featureVanishingPoint_Point_list[i].desiredFeature)));
319  L.stackMatrices(fvp.interaction());
320  }
321  //From Duo of vpLines
322  if( i < featureVanishingPoint_DuoLine_list.size() ){
324  vpLine l1(featureVanishingPoint_DuoLine_list[i].firstParam);
325  vpLine l2(featureVanishingPoint_DuoLine_list[i].secondParam);
326  l1.track(cMo);
327  l2.track(cMo);
328  vpFeatureBuilder::create(fvp, l1, l2);
329  err.stackMatrices(fvp.error(*(featureVanishingPoint_DuoLine_list[i].desiredFeature)));
330  L.stackMatrices(fvp.interaction());
331  }
332 
333  //--------------vpFeatureEllipse--------------
334  //From vpSphere
335  if( i < featureEllipse_Sphere_list.size() ){
336  vpFeatureEllipse fe;
337  vpSphere s(featureEllipse_Sphere_list[i].firstParam);
338  s.track(cMo);
340  err.stackMatrices(fe.error(*(featureEllipse_Sphere_list[i].desiredFeature)));
341  L.stackMatrices(fe.interaction());
342  }
343  //From vpCircle
344  if( i < featureEllipse_Circle_list.size() ){
345  vpFeatureEllipse fe;
346  vpCircle c(featureEllipse_Circle_list[i].firstParam);
347  c.track(cMo);
349  err.stackMatrices(fe.error(*(featureEllipse_Circle_list[i].desiredFeature)));
350  L.stackMatrices(fe.interaction());
351  }
352 
353  //--------------vpFeatureLine--------------
354  //From vpLine
355  if( i < featureLine_Line_list.size() ){
356  vpFeatureLine fl;
357  vpLine l(featureLine_Line_list[i].firstParam);
358  l.track(cMo);
360  err.stackMatrices(fl.error(*(featureLine_Line_list[i].desiredFeature)));
361  L.stackMatrices(fl.interaction());
362  }
363  //From Duo of vpCylinder / Integer
364  if( i < featureLine_DuoLineInt_List.size() ){
365  vpFeatureLine fl;
366  vpCylinder c(featureLine_DuoLineInt_List[i].firstParam);
367  c.track(cMo);
368  vpFeatureBuilder::create(fl, c, featureLine_DuoLineInt_List[i].secondParam);
369  err.stackMatrices(fl.error(*(featureLine_DuoLineInt_List[i].desiredFeature)));
370  L.stackMatrices(fl.interaction());
371  }
372 
373  //--------------vpFeatureSegment--------------
374  //From Duo of vpPoints
375  if( i < featureSegment_DuoPoints_list.size() ){
376  vpFeatureSegment fs;
377  vpPoint p1(featureSegment_DuoPoints_list[i].firstParam);
378  vpPoint p2(featureSegment_DuoPoints_list[i].secondParam);
379  p1.track(cMo);
380  p2.track(cMo);
381  vpFeatureBuilder::create(fs, p1, p2);
382  err.stackMatrices(fs.error(*(featureSegment_DuoPoints_list[i].desiredFeature)));
383  L.stackMatrices(fs.interaction());
384  }
385 
386 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
387  //--------------Specific Feature--------------
388  if( i < featureSpecific_list.size() ){
389  featureSpecific_list[i]->createCurrent(cMo);
390  err.stackMatrices(featureSpecific_list[i]->error());
391  L.stackMatrices(featureSpecific_list[i]->currentInteraction());
392  }
393 #endif
394  }
395 }
396 
397 
411 {
412  switch(type)
413  {
414  case VIRTUAL_VS:
415  computePoseVVS(cMo);
416  break;
417  case ROBUST_VIRTUAL_VS:
418  computePoseRobustVVS(cMo);
419  break;
420  default:
421  break;
422  }
423 }
424 
437 void vpPoseFeatures::computePoseVVS(vpHomogeneousMatrix & cMo)
438 {
439  try
440  {
441  double residu_1 = 1e8 ;
442  double r =1e8-1;
443  // we stop the minimization when the error is bellow 1e-8
444 
445  vpMatrix L;
446  vpColVector err;
447  vpColVector v ;
448 
449  unsigned int iter = 0;
450 
451  while((int)((residu_1 - r)*1e12) != 0 )
452  {
453  residu_1 = r ;
454 
455  // Compute the interaction matrix and the error
456  error_and_interaction(cMo,err,L);
457 
458  // compute the residual
459  r = err.sumSquare() ;
460 
461  // compute the pseudo inverse of the interaction matrix
462  vpMatrix Lp ;
463  unsigned int rank = L.pseudoInverse(Lp,1e-16) ;
464 
465  if(rank < 6){
466  if(verbose)
467  vpTRACE("Rank must be at least 6 ! cMo not computed.");
468 
469  break;
470  }
471 
472  // compute the VVS control law
473  v = -lambda*Lp*err ;
474 
475  cMo = vpExponentialMap::direct(v).inverse()*cMo ;
476  if (iter++>vvsIterMax){
477  vpTRACE("Max iteration reached") ;
478  break ;
479  }
480  }
481 
482  if(computeCovariance)
483  covarianceMatrix = vpMatrix::computeCovarianceMatrix(L,v,-lambda*err);
484 
485  }
486  catch(...)
487  {
488  vpERROR_TRACE("vpPoseFeatures::computePoseVVS") ;
489  throw ;
490  }
491 }
492 
493 
499 void vpPoseFeatures::computePoseRobustVVS(vpHomogeneousMatrix & cMo)
500 {
501  try{
502  double residu_1 = 1e8 ;
503  double r =1e8-1;
504 
505  // we stop the minimization when the error is bellow 1e-8
506  vpMatrix L, W;
507  vpColVector w, res;
508  vpColVector v ;
509  vpColVector error ; // error vector
510 
511  vpRobust robust(2*totalSize) ;
512  robust.setThreshold(0.0000) ;
513 
514  unsigned int iter = 0 ;
515 
516  while((int)((residu_1 - r)*1e12) !=0)
517  {
518  residu_1 = r ;
519 
520  // Compute the interaction matrix and the error
521  error_and_interaction(cMo,error,L);
522 
523  // compute the residual
524  r = error.sumSquare() ;
525 
526  if(iter == 0){
527  res = vpColVector(error.getRows()/2);
528  W = vpMatrix(error.getRows(),error.getRows());
529  w = vpColVector(error.getRows()/2);
530  w = 1;
531  }
532 
533  for(unsigned int k=0 ; k < error.getRows()/2 ; k++)
534  {
535  res[k] = vpMath::sqr(error[2*k]) + vpMath::sqr(error[2*k+1]) ;
536  }
537  robust.setIteration(0);
538  robust.MEstimator(vpRobust::TUKEY, res, w);
539 
540  // compute the pseudo inverse of the interaction matrix
541  for (unsigned int k=0 ; k < error.getRows()/2 ; k++)
542  {
543  W[2*k][2*k] = w[k] ;
544  W[2*k+1][2*k+1] = w[k] ;
545  }
546  // compute the pseudo inverse of the interaction matrix
547  vpMatrix Lp ;
548  vpMatrix LRank;
549  (W*L).pseudoInverse(Lp,1e-6) ;
550  unsigned int rank = L.pseudoInverse(LRank,1e-6) ;
551 
552  if(rank < 6){
553  if(verbose)
554  vpTRACE("Rank must be at least 6 ! cMo not computed.");
555 
556  break;
557  }
558 
559  // compute the VVS control law
560  v = -lambda*Lp*W*error ;
561 
562  cMo = vpExponentialMap::direct(v).inverse()*cMo ; ;
563  if (iter++>vvsIterMax){
564  vpTRACE("Max iteration reached") ;
565  break ;
566  }
567  }
568 
569  if(computeCovariance)
570  covarianceMatrix = vpMatrix::computeCovarianceMatrix(L,v,-lambda*error, W*W); // Remark: W*W = W*W.t() since the matrix is diagonale, but using W*W is more efficient.
571  }
572  catch(...)
573  {
574  vpERROR_TRACE("vpPoseFeatures::computePoseRobustVVS") ;
575  throw ;
576  }
577 }
578 
579 
580 
581 
582 
583 
584 
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
void addFeatureSegment(vpPoint &, vpPoint &)
vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpERROR_TRACE
Definition: vpDebug.h:379
#define vpTRACE
Definition: vpDebug.h:401
vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
Class that defines 2D vanishing point visual feature (Z coordinate in 3D space is infinity)...
Class that defines a 2D point visual feature which is composed by two parameters that are the cartes...
void addFeatureVanishingPoint(const vpPoint &)
Class that defines what is a sphere.
Definition: vpSphere.h:64
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
double sumSquare() const
return sum of the Aij^2 (for all i, for all j)
Definition: vpMatrix.cpp:760
static vpMatrix computeCovarianceMatrix(const vpMatrix &A, const vpColVector &x, const vpColVector &b)
void addFeaturePoint3D(const vpPoint &)
void addFeaturePoint(const vpPoint &)
Class that defines what is a point.
Definition: vpPoint.h:65
void addFeatureEllipse(const vpCircle &)
virtual ~vpPoseFeatures()
void computePose(vpHomogeneousMatrix &cMo, const vpPoseFeaturesMethodType &type=VIRTUAL_VS)
vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
Class that defines a line in the object frame, the camera frame and the image plane. All the parameters must be set in meter.
Definition: vpLine.h:124
Class that defines a 2D segment visual features. This class allow to consider two sets of visual feat...
static double sqr(double x)
Definition: vpMath.h:106
Class that defines the 3D point visual feature.
Class that defines a 2D line visual feature which is composed by two parameters that are and ...
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
static vpMatrix stackMatrices(const vpMatrix &A, const vpMatrix &B)
Stack two Matrices C = [ A B ]^T.
Definition: vpMatrix.cpp:2263
Class that defines what is a cylinder.
Definition: vpCylinder.h:97
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
vpHomogeneousMatrix inverse() const
static vpHomogeneousMatrix direct(const vpColVector &v)
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
compute the interaction matrix from a subset a the possible features
Contains an M-Estimator and various influence function.
Definition: vpRobust.h:63
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Definition: vpMatrix.cpp:1812
Class that defines 2D ellipse visual feature.
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:157
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
Class that defines what is a circle.
Definition: vpCircle.h:61
vpColVector error(const vpBasicFeature &s_star, const unsigned int select=FEATURE_ALL)
void addFeatureLine(const vpLine &)
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
compute the interaction matrix from a subset a the possible features