ViSP  2.10.0
vpPoseRansac.cpp
1 /****************************************************************************
2  *
3  * $Id: vpPoseRansac.cpp 5211 2015-01-26 17:44:35Z strinh $
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  * Pose computation.
36  *
37  * Authors:
38  * Eric Marchand
39  * Aurelien Yol
40  * Souriya Trinh
41  *
42  *****************************************************************************/
43 
44 
50 #include <iostream>
51 #include <cmath> // std::fabs
52 #include <limits> // numeric_limits
53 #include <stdlib.h>
54 #include <algorithm> // std::count
55 #include <float.h> //DBL_MAX
56 
57 #include <visp/vpPose.h>
58 #include <visp/vpColVector.h>
59 #include <visp/vpRansac.h>
60 #include <visp/vpTime.h>
61 #include <visp/vpList.h>
62 #include <visp/vpPoseException.h>
63 
64 #define eps 1e-6
65 
66 
76 {
77  srand(0); //Fix seed here so we will have the same pseudo-random series at each run.
78  std::vector<unsigned int> best_consensus;
79  std::vector<unsigned int> cur_consensus;
80  std::vector<unsigned int> cur_outliers;
81  std::vector<unsigned int> cur_randoms;
82  unsigned int size = (unsigned int)listP.size();
83  int nbTrials = 0;
84  unsigned int nbMinRandom = 4 ;
85  unsigned int nbInliers = 0;
86  double r, r_lagrange, r_dementhon;
87 
88  vpHomogeneousMatrix cMo_lagrange, cMo_dementhon;
89 
90  if (size < 4) {
91  //vpERROR_TRACE("Not enough point to compute the pose");
93  "Not enough point to compute the pose")) ;
94  }
95 
96  bool foundSolution = false;
97 
98  while (nbTrials < ransacMaxTrials && nbInliers < (unsigned)ransacNbInlierConsensus)
99  {
100  //Hold the list of the index of the inliers (points in the consensus set)
101  cur_consensus.clear();
102 
103  //Use a temporary variable because if not, the cMo passed in parameters will be modified when
104  // we compute the pose for the minimal sample sets but if the pose is not correct when we pass
105  // a function pointer we do not want to modify the cMo passed in parameters
106  vpHomogeneousMatrix cMo_tmp;
107  cur_outliers.clear();
108  cur_randoms.clear();
109 
110  //Vector of used points, initialized at false for all points
111  std::vector<bool> usedPt(size, false);
112 
113  vpPose poseMin;
114  for(unsigned int i = 0; i < nbMinRandom;)
115  {
116  if((size_t) std::count(usedPt.begin(), usedPt.end(), true) == usedPt.size()) {
117  //All points was picked once, break otherwise we stay in an infinite loop
118  break;
119  }
120 
121  //Pick a point randomly
122  unsigned int r_ = (unsigned int) rand() % size;
123  while(usedPt[r_]) {
124  //If already picked, pick another point randomly
125  r_ = (unsigned int) rand() % size;
126  }
127  //Mark this point as already picked
128  usedPt[r_] = true;
129 
130  std::list<vpPoint>::const_iterator iter = listP.begin();
131  std::advance(iter, r_);
132  vpPoint pt = *iter;
133 
134  bool degenerate = false;
135  for(std::list<vpPoint>::const_iterator it = poseMin.listP.begin(); it != poseMin.listP.end(); ++it){
136  vpPoint ptdeg = *it;
137  if( ((fabs(pt.get_x() - ptdeg.get_x()) < 1e-6) && (fabs(pt.get_y() - ptdeg.get_y()) < 1e-6)) ||
138  ((fabs(pt.get_oX() - ptdeg.get_oX()) < 1e-6) && (fabs(pt.get_oY() - ptdeg.get_oY()) < 1e-6) && (fabs(pt.get_oZ() - ptdeg.get_oZ()) < 1e-6))){
139  degenerate = true;
140  break;
141  }
142  }
143  if(!degenerate) {
144  poseMin.addPoint(pt);
145  cur_randoms.push_back(r_);
146  //Increment the number of points picked
147  i++;
148  }
149  }
150 
151  if(poseMin.npt < nbMinRandom) {
152  nbTrials++;
153  continue;
154  }
155 
156  //Flags set if pose computation is OK
157  bool is_valid_lagrange = false;
158  bool is_valid_dementhon = false;
159 
160  //Set maximum value for residuals
161  r_lagrange = DBL_MAX;
162  r_dementhon = DBL_MAX;
163 
164  try {
165  poseMin.computePose(vpPose::LAGRANGE, cMo_lagrange);
166  r_lagrange = poseMin.computeResidual(cMo_lagrange);
167  is_valid_lagrange = true;
168  } catch(/*vpException &e*/...) {
169 // std::cerr << e.what() << std::endl;
170  }
171 
172  try {
173  poseMin.computePose(vpPose::DEMENTHON, cMo_dementhon);
174  r_dementhon = poseMin.computeResidual(cMo_dementhon);
175  is_valid_dementhon = true;
176  } catch(/*vpException &e*/...) {
177 // std::cerr << e.what() << std::endl;
178  }
179 
180  //If at least one pose computation is OK,
181  //we can continue, otherwise pick another random set
182  if(is_valid_lagrange || is_valid_dementhon) {
183  if (r_lagrange < r_dementhon) {
184  r = r_lagrange;
185 // cMo = cMo_lagrange;
186  cMo_tmp = cMo_lagrange;
187  }
188  else {
189  r = r_dementhon;
190 // cMo = cMo_dementhon;
191  cMo_tmp = cMo_dementhon;
192  }
193  r = sqrt(r) / (double) nbMinRandom;
194 
195  //Filter the pose using some criterion (orientation angles, translations, etc.)
196  bool isPoseValid = true;
197  if(func != NULL) {
198  isPoseValid = func(&cMo_tmp);
199  if(isPoseValid) {
200  cMo = cMo_tmp;
201  }
202  } else {
203  //No post filtering on pose, so copy cMo_temp to cMo
204  cMo = cMo_tmp;
205  }
206 
207  if (isPoseValid && r < ransacThreshold)
208  {
209  unsigned int nbInliersCur = 0;
210  unsigned int iter = 0;
211  for (std::list<vpPoint>::const_iterator it = listP.begin(); it != listP.end(); ++it)
212  {
213  vpPoint pt = *it;
214  vpPoint p(pt) ;
215  p.track(cMo) ;
216 
217  double d = vpMath::sqr(p.get_x() - pt.get_x()) + vpMath::sqr(p.get_y() - pt.get_y()) ;
218  double error = sqrt(d) ;
219  if(error < ransacThreshold) {
220  // the point is considered as inlier if the error is below the threshold
221  // But, we need also to check if it is not a degenerate point
222  bool degenerate = false;
223 
224  for(unsigned int it_inlier_index = 0; it_inlier_index< cur_consensus.size(); it_inlier_index++){
225  std::list<vpPoint>::const_iterator it_point = listP.begin();
226  std::advance(it_point, cur_consensus[it_inlier_index]);
227  pt = *it_point;
228 
229  vpPoint ptdeg = *it;
230  if( ((fabs(pt.get_x() - ptdeg.get_x()) < 1e-6) && (fabs(pt.get_y() - ptdeg.get_y()) < 1e-6)) ||
231  ((fabs(pt.get_oX() - ptdeg.get_oX()) < 1e-6) && (fabs(pt.get_oY() - ptdeg.get_oY()) < 1e-6) && (fabs(pt.get_oZ() - ptdeg.get_oZ()) < 1e-6))){
232  degenerate = true;
233  break;
234  }
235  }
236 
237  if(!degenerate) {
238  nbInliersCur++;
239  cur_consensus.push_back(iter);
240  }
241  else {
242  cur_outliers.push_back(iter);
243  }
244  }
245  else {
246  cur_outliers.push_back(iter);
247  }
248 
249  iter++;
250  }
251 
252  if(nbInliersCur > nbInliers)
253  {
254  foundSolution = true;
255  best_consensus = cur_consensus;
256  nbInliers = nbInliersCur;
257  }
258 
259  nbTrials++;
260 
261  if(nbTrials >= ransacMaxTrials) {
262  vpERROR_TRACE("Ransac reached the maximum number of trials");
263  foundSolution = true;
264  }
265  }
266  else {
267  nbTrials++;
268 
269  if(nbTrials >= ransacMaxTrials) {
270  vpERROR_TRACE("Ransac reached the maximum number of trials");
271  }
272  }
273  } else {
274  nbTrials++;
275 
276  if(nbTrials >= ransacMaxTrials) {
277  vpERROR_TRACE("Ransac reached the maximum number of trials");
278  }
279  }
280  }
281 
282  if(foundSolution) {
283  //std::cout << "Nombre d'inliers " << nbInliers << std::endl ;
284 
285  //Display the random picked points
286  /*
287  std::cout << "Randoms : ";
288  for(unsigned int i = 0 ; i < cur_randoms.size() ; i++)
289  std::cout << cur_randoms[i] << " ";
290  std::cout << std::endl;
291  */
292 
293  //Display the outliers
294  /*
295  std::cout << "Outliers : ";
296  for(unsigned int i = 0 ; i < cur_outliers.size() ; i++)
297  std::cout << cur_outliers[i] << " ";
298  std::cout << std::endl;
299  */
300 
301  //Even if the cardinality of the best consensus set is inferior to ransacNbInlierConsensus,
302  //we want to refine the solution with data in best_consensus and return this pose.
303  //This is an approach used for example in p118 in Multiple View Geometry in Computer Vision, Hartley, R.~I. and Zisserman, A.
304  if(nbInliers >= nbMinRandom) //if(nbInliers >= (unsigned)ransacNbInlierConsensus)
305  {
306  //Refine the solution using all the points in the consensus set and with VVS pose estimation
307  vpPose pose ;
308  for(unsigned i = 0 ; i < best_consensus.size(); i++)
309  {
310  std::list<vpPoint>::const_iterator iter = listP.begin();
311  std::advance(iter, best_consensus[i]);
312  vpPoint pt = *iter;
313 
314  pose.addPoint(pt) ;
315  ransacInliers.push_back(pt);
316  }
317 
318  //Flags set if pose computation is OK
319  bool is_valid_lagrange = false;
320  bool is_valid_dementhon = false;
321 
322  //Set maximum value for residuals
323  r_lagrange = DBL_MAX;
324  r_dementhon = DBL_MAX;
325 
326  try {
327  pose.computePose(vpPose::LAGRANGE, cMo_lagrange);
328  r_lagrange = pose.computeResidual(cMo_lagrange);
329  is_valid_lagrange = true;
330  } catch(/*vpException &e*/...) {
331 // std::cerr << e.what() << std::endl;
332  }
333 
334  try {
335  pose.computePose(vpPose::DEMENTHON, cMo_dementhon);
336  r_dementhon = pose.computeResidual(cMo_dementhon);
337  is_valid_dementhon = true;
338  } catch(/*vpException &e*/...) {
339 // std::cerr << e.what() << std::endl;
340  }
341 
342  if(is_valid_lagrange || is_valid_dementhon) {
343  if (r_lagrange < r_dementhon) {
344  cMo = cMo_lagrange;
345  }
346  else {
347  cMo = cMo_dementhon;
348  }
349 
350  pose.setCovarianceComputation(computeCovariance);
351  pose.computePose(vpPose::VIRTUAL_VS, cMo);
352  if(computeCovariance) {
353  covarianceMatrix = pose.covarianceMatrix;
354  }
355  }
356  } else {
357  return false;
358  }
359  }
360 
361  return foundSolution;
362 }
363 
388 void vpPose::findMatch(std::vector<vpPoint> &p2D,
389  std::vector<vpPoint> &p3D,
390  const unsigned int &numberOfInlierToReachAConsensus,
391  const double &threshold,
392  unsigned int &ninliers,
393  std::vector<vpPoint> &listInliers,
394  vpHomogeneousMatrix &cMo,
395  const int &maxNbTrials )
396 {
397  vpPose pose;
398 
399  int nbPts = 0;
400  for(unsigned int i = 0 ; i < p2D.size() ; i++)
401  {
402  for(unsigned int j = 0 ; j < p3D.size() ; j++)
403  {
404  vpPoint pt;
405  pt.set_x(p2D[i].get_x());
406  pt.set_y(p2D[i].get_y());
407  pt.setWorldCoordinates(p3D[j].getWorldCoordinates());
408  pose.addPoint(pt);
409  nbPts++;
410  }
411  }
412 
413  if (pose.listP.size() < 4)
414  {
415  vpERROR_TRACE("Ransac method cannot be used in that case ") ;
416  vpERROR_TRACE("(at least 4 points are required)") ;
417  vpERROR_TRACE("Not enough point (%d) to compute the pose ",pose.listP.size()) ;
419  "Not enough points ")) ;
420  }
421  else
422  {
423  pose.setRansacMaxTrials(maxNbTrials);
424  pose.setRansacNbInliersToReachConsensus(numberOfInlierToReachAConsensus);
425  pose.setRansacThreshold(threshold);
426  pose.computePose(vpPose::RANSAC, cMo);
427  ninliers = pose.getRansacNbInliers();
428  listInliers = pose.getRansacInliers();
429  }
430 }
431 
432 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
433 
434 /*
435 \brief
436 
437 determines if there more than one the same point in the chosen set of point
438 
439 point are coded this way
440 x1,y1, X1, Y1, Z1
441 xnm, ynm, Xnm, Ynm, Znm
442 
443 leading to 5*n*m
444 */
445 bool
447 {
448 
449  // vpTRACE("%p %p %d",&x, ind, x.getRows()) ;
450  for (int i=1 ; i < 4 ; i++)
451  for (int j=0 ; j<i ; j++)
452  {
453  unsigned int indi = 5*ind[i] ;
454  unsigned int indj = 5*ind[j] ;
455 
456  if ((fabs(x[indi] - x[indj]) < 1e-6) && (fabs(x[indi+1] - x[indj+1]) < 1e-6))
457  { return true ; }
458 
459  if ((fabs(x[indi+2] - x[indj+2]) < 1e-6) && (fabs(x[indi+3] - x[indj+3]) < 1e-6) && (fabs(x[indi+4] - x[indj+4]) < 1e-6))
460  { return true ; }
461  }
462 
463  return false ;
464 }
469 void
471 {
472  unsigned int i ;
473 
474  vpPoint p[4] ;
475 
476  vpPose pose ;
477  pose.clearPoint() ;
478  for(i=0 ; i < 4 ; i++)
479  {
480 
481  unsigned int index = 5*ind[i] ;
482 
483  p[i].set_x(x[index]) ;
484  p[i].set_y(x[index+1]) ;
485 
486  p[i].setWorldCoordinates(x[index+2],x[index+3], x[index+4]) ;
487  pose.addPoint(p[i]) ;
488  }
489 
490 
491  // pose.printPoint() ;
492  vpHomogeneousMatrix cMo ;
493  try {
494  pose.computePose(vpPose::DEMENTHON, cMo) ;
495  // std::cout << cMo << std::endl ;
496  }
497  catch(...)
498  {
499  cMo.setIdentity() ;
500  }
501 
502  M.resize(16) ;
503  for (i=0 ; i <16 ; i++)
504  {
505  M[i] = cMo.data[i] ;
506  }
507 
508 }
509 
510 
516 double
518 {
519 
520  unsigned int i ;
521  unsigned int n = x.getRows()/5 ;
522 
523  vpPoint *p;
524  p = new vpPoint [n] ;
525  {
526  // firsttime=1 ;
527  for( i=0 ; i < n ; i++)
528  {
529  p[i].setWorldCoordinates(x[5*i+2],x[5*i+3], x[5*i+4]) ;
530  }
531  }
532 
533  vpHomogeneousMatrix cMo ;
534  for (i=0 ; i <16 ; i++)
535  {
536  cMo.data[i] = M[i];
537  }
538 
539 
540  d.resize(n) ;
541  vpColVector cP, xy ;
542 
543  for( i=0 ; i < n ; i++)
544  {
545  p[i].changeFrame(cMo,cP) ;
546  p[i].projection(cP,xy) ;
547  d[i] = sqrt(vpMath::sqr(x[5*i]-xy[0])+vpMath::sqr(x[5*i+1]-xy[1])) ;
548  }
549 
550  delete [] p;
551 
552  return 0 ;
553 }
554 
555 void
556 vpPose::initRansac(const unsigned int n,
557  const double *x, const double *y,
558  const unsigned int m,
559  const double *X, const double *Y, const double *Z,
560  vpColVector &data)
561 {
562  data.resize(5*n*m) ;
563  unsigned int k =0 ;
564  for (unsigned int i=0 ; i < n ; i++)
565  {
566  for (unsigned int j=0 ; j < m ; j++)
567  {
568  data[k] = x[i] ;
569  data[k+1] = y[i] ;
570  data[k+2] = X[j] ;
571  data[k+3] = Y[j] ;
572  data[k+4] = Z[j] ;
573 
574  k+=5 ;
575  }
576  }
577 }
578 
579 
612 void
613 vpPose::ransac(const unsigned int n,
614  const double *x, const double *y,
615  const unsigned int m,
616  const double *X, const double *Y, const double *Z,
617  const int numberOfInlierToReachAConsensus,
618  const double threshold,
619  unsigned int &ninliers,
620  vpColVector &xi, vpColVector &yi,
621  vpColVector &Xi, vpColVector &Yi, vpColVector &Zi,
622  vpHomogeneousMatrix &cMo,
623  const int maxNbTrials)
624 {
625 
626 
627  double tms = vpTime::measureTimeMs() ;
628  vpColVector data ;
629  unsigned int i;
630  vpPose::initRansac(n,x,y,m,X,Y,Z, data) ;
631 
632  vpColVector M(16) ;
633  vpColVector inliers(n*m) ;
634  vpRansac<vpPose>::ransac(n*m,data,4,
635  threshold, M,inliers,
636  numberOfInlierToReachAConsensus, 0.0, maxNbTrials) ;
637 
638 
639  // we count the number of inliers
640  ninliers = 0 ;
641  for(i=0 ; i < n*m ; i++)
642  {
643  //if (inliers[i]==1)
644  if (std::fabs(inliers[i]-1) <= std::fabs(vpMath::maximum(inliers[i], 1.)) * std::numeric_limits<double>::epsilon())
645  {
646  ninliers++ ;
647  }
648  }
649 
650  xi.resize(ninliers) ;
651  yi.resize(ninliers) ;
652  Xi.resize(ninliers) ;
653  Yi.resize(ninliers) ;
654  Zi.resize(ninliers) ;
655 
656  unsigned int k =0 ;
657  for(i=0 ; i < n*m ; i++)
658  {
659  //if (inliers[i]==1)
660  if (std::fabs(inliers[i]-1) <= std::fabs(vpMath::maximum(inliers[i], 1.)) * std::numeric_limits<double>::epsilon())
661  {
662  xi[k] = data[5*i] ;
663  yi[k] = data[5*i+1] ;
664  Xi[k] = data[5*i+2] ;
665  Yi[k] = data[5*i+3] ;
666  Zi[k] = data[5*i+4] ;
667  k++ ;
668  }
669  }
670 
671  for (i=0 ; i <16 ; i++)
672  {
673  cMo.data[i] = M[i];
674  }
675 
676  std::cout << vpTime::measureTimeMs() - tms << "ms" << std::endl ;
677 
678 }
679 
705 void
706 vpPose::ransac(const unsigned int n,
707  const vpPoint *p,
708  const unsigned int m,
709  const vpPoint *P,
710  const int numberOfInlierToReachAConsensus,
711  const double threshold,
712  unsigned int &ninliers,
713  std::list<vpPoint> &lPi,
714  vpHomogeneousMatrix &cMo,
715  const int maxNbTrials)
716 {
717  double *x, *y;
718  x = new double [n];
719  y = new double [n] ;
720  for (unsigned int i=0 ; i < n ; i++)
721  {
722  x[i] = p[i].get_x() ;
723  y[i] = p[i].get_y() ;
724  }
725  double *X, *Y, *Z;
726  X = new double [m];
727  Y = new double [m];
728  Z = new double [m];
729  for (unsigned int i=0 ; i < m ; i++)
730  {
731  X[i] = P[i].get_oX() ;
732  Y[i] = P[i].get_oY() ;
733  Z[i] = P[i].get_oZ() ;
734  }
735 
736  vpColVector xi,yi,Xi,Yi,Zi ;
737 
738  ransac(n,x,y,
739  m,X,Y,Z, numberOfInlierToReachAConsensus,
740  threshold,
741  ninliers,
742  xi,yi,Xi,Yi,Zi,
743  cMo, maxNbTrials) ;
744 
745  for(unsigned int i=0 ; i < ninliers ; i++)
746  {
747  vpPoint Pi ;
748  Pi.setWorldCoordinates(Xi[i], Yi[i], Zi[i]) ;
749  Pi.set_x(xi[i]) ;
750  Pi.set_y(yi[i]) ;
751  lPi.push_back(Pi) ;
752  }
753 
754  delete [] x;
755  delete [] y;
756  delete [] X;
757  delete [] Y;
758  delete [] Z;
759 }
760 
784 void
785 vpPose::ransac(std::list<vpPoint> &lp,
786  std::list<vpPoint> &lP,
787  const int numberOfInlierToReachAConsensus,
788  const double threshold,
789  unsigned int &ninliers,
790  std::list<vpPoint> &lPi,
791  vpHomogeneousMatrix &cMo,
792  const int maxNbTrials)
793 {
794  unsigned int i;
795  unsigned int n = (unsigned int)lp.size() ;
796  unsigned int m = (unsigned int)lP.size() ;
797 
798  double *x, *y;
799  x = new double [n];
800  y = new double [n];
801 
802  vpPoint pin ;
803  i = 0;
804  for (std::list<vpPoint>::const_iterator it = lp.begin(); it != lp.end(); ++it)
805  {
806  pin = *it;
807  x[i] = pin.get_x() ;
808  y[i] = pin.get_y() ;
809  ++ i;
810  }
811 
812  double *X, *Y, *Z;
813  X = new double [m];
814  Y = new double [m];
815  Z = new double [m];
816  i = 0;
817  for (std::list<vpPoint>::const_iterator it = lP.begin(); it != lP.end(); ++it)
818  {
819  pin = *it;
820  X[i] = pin.get_oX() ;
821  Y[i] = pin.get_oY() ;
822  Z[i] = pin.get_oZ() ;
823  ++i;
824  }
825 
826  vpColVector xi,yi,Xi,Yi,Zi ;
827 
828  ransac(n,x,y,
829  m,X,Y,Z, numberOfInlierToReachAConsensus,
830  threshold,
831  ninliers,
832  xi,yi,Xi,Yi,Zi,
833  cMo, maxNbTrials) ;
834 
835  for( i=0 ; i < ninliers ; i++)
836  {
837  vpPoint Pi ;
838  Pi.setWorldCoordinates(Xi[i],Yi[i], Zi[i]) ;
839  Pi.set_x(xi[i]) ;
840  Pi.set_y(yi[i]) ;
841  lPi.push_back(Pi);
842  }
843 
844  delete [] x;
845  delete [] y;
846  delete [] X;
847  delete [] Y;
848  delete [] Z;
849 
850 }
851 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
852 
853 /*
854  * Local variables:
855  * c-basic-offset: 2
856  * End:
857  */
void projection(const vpColVector &_cP, vpColVector &_p)
Projection onto the image plane of a point. Input: the 3D coordinates in the camera frame _cP...
Definition: vpPoint.cpp:132
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:395
void setIdentity()
Basic initialisation (identity)
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.h:129
void setRansacThreshold(const double &t)
Definition: vpPose.h:170
void set_x(const double x)
Set the point x coordinate in the image plane.
Definition: vpPoint.h:194
void track(const vpHomogeneousMatrix &cMo)
static double measureTimeMs()
Definition: vpTime.cpp:86
something is not initialized
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.h:138
static void computeTransformation(vpColVector &x, unsigned int *ind, vpColVector &M)
std::list< vpPoint > listP
array of point (use here class vpPoint)
Definition: vpPose.h:95
Class that defines what is a point.
Definition: vpPoint.h:65
bool poseRansac(vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
compute the pose using the Ransac approach
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
double * data
address of the first element of the data array
Definition: vpMatrix.h:118
static void findMatch(std::vector< vpPoint > &p2D, std::vector< vpPoint > &p3D, const unsigned int &numberOfInlierToReachAConsensus, const double &threshold, unsigned int &ninliers, std::vector< vpPoint > &listInliers, vpHomogeneousMatrix &cMo, const int &maxNbTrials=10000)
unsigned int getRansacNbInliers() const
Definition: vpPose.h:179
static double sqr(double x)
Definition: vpMath.h:106
bool computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
compute the pose for a given method
Definition: vpPose.cpp:386
Class used for pose computation from N points (pose from point only).
Definition: vpPose.h:78
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.h:131
void set_y(const double y)
Set the point y coordinate in the image plane.
Definition: vpPoint.h:196
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.h:136
unsigned int npt
number of point used in pose computation
Definition: vpPose.h:94
void setRansacMaxTrials(const int &rM)
Definition: vpPose.h:178
static void ransac(const unsigned int n, const double *x, const double *y, const unsigned int m, const double *X, const double *Y, const double *Z, const int numberOfInlierToReachAConsensus, const double threshold, unsigned int &ninliers, vpColVector &xi, vpColVector &yi, vpColVector &Xi, vpColVector &Yi, vpColVector &Zi, vpHomogeneousMatrix &cMo, const int maxNbTrials=10000)
void setRansacNbInliersToReachConsensus(const unsigned int &nbC)
Definition: vpPose.h:169
static bool degenerateConfiguration(vpColVector &x, unsigned int *ind)
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.h:127
Error that can be emited by the vpPose class and its derivates.
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
static bool ransac(unsigned int npts, vpColVector &x, unsigned int s, double t, vpColVector &model, vpColVector &inliers, int consensus=1000, double areaThreshold=0.0, const int maxNbumbersOfTrials=10000)
RANSAC - Robustly fits a model to data with the RANSAC algorithm.
Definition: vpRansac.h:124
unsigned int getRows() const
Return the number of rows of the matrix.
Definition: vpMatrix.h:161
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &_cP)
Definition: vpPoint.cpp:150
void addPoint(const vpPoint &P)
Add a new point in this array.
Definition: vpPose.cpp:155
std::vector< vpPoint > getRansacInliers() const
Definition: vpPose.h:180
void setCovarianceComputation(const bool &flag)
Definition: vpPose.h:187
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
Definition: vpPose.cpp:344
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:98
void clearPoint()
suppress all the point in the array of point
Definition: vpPose.cpp:133