46 #include <visp3/vision/vpPose.h>
47 #include <visp3/core/vpDebug.h>
48 #include <visp3/core/vpException.h>
49 #include <visp3/vision/vpPoseException.h>
50 #include <visp3/core/vpMeterPixelConversion.h>
51 #include <visp3/core/vpCameraParameters.h>
52 #include <visp3/core/vpDisplay.h>
53 #include <visp3/core/vpMath.h>
58 #define DEBUG_LEVEL1 0
66 std::cout <<
"begin vpPose::Init() " << std::endl ;
76 distanceToPlaneForCoplanarityTest = 0.001 ;
78 computeCovariance =
false;
80 ransacMaxTrials = 1000;
81 ransacThreshold = 0.0001;
82 ransacNbInlierConsensus = 4;
86 std::cout <<
"end vpPose::Init() " << std::endl ;
93 : npt(0), listP(), residual(0), lambda(0.25), vvsIterMax(200), c3d(),
94 computeCovariance(false), covarianceMatrix(),
95 ransacNbInlierConsensus(4), ransacMaxTrials(1000), ransacInliers(), ransacInlierIndex(), ransacThreshold(0.0001),
96 distanceToPlaneForCoplanarityTest(0.001), ransacFlags(PREFILTER_DUPLICATE_POINTS),
97 listOfPoints(), useParallelRansac(false), nbParallelRansacThreads(0)
100 std::cout <<
"begin vpPose::vpPose() " << std::endl ;
106 std::cout <<
"end vpPose::vpPose() " << std::endl ;
117 std::cout <<
"begin vpPose::~vpPose() " << std::endl ;
123 std::cout <<
"end vpPose::~vpPose() " << std::endl ;
147 listP.push_back(newP);
148 listOfPoints.push_back(newP);
162 listP.insert(
listP.end(), lP.begin(), lP.end());
163 listOfPoints.insert(listOfPoints.end(), lP.begin(), lP.end());
170 distanceToPlaneForCoplanarityTest = d ;
187 coplanar_plane_type = 0;
192 "Not enough points ")) ;
195 if (
npt ==3)
return true ;
197 double x1=0,x2=0,x3=0,y1=0,y2=0,y3=0,z1=0,z2=0,z3=0 ;
199 std::list<vpPoint>::const_iterator it =
listP.begin();
204 bool degenerate =
true;
205 bool not_on_origin =
true;
206 std::list<vpPoint>::const_iterator it_tmp;
208 std::list<vpPoint>::const_iterator it_i, it_j, it_k;
209 for (it_i=
listP.begin(); it_i !=
listP.end(); ++it_i) {
210 if (degenerate ==
false) {
216 if ((std::fabs(P1.
get_oX()) <= std::numeric_limits<double>::epsilon())
217 && (std::fabs(P1.
get_oY()) <= std::numeric_limits<double>::epsilon())
218 && (std::fabs(P1.
get_oZ()) <= std::numeric_limits<double>::epsilon())) {
219 not_on_origin =
false;
222 not_on_origin =
true;
225 it_tmp = it_i; ++it_tmp;
226 for (it_j=it_tmp; it_j !=
listP.end(); ++it_j) {
227 if (degenerate ==
false) {
232 if ((std::fabs(P2.
get_oX()) <= std::numeric_limits<double>::epsilon())
233 && (std::fabs(P2.
get_oY()) <= std::numeric_limits<double>::epsilon())
234 && (std::fabs(P2.
get_oZ()) <= std::numeric_limits<double>::epsilon())) {
235 not_on_origin =
false;
238 not_on_origin =
true;
241 it_tmp = it_j; ++it_tmp;
242 for (it_k=it_tmp; it_k !=
listP.end(); ++it_k) {
244 if ((std::fabs(P3.
get_oX()) <= std::numeric_limits<double>::epsilon())
245 && (std::fabs(P3.
get_oY()) <= std::numeric_limits<double>::epsilon())
246 && (std::fabs(P3.
get_oZ()) <= std::numeric_limits<double>::epsilon())) {
247 not_on_origin =
false;
250 not_on_origin =
true;
266 a_b[0] = x1-x2; a_b[1] = y1-y2; a_b[2] = z1-z2;
267 b_c[0] = x2-x3; b_c[1] = y2-y3; b_c[2] = z2-z3;
270 if (cross_prod.
sumSquare() <= std::numeric_limits<double>::epsilon())
275 if (degenerate ==
false)
284 coplanar_plane_type = 4;
288 double a = y1*z2 - y1*z3 - y2*z1 + y2*z3 + y3*z1 - y3*z2 ;
289 double b = -x1*z2 + x1*z3 + x2*z1 - x2*z3 - x3*z1 + x3*z2 ;
290 double c = x1*y2 - x1*y3 - x2*y1 + x2*y3 + x3*y1 - x3*y2 ;
291 double d = -x1*y2*z3 + x1*y3*z2 +x2*y1*z3 - x2*y3*z1 - x3*y1*z2 + x3*y2*z1 ;
294 if (std::fabs(b) <= std::numeric_limits<double>::epsilon()
295 && std::fabs(c) <= std::numeric_limits<double>::epsilon() ) {
296 coplanar_plane_type = 1;
297 }
else if (std::fabs(a) <= std::numeric_limits<double>::epsilon()
298 && std::fabs(c) <= std::numeric_limits<double>::epsilon() ) {
299 coplanar_plane_type = 2;
300 }
else if (std::fabs(a) <= std::numeric_limits<double>::epsilon()
301 && std::fabs(b) <= std::numeric_limits<double>::epsilon() ) {
302 coplanar_plane_type = 3;
307 for(it=
listP.begin(); it !=
listP.end(); ++it)
313 if (fabs(dist) > distanceToPlaneForCoplanarityTest)
339 double residual_ = 0 ;
341 for(std::list<vpPoint>::const_iterator it=
listP.begin(); it !=
listP.end(); ++it)
344 double x = P.
get_x() ;
345 double y = P.
get_y() ;
378 "No enough point ")) ;
389 vpERROR_TRACE(
"Dementhon method cannot be used in that case ") ;
393 "Not enough points ")) ;
397 int coplanar_plane_type = 0;
398 bool plan =
coplanar(coplanar_plane_type) ;
432 int coplanar_plane_type;
433 bool plan =
coplanar(coplanar_plane_type) ;
435 if (plan ==
true && coplanar_plane_type > 0)
438 if (coplanar_plane_type == 4)
440 vpERROR_TRACE(
"Lagrange method cannot be used in that case ") ;
443 "Points are collinear ")) ;
447 vpERROR_TRACE(
"Lagrange method cannot be used in that case ") ;
451 "Not enough points ")) ;
466 vpERROR_TRACE(
"Lagrange method cannot be used in that case ") ;
470 "Not enough points ")) ;
486 vpERROR_TRACE(
"Ransac method cannot be used in that case ") ;
490 "Not enough points ")) ;
554 for(std::list<vpPoint>::const_iterator it=
listP.begin(); it !=
listP.end(); ++it)
558 std::cout <<
"3D oP " << P.
oP.
t() ;
559 std::cout <<
"3D cP " << P.
cP.
t() ;
560 std::cout <<
"2D " << P.
p.
t() ;
612 for(std::list<vpPoint>::const_iterator it=
listP.begin(); it !=
listP.end(); ++it)
633 for(std::list<vpPoint>::const_iterator it=
listP.begin(); it !=
listP.end(); ++it)
671 std::vector<double> rectx(4) ;
672 std::vector<double> recty(4) ;
681 std::vector<double> irectx(4) ;
682 std::vector<double> irecty(4) ;
683 irectx[0]=(p1.
get_x()) ;
684 irecty[0]=(p1.
get_y()) ;
685 irectx[1]=(p2.
get_x()) ;
686 irecty[1]=(p2.
get_y()) ;
687 irectx[2]=(p3.
get_x()) ;
688 irecty[2]=(p3.
get_y()) ;
689 irectx[3]=(p4.
get_x()) ;
690 irecty[3]=(p4.
get_y()) ;
698 for (
unsigned int i=0 ; i < 3 ; i++)
699 for(
unsigned int j=0 ; j < 3 ; j++)
700 H[i][j] = hom[i][j] ;
Implementation of a matrix and operations on matrices.
double residual
Residual in meter.
void poseLagrangePlan(vpHomogeneousMatrix &cMo, const int coplanar_plane_type=0)
Compute the pose of a planar object using Lagrange approach.
bool coplanar(int &coplanar_plane_type)
Implementation of an homogeneous matrix and operations on such kind of matrices.
void poseLagrangeNonPlan(vpHomogeneousMatrix &cMo)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Point coordinates conversion from normalized coordinates in meter to pixel coordinates ...
Class to define colors available for display functionnalities.
void displayModel(vpImage< unsigned char > &I, vpCameraParameters &cam, vpColor col=vpColor::none)
void addPoints(const std::vector< vpPoint > &lP)
double get_oY() const
Get the point Y coordinate in the object frame.
void track(const vpHomogeneousMatrix &cMo)
double get_y() const
Get the point y coordinate in the image plane.
std::list< vpPoint > listP
Array of point (use here class vpPoint)
void poseVirtualVS(vpHomogeneousMatrix &cMo)
Compute the pose using virtual visual servoing approach.
Class that defines what is a point.
bool poseRansac(vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
static void HLM(const std::vector< double > &xb, const std::vector< double > &yb, const std::vector< double > &xa, const std::vector< double > &ya, bool isplanar, vpHomography &aHb)
double lambda
parameters use for the virtual visual servoing approach
Implementation of an homography and operations on homographies.
static void display(vpImage< unsigned char > &I, vpHomogeneousMatrix &cMo, vpCameraParameters &cam, double size, vpColor col=vpColor::none)
static double poseFromRectangle(vpPoint &p1, vpPoint &p2, vpPoint &p3, vpPoint &p4, double lx, vpCameraParameters &cam, vpHomogeneousMatrix &cMo)
Carries out the camera pose the image of a rectangle and the intrinsec parameters, the length on x axis is known but the proprtion of the rectangle are unknown.
static double sqr(double x)
Class used for pose computation from N points (pose from point only). Some of the algorithms implemen...
Generic class defining intrinsic camera parameters.
vpColVector getCol(const unsigned int j) const
double get_oZ() const
Get the point Z coordinate in the object frame.
void poseLowe(vpHomogeneousMatrix &cMo)
Compute the pose using the Lowe non linear approach it consider the minimization of a residual using ...
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, bool(*func)(vpHomogeneousMatrix *)=NULL)
double get_x() const
Get the point x coordinate in the image plane.
unsigned int npt
Number of point used in pose computation.
double get_oX() const
Get the point X coordinate in the object frame.
static void displayFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, double size, const vpColor &color=vpColor::none, unsigned int thickness=1, vpImagePoint offset=vpImagePoint(0, 0))
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
void setWorldCoordinates(const double oX, const double oY, const double oZ)
void poseDementhonPlan(vpHomogeneousMatrix &cMo)
Compute the pose using Dementhon approach for planar objects this is a direct implementation of the a...
Error that can be emited by the vpPose class and its derivates.
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.
vpPoseMethodType
Methods that could be used to estimate the pose from points.
void setDistanceToPlaneForCoplanarityTest(double d)
vpMatrix pseudoInverse(double svThreshold=1e-6) const
Compute the pseudo inverse of the matrix using the SVD.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
void addPoint(const vpPoint &P)
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the residual expressed in meter for the pose matrix 'cMo'.