Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpPose.h
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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.
32 */
33
38
39#ifndef VP_POSE_H
40#define VP_POSE_H
41
42#include <visp3/core/vpCameraParameters.h>
43#include <visp3/core/vpHomogeneousMatrix.h>
44#include <visp3/core/vpPixelMeterConversion.h>
45#include <visp3/core/vpPlane.h>
46#include <visp3/core/vpPoint.h>
47#include <visp3/core/vpRGBa.h>
48
49#include <list>
50#include <math.h>
51#include <vector>
52
53// Check if std:c++17 or higher.
54// Here we cannot use (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) in the declaration of the class
55#if ((__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)))
56#include <map>
57#include <optional>
58#endif
59
60#include <visp3/core/vpUniRand.h>
61
63
81class VISP_EXPORT vpPose
82{
83public:
107
117
118 unsigned int npt;
119 std::list<vpPoint> listP;
120
121 double residual;
122
123public:
124 // Typedef a function that checks if a pose is valid.
126
130 vpPose();
131
132#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
133 vpPose(const vpPose &) = default;
134 vpPose &operator=(const vpPose &) = default;
135#endif
136
140 VP_EXPLICIT vpPose(const std::vector<vpPoint> &lP);
141
145 virtual ~vpPose();
146
155 void addPoint(const vpPoint &P);
156
165 void addPoints(const std::vector<vpPoint> &lP);
166
170 void clearPoint();
171
197
208
222 double computeResidual(const vpHomogeneousMatrix &cMo) const;
223
236 double computeResidual(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam) const;
237
252 double computeResidual(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, vpColVector &squaredResidual) const;
253
269 bool coplanar(int &coplanar_plane_type, double *p_a = nullptr, double *p_b = nullptr, double *p_c = nullptr, double *p_d = nullptr);
270
276
282
289
296
307 void poseLagrangePlan(vpHomogeneousMatrix &cMo, bool *p_isPlan = nullptr, double *p_a = nullptr, double *p_b = nullptr,
308 double *p_c = nullptr, double *p_d = nullptr);
309
316
324 void poseLowe(vpHomogeneousMatrix &cMo);
325
339 bool poseRansac(vpHomogeneousMatrix &cMo, FuncCheckValidityPose func = nullptr);
340
348
355
359 void printPoint();
360
364 void setDementhonSvThreshold(const double &svThresh);
365
369 void setDistToPlaneForCoplanTest(double d);
370
374 void setLambda(double lambda) { m_lambda = lambda; }
375
379 void setVvsEpsilon(const double eps)
380 {
381 if (eps >= 0) {
382 vvsEpsilon = eps;
383 }
384 else {
385 throw vpException(vpException::badValue, "Epsilon value must be >= 0.");
386 }
387 }
388
392 void setVvsIterMax(int nb) { vvsIterMax = nb; }
393
397 void setRansacNbInliersToReachConsensus(const unsigned int &nbC) { ransacNbInlierConsensus = nbC; }
398
402 void setRansacThreshold(const double &t)
403 {
404 // Test whether or not t is > 0
405 if (t > std::numeric_limits<double>::epsilon()) {
406 ransacThreshold = t;
407 }
408 else {
409 throw vpException(vpException::badValue, "The Ransac threshold must be positive as we deal with distance.");
410 }
411 }
412
416 void setRansacMaxTrials(const int &rM) { ransacMaxTrials = rM; }
417
421 unsigned int getRansacNbInliers() const { return static_cast<unsigned int>(ransacInliers.size()); }
422
426 std::vector<unsigned int> getRansacInlierIndex() const { return ransacInlierIndex; }
427
431 std::vector<vpPoint> getRansacInliers() const { return ransacInliers; }
432
439 void setCovarianceComputation(const bool &flag) { computeCovariance = flag; }
440
451 {
452 if (!computeCovariance) {
453 std::cout << "Warning: The covariance matrix has not been computed. See setCovarianceComputation() to do it." << std::endl;
454 }
455 return covarianceMatrix;
456 }
457
469 inline void setRansacFilterFlag(const RANSAC_FILTER_FLAGS &flag) { ransacFlag = flag; }
470
476 inline int getNbParallelRansacThreads() const { return nbParallelRansacThreads; }
477
486 inline void setNbParallelRansacThreads(int nb) { nbParallelRansacThreads = nb; }
487
493 inline bool getUseParallelRansac() const { return useParallelRansac; }
494
500 inline void setUseParallelRansac(bool use) { useParallelRansac = use; }
501
507 std::vector<vpPoint> getPoints() const
508 {
509 std::vector<vpPoint> vectorOfPoints(listP.begin(), listP.end());
510 return vectorOfPoints;
511 }
512
533 static bool computePlanarObjectPoseFromRGBD(const vpImage<float> &depthMap, const std::vector<vpImagePoint> &corners,
534 const vpCameraParameters &colorIntrinsics,
535 const std::vector<vpPoint> &point3d, vpHomogeneousMatrix &cMo,
536 double *confidence_index = nullptr);
537
570 static bool computePlanarObjectPoseFromRGBD(const vpImage<float> &depthMap,
571 const std::vector<std::vector<vpImagePoint> > &corners,
572 const vpCameraParameters &colorIntrinsics,
573 const std::vector<std::vector<vpPoint> > &point3d,
574 vpHomogeneousMatrix &cMo, double *confidence_index = nullptr,
575 bool coplanar_points = true);
576
596 static int computeRansacIterations(double probability, double epsilon, const int sampleSize = 4,
597 int maxIterations = 2000);
598
609 static void display(vpImage<unsigned char> &I, vpHomogeneousMatrix &cMo, vpCameraParameters &cam, double size,
610 vpColor col = vpColor::none);
611
622 static void display(vpImage<vpRGBa> &I, vpHomogeneousMatrix &cMo, vpCameraParameters &cam, double size,
623 vpColor col = vpColor::none);
624
655 static void findMatch(std::vector<vpPoint> &p2D, std::vector<vpPoint> &p3D,
656 const unsigned int &numberOfInlierToReachAConsensus, const double &threshold,
657 unsigned int &ninliers, std::vector<vpPoint> &listInliers, vpHomogeneousMatrix &cMo,
658 const int &maxNbTrials = 10000, bool useParallelRansac = true, unsigned int nthreads = 0,
659 FuncCheckValidityPose func = nullptr);
660
661#ifdef VISP_HAVE_HOMOGRAPHY
683 static double poseFromRectangle(vpPoint &p1, vpPoint &p2, vpPoint &p3, vpPoint &p4, double lx,
684 const vpCameraParameters &cam, vpHomogeneousMatrix &cMo);
685#endif
686
687 // Check if std:c++17 or higher.
688 // Here we cannot use (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_17) in the declaration of the class
689#if ((__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L)))
690
707 template <typename DataId>
708 static std::optional<vpHomogeneousMatrix> computePlanarObjectPoseWithAtLeast3Points(
709 const vpPlane &plane_in_camera_frame, const std::map<DataId, vpPoint> &pts,
710 const std::map<DataId, vpImagePoint> &ips, const vpCameraParameters &camera_intrinsics,
711 std::optional<vpHomogeneousMatrix> cMo_init = std::nullopt, bool enable_vvs = true)
712 {
713 if (cMo_init && (!enable_vvs)) {
714 throw(vpException(
716 "It doesn't make sense to use an initialized pose without enabling VVS to compute the pose from 4 points"));
717 }
718
719 // Check if detection and model fit
720 // - The next line produces an internal compiler error with Visual Studio 2017:
721 // modules\vision\include\visp3/vision/vpPose.h(404): fatal error C1001: An internal error has occurred in the
722 // compiler.
723 // To work around this problem, try simplifying or changing the program near the locations listed above.
724 // Please choose the Technical Support command on the Visual C++
725 // Help menu, or open the Technical Support help file for more information
726 // - Note that the next line builds with Visual Studio 2022.
727 // for ([[maybe_unused]] const auto &[ip_id, _] : ips) {
728 for (const auto &[ip_id, ip_unused] : ips) {
729 (void)ip_unused;
730 if (pts.find(ip_id) == end(pts)) {
732 "Cannot compute pose with points and image points which do not have the same IDs"));
733 }
734 }
735
736 std::vector<vpPoint> P {}, Q {};
737 // The next line in C++17 produces a build error with Visual Studio 2017, that's why we
738 // use rather C++11 to loop through std::map
739 // for (auto [pt_id, pt] : pts) {
740 for (const auto &pt_map : pts) {
741 if (ips.find(pt_map.first) != end(ips)) {
742 double x = 0, y = 0;
743 vpPoint pt = pt_map.second;
744 vpPixelMeterConversion::convertPoint(camera_intrinsics, ips.at(pt_map.first), x, y);
745 const auto Z = plane_in_camera_frame.computeZ(x, y);
746
747 pt.set_x(x);
748 pt.set_y(y);
749 pt.set_Z(Z);
750
751 Q.push_back(pt);
752 P.emplace_back(x * Z, y * Z, Z);
753 }
754 }
755
756 if (Q.size() < 3) {
757 return std::nullopt;
758 }
759
760 auto cMo = cMo_init.value_or(vpHomogeneousMatrix::compute3d3dTransformation(P, Q));
761 if (!cMo.isValid()) {
762 return std::nullopt;
763 }
764
765 return enable_vvs ? vpPose::poseVirtualVSWithDepth(Q, cMo).value_or(cMo) : cMo;
766 }
767
777 static std::optional<vpHomogeneousMatrix> poseVirtualVSWithDepth(const std::vector<vpPoint> &points,
778 const vpHomogeneousMatrix &cMo);
779#endif
780
781protected:
782 double m_lambda;
784
794
800
801private:
802 void callLagrangePose(vpHomogeneousMatrix &cMo);
803
805 int vvsIterMax;
807 std::vector<vpPoint> c3d;
809 bool computeCovariance;
811 vpMatrix covarianceMatrix;
814 unsigned int ransacNbInlierConsensus;
816 int ransacMaxTrials;
818 std::vector<vpPoint> ransacInliers;
820 std::vector<unsigned int> ransacInlierIndex;
822 double ransacThreshold;
825 double distToPlaneForCoplanarityTest;
827 RANSAC_FILTER_FLAGS ransacFlag;
830 std::vector<vpPoint> listOfPoints;
832 bool useParallelRansac;
834 int nbParallelRansacThreads;
837 double vvsEpsilon;
838
842 class vpRansacFunctor
843 {
844 public:
848 vpRansacFunctor(const vpHomogeneousMatrix &cMo_, unsigned int ransacNbInlierConsensus_, const int ransacMaxTrials_,
849 double ransacThreshold_, unsigned int initial_seed_, bool checkDegeneratePoints_,
850 const std::vector<vpPoint> &listOfUniquePoints_, FuncCheckValidityPose func_)
851 : m_best_consensus(), m_checkDegeneratePoints(checkDegeneratePoints_), m_cMo(cMo_), m_foundSolution(false),
852 m_func(func_), m_listOfUniquePoints(listOfUniquePoints_), m_nbInliers(0), m_ransacMaxTrials(ransacMaxTrials_),
853 m_ransacNbInlierConsensus(ransacNbInlierConsensus_), m_ransacThreshold(ransacThreshold_),
854 m_uniRand(initial_seed_)
855 { }
856
860 void operator()() { m_foundSolution = poseRansacImpl(); }
861
865 bool getResult() const { return m_foundSolution; }
866
870 std::vector<unsigned int> getBestConsensus() const { return m_best_consensus; }
871
875 vpHomogeneousMatrix getEstimatedPose() const { return m_cMo; }
876
880 unsigned int getNbInliers() const { return m_nbInliers; }
881
882 private:
883 std::vector<unsigned int> m_best_consensus;
884 bool m_checkDegeneratePoints;
885 vpHomogeneousMatrix m_cMo;
886 bool m_foundSolution;
887 FuncCheckValidityPose m_func;
888 std::vector<vpPoint> m_listOfUniquePoints;
889 unsigned int m_nbInliers;
890 int m_ransacMaxTrials;
891 unsigned int m_ransacNbInlierConsensus;
892 double m_ransacThreshold;
893 vpUniRand m_uniRand;
894
899 bool poseRansacImpl();
900 };
901};
902
903END_VISP_NAMESPACE
904
905#endif
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
static const vpColor none
Definition vpColor.h:210
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition vpException.h:73
@ fatalError
Fatal error.
Definition vpException.h:72
Implementation of an homogeneous matrix and operations on such kind of matrices.
static vpHomogeneousMatrix compute3d3dTransformation(const std::vector< vpPoint > &p, const std::vector< vpPoint > &q)
Definition of the vpImage class member functions.
Definition vpImage.h:131
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
This class defines the container for a plane geometrical structure.
Definition vpPlane.h:56
double computeZ(double x, double y) const
Definition vpPlane.cpp:298
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
void set_x(double x)
Set the point x coordinate in the image plane.
Definition vpPoint.cpp:471
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
Definition vpPoint.cpp:457
void set_y(double y)
Set the point y coordinate in the image plane.
Definition vpPoint.cpp:473
vpPose(const vpPose &)=default
std::vector< vpPoint > getPoints() const
Definition vpPose.h:507
void setRansacMaxTrials(const int &rM)
Definition vpPose.h:416
double m_lambda
Parameters use for the virtual visual servoing approach.
Definition vpPose.h:782
void addPoint(const vpPoint &P)
Definition vpPose.cpp:96
void setRansacNbInliersToReachConsensus(const unsigned int &nbC)
Definition vpPose.h:397
vpMatrix getCovarianceMatrix() const
Definition vpPose.h:450
std::vector< unsigned int > getRansacInlierIndex() const
Definition vpPose.h:426
double computeResidualDementhon(const vpHomogeneousMatrix &cMo)
bool getUseParallelRansac() const
Definition vpPose.h:493
void printPoint()
Definition vpPose.cpp:554
vpPoseMethodType
Methods that could be used to estimate the pose from points.
Definition vpPose.h:86
@ DEMENTHON
Definition vpPose.h:88
@ LAGRANGE_LOWE
Definition vpPose.h:93
@ RANSAC
Definition vpPose.h:92
@ DEMENTHON_LOWE
Definition vpPose.h:95
@ DEMENTHON_LAGRANGE_VIRTUAL_VS
Definition vpPose.h:103
@ LAGRANGE_VIRTUAL_VS
Definition vpPose.h:101
@ VIRTUAL_VS
Definition vpPose.h:97
@ LAGRANGE
Definition vpPose.h:87
@ DEMENTHON_VIRTUAL_VS
Definition vpPose.h:99
@ LOWE
Definition vpPose.h:89
void setCovarianceComputation(const bool &flag)
Definition vpPose.h:439
unsigned int npt
Number of point used in pose computation.
Definition vpPose.h:118
bool computePose(vpPoseMethodType method, vpHomogeneousMatrix &cMo, FuncCheckValidityPose func=nullptr)
Definition vpPose.cpp:385
int getNbParallelRansacThreads() const
Definition vpPose.h:476
std::vector< vpPoint > getRansacInliers() const
Definition vpPose.h:431
void setDistToPlaneForCoplanTest(double d)
Definition vpPose.cpp:110
void addPoints(const std::vector< vpPoint > &lP)
Definition vpPose.cpp:103
void poseLagrangePlan(vpHomogeneousMatrix &cMo, bool *p_isPlan=nullptr, double *p_a=nullptr, double *p_b=nullptr, double *p_c=nullptr, double *p_d=nullptr)
void poseDementhonNonPlan(vpHomogeneousMatrix &cMo)
double m_dementhonSvThresh
SVD threshold use for the pseudo-inverse computation in poseDementhonPlan.
Definition vpPose.h:783
std::list< vpPoint > listP
Array of point (use here class vpPoint).
Definition vpPose.h:119
double computeResidual(const vpHomogeneousMatrix &cMo) const
Compute and return the sum of squared residuals expressed in meter^2 for the pose matrix cMo.
Definition vpPose.cpp:298
void poseLagrangeNonPlan(vpHomogeneousMatrix &cMo)
bool(* FuncCheckValidityPose)(const vpHomogeneousMatrix &)
Definition vpPose.h:125
static std::optional< vpHomogeneousMatrix > computePlanarObjectPoseWithAtLeast3Points(const vpPlane &plane_in_camera_frame, const std::map< DataId, vpPoint > &pts, const std::map< DataId, vpImagePoint > &ips, const vpCameraParameters &camera_intrinsics, std::optional< vpHomogeneousMatrix > cMo_init=std::nullopt, bool enable_vvs=true)
Definition vpPose.h:708
void setRansacFilterFlag(const RANSAC_FILTER_FLAGS &flag)
Definition vpPose.h:469
void clearPoint()
Definition vpPose.cpp:89
bool coplanar(int &coplanar_plane_type, double *p_a=nullptr, double *p_b=nullptr, double *p_c=nullptr, double *p_d=nullptr)
Definition vpPose.cpp:120
int calculArbreDementhon(vpMatrix &b, vpColVector &U, vpHomogeneousMatrix &cMo)
vpPose()
Definition vpPose.cpp:65
void setVvsIterMax(int nb)
Definition vpPose.h:392
void poseLowe(vpHomogeneousMatrix &cMo)
Compute the pose using the Lowe non linear approach it consider the minimization of a residual using ...
RANSAC_FILTER_FLAGS
Definition vpPose.h:112
@ CHECK_DEGENERATE_POINTS
Definition vpPose.h:115
@ PREFILTER_DEGENERATE_POINTS
Definition vpPose.h:114
@ NO_FILTER
No filter is applied.
Definition vpPose.h:113
unsigned int getRansacNbInliers() const
Definition vpPose.h:421
void setUseParallelRansac(bool use)
Definition vpPose.h:500
static std::optional< vpHomogeneousMatrix > poseVirtualVSWithDepth(const std::vector< vpPoint > &points, const vpHomogeneousMatrix &cMo)
bool computePoseDementhonLagrangeVVS(vpHomogeneousMatrix &cMo)
Method that first computes the pose cMo using the linear approaches of Dementhon and Lagrange and the...
Definition vpPose.cpp:463
void displayModel(vpImage< unsigned char > &I, vpCameraParameters &cam, vpColor col=vpColor::none)
Definition vpPose.cpp:578
void setLambda(double lambda)
Definition vpPose.h:374
void setVvsEpsilon(const double eps)
Definition vpPose.h:379
void setNbParallelRansacThreads(int nb)
Definition vpPose.h:486
double residual
Residual in meter.
Definition vpPose.h:121
vpPose & operator=(const vpPose &)=default
bool poseRansac(vpHomogeneousMatrix &cMo, FuncCheckValidityPose func=nullptr)
void poseVirtualVS(vpHomogeneousMatrix &cMo)
void poseDementhonPlan(vpHomogeneousMatrix &cMo)
void setDementhonSvThreshold(const double &svThresh)
Definition vpPose.cpp:112
void poseVirtualVSrobust(vpHomogeneousMatrix &cMo)
void setRansacThreshold(const double &t)
Definition vpPose.h:402