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>
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();
84 unsigned int nbMinRandom = 4 ;
85 unsigned int nbInliers = 0;
86 double r, r_lagrange, r_dementhon;
93 "Not enough point to compute the pose")) ;
96 bool foundSolution =
false;
98 while (nbTrials < ransacMaxTrials && nbInliers < (
unsigned)ransacNbInlierConsensus)
101 cur_consensus.clear();
107 cur_outliers.clear();
111 std::vector<bool> usedPt(size,
false);
114 for(
unsigned int i = 0; i < nbMinRandom;)
116 if((
size_t) std::count(usedPt.begin(), usedPt.end(),
true) == usedPt.size()) {
122 unsigned int r_ = (
unsigned int) rand() % size;
125 r_ = (
unsigned int) rand() % size;
130 std::list<vpPoint>::const_iterator iter =
listP.begin();
131 std::advance(iter, r_);
134 bool degenerate =
false;
135 for(std::list<vpPoint>::const_iterator it = poseMin.
listP.begin(); it != poseMin.
listP.end(); ++it){
145 cur_randoms.push_back(r_);
151 if(poseMin.
npt < nbMinRandom) {
157 bool is_valid_lagrange =
false;
158 bool is_valid_dementhon =
false;
161 r_lagrange = DBL_MAX;
162 r_dementhon = DBL_MAX;
167 is_valid_lagrange =
true;
175 is_valid_dementhon =
true;
182 if(is_valid_lagrange || is_valid_dementhon) {
183 if (r_lagrange < r_dementhon) {
186 cMo_tmp = cMo_lagrange;
191 cMo_tmp = cMo_dementhon;
193 r = sqrt(r) / (double) nbMinRandom;
196 bool isPoseValid =
true;
198 isPoseValid = func(&cMo_tmp);
207 if (isPoseValid && r < ransacThreshold)
209 unsigned int nbInliersCur = 0;
210 unsigned int iter = 0;
211 for (std::list<vpPoint>::const_iterator it =
listP.begin(); it !=
listP.end(); ++it)
218 double error = sqrt(d) ;
219 if(error < ransacThreshold) {
222 bool degenerate =
false;
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]);
239 cur_consensus.push_back(iter);
242 cur_outliers.push_back(iter);
246 cur_outliers.push_back(iter);
252 if(nbInliersCur > nbInliers)
254 foundSolution =
true;
255 best_consensus = cur_consensus;
256 nbInliers = nbInliersCur;
261 if(nbTrials >= ransacMaxTrials) {
262 vpERROR_TRACE(
"Ransac reached the maximum number of trials");
263 foundSolution =
true;
269 if(nbTrials >= ransacMaxTrials) {
270 vpERROR_TRACE(
"Ransac reached the maximum number of trials");
276 if(nbTrials >= ransacMaxTrials) {
277 vpERROR_TRACE(
"Ransac reached the maximum number of trials");
304 if(nbInliers >= nbMinRandom)
308 for(
unsigned i = 0 ; i < best_consensus.size(); i++)
310 std::list<vpPoint>::const_iterator iter =
listP.begin();
311 std::advance(iter, best_consensus[i]);
315 ransacInliers.push_back(pt);
319 bool is_valid_lagrange =
false;
320 bool is_valid_dementhon =
false;
323 r_lagrange = DBL_MAX;
324 r_dementhon = DBL_MAX;
329 is_valid_lagrange =
true;
337 is_valid_dementhon =
true;
342 if(is_valid_lagrange || is_valid_dementhon) {
343 if (r_lagrange < r_dementhon) {
352 if(computeCovariance) {
353 covarianceMatrix = pose.covarianceMatrix;
361 return foundSolution;
389 std::vector<vpPoint> &p3D,
390 const unsigned int &numberOfInlierToReachAConsensus,
391 const double &threshold,
392 unsigned int &ninliers,
393 std::vector<vpPoint> &listInliers,
395 const int &maxNbTrials )
400 for(
unsigned int i = 0 ; i < p2D.size() ; i++)
402 for(
unsigned int j = 0 ; j < p3D.size() ; j++)
405 pt.
set_x(p2D[i].get_x());
406 pt.
set_y(p2D[i].get_y());
413 if (pose.
listP.size() < 4)
415 vpERROR_TRACE(
"Ransac method cannot be used in that case ") ;
419 "Not enough points ")) ;
432 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
450 for (
int i=1 ; i < 4 ; i++)
451 for (
int j=0 ; j<i ; j++)
453 unsigned int indi = 5*ind[i] ;
454 unsigned int indj = 5*ind[j] ;
456 if ((fabs(x[indi] - x[indj]) < 1e-6) && (fabs(x[indi+1] - x[indj+1]) < 1e-6))
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))
478 for(i=0 ; i < 4 ; i++)
481 unsigned int index = 5*ind[i] ;
483 p[i].
set_x(x[index]) ;
484 p[i].
set_y(x[index+1]) ;
503 for (i=0 ; i <16 ; i++)
521 unsigned int n = x.
getRows()/5 ;
527 for( i=0 ; i < n ; i++)
534 for (i=0 ; i <16 ; i++)
543 for( i=0 ; i < n ; i++)
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,
564 for (
unsigned int i=0 ; i < n ; i++)
566 for (
unsigned int j=0 ; j < m ; j++)
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,
623 const int maxNbTrials)
630 vpPose::initRansac(n,x,y,m,X,Y,Z, data) ;
635 threshold, M,inliers,
636 numberOfInlierToReachAConsensus, 0.0, maxNbTrials) ;
641 for(i=0 ; i < n*m ; i++)
644 if (std::fabs(inliers[i]-1) <= std::fabs(
vpMath::maximum(inliers[i], 1.)) * std::numeric_limits<double>::epsilon())
657 for(i=0 ; i < n*m ; i++)
660 if (std::fabs(inliers[i]-1) <= std::fabs(
vpMath::maximum(inliers[i], 1.)) * std::numeric_limits<double>::epsilon())
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] ;
671 for (i=0 ; i <16 ; i++)
708 const unsigned int m,
710 const int numberOfInlierToReachAConsensus,
711 const double threshold,
712 unsigned int &ninliers,
713 std::list<vpPoint> &lPi,
715 const int maxNbTrials)
720 for (
unsigned int i=0 ; i < n ; i++)
722 x[i] = p[i].
get_x() ;
723 y[i] = p[i].
get_y() ;
729 for (
unsigned int i=0 ; i < m ; i++)
739 m,X,Y,Z, numberOfInlierToReachAConsensus,
745 for(
unsigned int i=0 ; i < ninliers ; i++)
786 std::list<vpPoint> &lP,
787 const int numberOfInlierToReachAConsensus,
788 const double threshold,
789 unsigned int &ninliers,
790 std::list<vpPoint> &lPi,
792 const int maxNbTrials)
795 unsigned int n = (
unsigned int)lp.size() ;
796 unsigned int m = (
unsigned int)lP.size() ;
804 for (std::list<vpPoint>::const_iterator it = lp.begin(); it != lp.end(); ++it)
817 for (std::list<vpPoint>::const_iterator it = lP.begin(); it != lP.end(); ++it)
829 m,X,Y,Z, numberOfInlierToReachAConsensus,
835 for( i=0 ; i < ninliers ; i++)
851 #endif // VISP_BUILD_DEPRECATED_FUNCTIONS
void projection(const vpColVector &_cP, vpColVector &_p)
Projection onto the image plane of a point. Input: the 3D coordinates in the camera frame _cP...
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
void setIdentity()
Basic initialisation (identity)
double get_oY() const
Get the point Y coordinate in the object frame.
void setRansacThreshold(const double &t)
void set_x(const double x)
Set the point x coordinate in the image plane.
void track(const vpHomogeneousMatrix &cMo)
static double measureTimeMs()
something is not initialized
double get_y() const
Get the point y coordinate in the image plane.
static void computeTransformation(vpColVector &x, unsigned int *ind, vpColVector &M)
std::list< vpPoint > listP
array of point (use here class vpPoint)
Class that defines what is a point.
bool poseRansac(vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
compute the pose using the Ransac approach
static Type maximum(const Type &a, const Type &b)
double * data
address of the first element of the data array
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
static double sqr(double x)
bool computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
compute the pose for a given method
Class used for pose computation from N points (pose from point only).
double get_oZ() const
Get the point Z coordinate in the object frame.
void set_y(const double y)
Set the point y coordinate in the image plane.
double get_x() const
Get the point x coordinate in the image plane.
unsigned int npt
number of point used in pose computation
void setRansacMaxTrials(const int &rM)
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)
static bool degenerateConfiguration(vpColVector &x, unsigned int *ind)
double get_oX() const
Get the point X coordinate in the object frame.
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...
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.
unsigned int getRows() const
Return the number of rows of the matrix.
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &_cP)
void addPoint(const vpPoint &P)
Add a new point in this array.
std::vector< vpPoint > getRansacInliers() const
void setCovarianceComputation(const bool &flag)
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.
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...
void resize(const unsigned int i, const bool flagNullify=true)
void clearPoint()
suppress all the point in the array of point