1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Generic model based tracker. This class declares the methods to implement
33  *in order to have a model based tracker.
34  *
35  * Authors:
36  * Romain Tallonneau
37  * Aurelien Yol
38  *
39  *****************************************************************************/
40 
41 /*!
42   \file vpMbTracker.h
43   \brief Generic model based tracker.
44 */
45 #ifndef vpMbTracker_hh
46 #define vpMbTracker_hh
47 
48 #include <map>
49 #include <string>
50 #include <vector>
51 
52 #include <visp3/core/vpCameraParameters.h>
53 #include <visp3/core/vpColVector.h>
54 #include <visp3/core/vpHomogeneousMatrix.h>
55 #include <visp3/core/vpImage.h>
56 #include <visp3/core/vpImagePoint.h>
57 #include <visp3/core/vpMatrix.h>
58 #include <visp3/core/vpPoint.h>
59 #include <visp3/core/vpPolygon.h>
60 #include <visp3/core/vpRGBa.h>
61 #include <visp3/core/vpRobust.h>
62 #include <visp3/mbt/vpMbHiddenFaces.h>
63 #include <visp3/mbt/vpMbtPolygon.h>
64 
65 #include <visp3/mbt/vpMbtDistanceCircle.h>
66 #include <visp3/mbt/vpMbtDistanceCylinder.h>
67 #include <visp3/mbt/vpMbtDistanceLine.h>
68 
69 #ifdef VISP_HAVE_COIN3D
70 // Work around to avoid type redefinition int8_t with Coin
71 // #if defined(_WIN32) && defined(VISP_HAVE_OGRE) && (_MSC_VER >= 1600) //
72 // Visual Studio 2010
73 //   #define HAVE_INT8_T 1
74 // #endif
75 
76 // Inventor includes
77 #include <Inventor/VRMLnodes/SoVRMLGroup.h>
78 #include <Inventor/VRMLnodes/SoVRMLIndexedFaceSet.h>
79 #include <Inventor/VRMLnodes/SoVRMLIndexedLineSet.h>
80 #endif
81 
82 /*!
83   \class vpMbTracker
84   \ingroup group_mbt_trackers
85   \brief Main methods for a model-based tracker.
86 
87   This class provides the main methods for a model based tracker. This pure
88   virtual class must be used in inheritance for a tracker that compute the
89   interaction matrix and the residu vector using a defined information (edge,
90   points of interest, patch, ...)
91 
92   This class intends to define a common basis for object tracking. This is
93   realised by implementing the main functions:
94   - init() : Initialisation of the tracker (it includes re-initialisation).
95   This method is called at the end of the initClick() method.
96   - initFaceFromCorners() : Initialisation of the lines that has to be
97   tracked.
98   - track() : Tracking on the current image
99   - testTracking() : Test the tracking. This method throws exception if the
100     tracking failed.
101   - display() : Display the model and eventually other information.
102 
103 */
104 class VISP_EXPORT vpMbTracker
105 {
106 public:
107   typedef enum { GAUSS_NEWTON_OPT = 0, LEVENBERG_MARQUARDT_OPT = 1 } vpMbtOptimizationMethod;
108 
109 protected:
110   //! The camera parameters.
111   vpCameraParameters m_cam;
112   //! The current pose.
113   vpHomogeneousMatrix m_cMo;
114   //! The Degrees of Freedom to estimate
115   vpMatrix oJo;
116   //! Boolean to know if oJo is identity (for fast computation)
117   bool isoJoIdentity;
118   //! The name of the file containing the model (it is used to create a file
119   //! name.0.pos used to store the compute pose in the initClick method).
120   std::string modelFileName;
121   //! Flag used to ensure that the CAD model is loaded before the
122   //! initialisation.
123   bool modelInitialised;
124   //! Filename used to save the initial pose computed using the initClick()
125   //! method. It is also used to read a previous pose in the same method.
126   std::string poseSavingFilename;
127   //! Flag used to specify if the covariance matrix has to be computed or not.
128   bool computeCovariance;
129   //! Covariance matrix
130   vpMatrix covarianceMatrix;
131   //! Flag used to specify if the gradient error criteria has to be computed
132   //! or not.
133   bool computeProjError;
134   //! Error angle between the gradient direction of the model features
135   //! projected at the resulting pose and their normal.
136   double projectionError;
137   //! If true, the features are displayed.
138   bool displayFeatures;
139   //! Optimization method used
140   vpMbtOptimizationMethod m_optimizationMethod;
141 
142   //! Set of faces describing the object.
143   vpMbHiddenFaces<vpMbtPolygon> faces;
144   //! Angle used to detect a face appearance
145   double angleAppears;
146   //! Angle used to detect a face disappearance
147   double angleDisappears;
148   //! Distance for near clipping
149   double distNearClip;
150   //! Distance for near clipping
151   double distFarClip;
152   //! Flags specifying which clipping to used
153   unsigned int clippingFlag;
154   //! Use Ogre3d for visibility tests
155   bool useOgre;
156   bool ogreShowConfigDialog;
157   //! Use Scanline for visibility tests
158   bool useScanLine;
159   //! Number of points in CAO model
160   unsigned int nbPoints;
161   //! Number of lines in CAO model
162   unsigned int nbLines;
163   //! Number of polygon lines in CAO model
164   unsigned int nbPolygonLines;
165   //! Number of polygon points in CAO model
166   unsigned int nbPolygonPoints;
167   //! Number of cylinders in CAO model
168   unsigned int nbCylinders;
169   //! Number of circles in CAO model
170   unsigned int nbCircles;
171   //! True if LOD mode is enabled
172   bool useLodGeneral;
173   //! True if the CAO model is loaded before the call to loadConfigFile,
174   //! (deduced by the number of polygons)
175   bool applyLodSettingInConfig;
176   //! Minimum line length threshold for LOD mode (general setting)
177   double minLineLengthThresholdGeneral;
178   //! Minimum polygon area threshold for LOD mode (general setting)
179   double minPolygonAreaThresholdGeneral;
180   //! Map with [map.first]=parameter_names and [map.second]=type (string,
181   //! number or boolean)
182   std::map<std::string, std::string> mapOfParameterNames;
183   //! If true, compute the interaction matrix at each iteration of the
184   //! minimization. Otherwise, compute it only on the first iteration
185   bool m_computeInteraction;
186   //! Gain of the virtual visual servoing stage
187   double m_lambda;
188   //! Maximum number of iterations of the virtual visual servoing stage
189   unsigned int m_maxIter;
190   //! Epsilon threshold to stop the VVS optimization loop
191   double m_stopCriteriaEpsilon;
192   //! Initial Mu for Levenberg Marquardt optimization loop
193   double m_initialMu;
194 
195   //! Distance line primitives for projection error
196   std::vector<vpMbtDistanceLine *> m_projectionErrorLines;
197   //! Distance cylinder primitives for projection error
198   std::vector<vpMbtDistanceCylinder *> m_projectionErrorCylinders;
199   //! Distance circle primitive for projection error
200   std::vector<vpMbtDistanceCircle *> m_projectionErrorCircles;
201   //! Set of faces describing the object, used for projection error
202   vpMbHiddenFaces<vpMbtPolygon> m_projectionErrorFaces;
203   bool m_projectionErrorOgreShowConfigDialog;
204   //! Moving-Edges parameters for projection error
205   vpMe m_projectionErrorMe;
206   //! Kernel size used to compute the gradient orientation
207   unsigned int m_projectionErrorKernelSize;
208   //! Sobel kernel in X
209   vpMatrix m_SobelX;
210   //! Sobel kernel in Y
211   vpMatrix m_SobelY;
212   //! Display gradient and model orientation for projection error computation
213   bool m_projectionErrorDisplay;
214   //! Length of the arrows used to show the gradient and model orientation
215   unsigned int m_projectionErrorDisplayLength;
216   //! Thickness of the arrows used to show the gradient and model orientation
217   unsigned int m_projectionErrorDisplayThickness;
218   //! Camera parameters used for projection error computation
219   vpCameraParameters m_projectionErrorCam;
220   //! Mask used to disable tracking on a part of image
221   const vpImage<bool> *m_mask;
222   //! Grayscale image buffer, used when passing color images
223   vpImage<unsigned char> m_I;
224   //! Flag that indicates that SoDB::init(); was called
225   bool m_sodb_init_called;
226   //! Random number generator used in vpMbtDistanceLine::buildFrom()
227   vpUniRand m_rand;
228 
229 public:
230   vpMbTracker();
231   virtual ~vpMbTracker();
232 
233   /** @name Inherited functionalities from vpMbTracker */
234   virtual double computeCurrentProjectionError(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &_cMo,
235                                                const vpCameraParameters &_cam);
236 
237   /*! Return the angle used to test polygons appearance. */
getAngleAppear()238   virtual inline double getAngleAppear() const { return angleAppears; }
239 
240   /*! Return the angle used to test polygons disappearance. */
getAngleDisappear()241   virtual inline double getAngleDisappear() const { return angleDisappears; }
242 
243   /*!
244     Get the camera parameters.
245 
246     \param cam : copy of the camera parameters used by the tracker.
247   */
getCameraParameters(vpCameraParameters & cam)248   virtual void getCameraParameters(vpCameraParameters &cam) const { cam = m_cam; }
249 
250   /*!
251     Get the clipping used and defined in
252     vpPolygon3D::vpMbtPolygonClippingType.
253 
254     \return Clipping flags.
255   */
getClipping()256   virtual inline unsigned int getClipping() const { return clippingFlag; }
257 
258   /*!
259     Get the covariance matrix. This matrix is only computed if
260     setCovarianceComputation() is turned on.
261 
262     \sa setCovarianceComputation()
263   */
264 
getCovarianceMatrix()265   virtual vpMatrix getCovarianceMatrix() const
266   {
267     if (!computeCovariance) {
268       //      vpTRACE("Warning : The covariance matrix has not been computed.
269       //      See setCovarianceComputation() to do it.");
270       std::cerr << "Warning : The covariance matrix has not been computed. "
271                    "See setCovarianceComputation() to do it."
272                 << std::endl;
273     }
274 
275     return covarianceMatrix;
276   }
277 
278   /*!
279     Get the initial value of mu used in the Levenberg Marquardt optimization
280     loop.
281 
282     \return the initial mu value.
283   */
getInitialMu()284   virtual inline double getInitialMu() const { return m_initialMu; }
285 
286   /*!
287     Get the value of the gain used to compute the control law.
288 
289     \return the value for the gain.
290   */
getLambda()291   virtual inline double getLambda() const { return m_lambda; }
292 
293   /*!
294     Get the maximum number of iterations of the virtual visual servoing stage.
295 
296     \return the number of iteration
297    */
getMaxIter()298   virtual inline unsigned int getMaxIter() const { return m_maxIter; }
299 
300   /*!
301     Get the error angle between the gradient direction of the model features
302     projected at the resulting pose and their normal. The error is expressed
303     in degree between 0 and 90. This value is computed if
304     setProjectionErrorComputation() is turned on.
305 
306     \return the value for the error.
307 
308     \sa setProjectionErrorComputation()
309   */
getProjectionError()310   virtual double getProjectionError() const { return projectionError; }
311 
312   virtual vpColVector getEstimatedDoF() const;
313 
314   /*!
315     Return the error vector \f$(s-s^*)\f$ reached after the virtual visual
316     servoing process used to estimate the pose.
317 
318     The following example shows how to use this function to compute the norm
319     of the residual and the norm of the residual normalized by the number of
320     features that are tracked:
321     \code
322     tracker.track(I); std::cout << "Residual: " << sqrt( (tracker.getError()).sumSquare()) << std::endl;
323     std::cout << "Residual normalized: "
324               << sqrt( (tracker.getError()).sumSquare())/tracker.getError().size() << std::endl;
325     \endcode
326 
327     \sa getRobustWeights()
328    */
329   virtual vpColVector getError() const = 0;
330 
331   /*! Return a reference to the faces structure. */
getFaces()332   virtual inline vpMbHiddenFaces<vpMbtPolygon> &getFaces() { return faces; }
333 
334   /*!
335     Get the far distance for clipping.
336 
337     \return Far clipping value.
338   */
getFarClippingDistance()339   virtual inline double getFarClippingDistance() const { return distFarClip; }
340 
341   /*!
342     Return the weights vector \f$w_i\f$ computed by the robust scheme.
343 
344     The following example shows how to use this function to compute the norm
345     of the weighted residual and the norm of the weighted residual normalized
346     by the sum of the weights associated to the features that are tracked:
347     \code
348       tracker.track(I);
349       vpColVector w = tracker.getRobustWeights();
350       vpColVector e = tracker.getError();
351       vpColVector we(w.size());
352       for(unsigned int i=0; i<w.size(); i++)
353         we[i] = w[i]*e[i];
354 
355       std::cout << "Weighted residual: " << sqrt( (we).sumSquare() ) << std::endl;
356       std::cout << "Weighted residual normalized: " << sqrt( (we).sumSquare() ) / w.sum() << std::endl;
357     \endcode
358 
359     \sa getError()
360    */
361   virtual vpColVector getRobustWeights() const = 0;
362 
363   /*!
364     Get the number of polygons (faces) representing the object to track.
365 
366     \return Number of polygons.
367   */
getNbPolygon()368   virtual inline unsigned int getNbPolygon() const { return static_cast<unsigned int>(faces.size()); }
369 
370   /*!
371     Get the near distance for clipping.
372 
373     \return Near clipping value.
374   */
getNearClippingDistance()375   virtual inline double getNearClippingDistance() const { return distNearClip; }
376 
377   /*!
378     Get the optimization method used during the tracking.
379     0 = Gauss-Newton approach.
380     1 = Levenberg-Marquardt approach.
381 
382     \return Optimization method.
383   */
getOptimizationMethod()384   virtual inline vpMbtOptimizationMethod getOptimizationMethod() const { return m_optimizationMethod; }
385 
386   /*!
387     Return the polygon (face) "index".
388 
389     \exception vpException::dimensionError if index does not represent a good
390     polygon.
391 
392     \param index : Index of the polygon to return.
393     \return Pointer to the polygon index.
394   */
getPolygon(unsigned int index)395   virtual inline vpMbtPolygon *getPolygon(unsigned int index)
396   {
397     if (index >= static_cast<unsigned int>(faces.size())) {
398       throw vpException(vpException::dimensionError, "index out of range");
399     }
400 
401     return faces[index];
402   }
403 
404   virtual std::pair<std::vector<vpPolygon>, std::vector<std::vector<vpPoint> > >
405   getPolygonFaces(bool orderPolygons = true, bool useVisibility = true, bool clipPolygon = false);
406 
407   /*!
408     Get the current pose between the object and the camera.
409     cMo is the matrix which can be used to express
410     coordinates from the object frame to camera frame.
411 
412     \param cMo : the pose
413   */
getPose(vpHomogeneousMatrix & cMo)414   virtual inline void getPose(vpHomogeneousMatrix &cMo) const { cMo = m_cMo; }
415 
416   /*!
417     Get the current pose between the object and the camera.
418     cMo is the matrix which can be used to express
419     coordinates from the object frame to camera frame.
420 
421     \return the current pose
422   */
getPose()423   virtual inline vpHomogeneousMatrix getPose() const { return m_cMo; }
424 
getStopCriteriaEpsilon()425   virtual inline double getStopCriteriaEpsilon() const { return m_stopCriteriaEpsilon; }
426 
427 // Intializer
428 
429 #ifdef VISP_HAVE_MODULE_GUI
430   virtual void initClick(const vpImage<unsigned char> &I, const std::string &initFile, bool displayHelp = false,
431                          const vpHomogeneousMatrix &T=vpHomogeneousMatrix());
432   virtual void initClick(const vpImage<vpRGBa> &I_color, const std::string &initFile, bool displayHelp = false,
433                          const vpHomogeneousMatrix &T = vpHomogeneousMatrix());
434 
435   virtual void initClick(const vpImage<unsigned char> &I, const std::vector<vpPoint> &points3D_list,
436                          const std::string &displayFile = "");
437   virtual void initClick(const vpImage<vpRGBa> &I_color, const std::vector<vpPoint> &points3D_list,
438                          const std::string &displayFile = "");
439 #endif
440 
441   virtual void initFromPoints(const vpImage<unsigned char> &I, const std::string &initFile);
442   virtual void initFromPoints(const vpImage<vpRGBa> &I_color, const std::string &initFile);
443 
444   virtual void initFromPoints(const vpImage<unsigned char> &I, const std::vector<vpImagePoint> &points2D_list,
445                               const std::vector<vpPoint> &points3D_list);
446   virtual void initFromPoints(const vpImage<vpRGBa> &I_color, const std::vector<vpImagePoint> &points2D_list,
447                               const std::vector<vpPoint> &points3D_list);
448 
449   virtual void initFromPose(const vpImage<unsigned char> &I, const std::string &initFile);
450   virtual void initFromPose(const vpImage<vpRGBa> &I_color, const std::string &initFile);
451 
452   virtual void initFromPose(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo);
453   virtual void initFromPose(const vpImage<vpRGBa> &I_color, const vpHomogeneousMatrix &cMo);
454 
455   virtual void initFromPose(const vpImage<unsigned char> &I, const vpPoseVector &cPo);
456   virtual void initFromPose(const vpImage<vpRGBa> &I_color, const vpPoseVector &cPo);
457 
458   virtual void loadModel(const std::string &modelFile, bool verbose = false, const vpHomogeneousMatrix &T=vpHomogeneousMatrix());
459 
460   /*!
461     Set the angle used to test polygons appearance.
462     If the angle between the normal of the polygon and the line going
463     from the camera to the polygon center has a value lower than
464     this parameter, the polygon is considered as appearing.
465     The polygon will then be tracked.
466 
467     \param a : new angle in radian.
468   */
setAngleAppear(const double & a)469   virtual inline void setAngleAppear(const double &a) { angleAppears = a; }
470 
471   /*!
472     Set the angle used to test polygons disappearance.
473     If the angle between the normal of the polygon and the line going
474     from the camera to the polygon center has a value greater than
475     this parameter, the polygon is considered as disappearing.
476     The tracking of the polygon will then be stopped.
477 
478     \param a : new angle in radian.
479   */
setAngleDisappear(const double & a)480   virtual inline void setAngleDisappear(const double &a) { angleDisappears = a; }
481 
482   /*!
483     Set the camera parameters.
484 
485     \param cam : The new camera parameters.
486   */
setCameraParameters(const vpCameraParameters & cam)487   virtual void setCameraParameters(const vpCameraParameters &cam) { m_cam = cam; }
488 
489   virtual void setClipping(const unsigned int &flags);
490 
491   /*!
492     Set if the covariance matrix has to be computed.
493 
494     \param flag : True if the covariance has to be computed, false otherwise.
495     If computed its value is available with getCovarianceMatrix()
496 
497     \sa getCovarianceMatrix()
498   */
setCovarianceComputation(const bool & flag)499   virtual void setCovarianceComputation(const bool &flag) { computeCovariance = flag; }
500 
501   /*!
502     Enable to display the features. By features, we meant the moving edges
503     (ME) and the klt points if used.
504 
505     Note that if present, the moving edges can be displayed with different
506     colors:
507     - If green : The ME is a good point.
508     - If blue : The ME is removed because of a contrast problem during the
509     tracking phase.
510     - If purple : The ME is removed because of a threshold problem during the
511     tracking phase.
512     - If red : The ME is removed because it is rejected by the robust approach
513     in the virtual visual servoing scheme.
514 
515     \param displayF : set it to true to display the features.
516   */
setDisplayFeatures(bool displayF)517   virtual void setDisplayFeatures(bool displayF) { displayFeatures = displayF; }
518 
519   virtual void setEstimatedDoF(const vpColVector &v);
520 
521   virtual void setFarClippingDistance(const double &dist);
522 
523   /*!
524     Set the initial value of mu for the Levenberg Marquardt optimization loop.
525 
526     \param mu : initial mu.
527   */
setInitialMu(double mu)528   virtual inline void setInitialMu(double mu) { m_initialMu = mu; }
529 
530   /*!
531     Set the value of the gain used to compute the control law.
532 
533     \param gain : the desired value for the gain.
534   */
setLambda(double gain)535   virtual inline void setLambda(double gain) { m_lambda = gain; }
536 
537   virtual void setLod(bool useLod, const std::string &name = "");
538 
539   /*!
540     Set the maximum iteration of the virtual visual servoing stage.
541 
542     \param max : the desired number of iteration
543    */
setMaxIter(unsigned int max)544   virtual inline void setMaxIter(unsigned int max) { m_maxIter = max; }
545 
546   virtual void setMinLineLengthThresh(double minLineLengthThresh, const std::string &name = "");
547 
548   virtual void setMinPolygonAreaThresh(double minPolygonAreaThresh, const std::string &name = "");
549 
550   virtual void setNearClippingDistance(const double &dist);
551 
552   /*!
553     Set the optimization method used during the tracking.
554 
555     \param opt : Optimization method to use.
556   */
setOptimizationMethod(const vpMbtOptimizationMethod & opt)557   virtual inline void setOptimizationMethod(const vpMbtOptimizationMethod &opt) { m_optimizationMethod = opt; }
558 
559   void setProjectionErrorMovingEdge(const vpMe &me);
560 
561   void setProjectionErrorKernelSize(const unsigned int &size);
562 
setMask(const vpImage<bool> & mask)563   virtual void setMask(const vpImage<bool> &mask) { m_mask = &mask; }
564 
565   /*!
566     Set the minimal error (previous / current estimation) to determine if
567     there is convergence or not.
568 
569     \param eps : Epsilon threshold.
570   */
setStopCriteriaEpsilon(const double eps)571   virtual inline void setStopCriteriaEpsilon(const double eps) { m_stopCriteriaEpsilon = eps; }
572 
573   /*!
574     Set if the projection error criteria has to be computed. This criteria
575     could be used to detect the quality of the tracking. It computes an angle
576     between 0 and 90 degrees that is available with getProjectionError().
577     Closer to 0 is the value, better is the tracking.
578 
579     \param flag : True if the projection error criteria has to be computed,
580     false otherwise.
581 
582     \sa getProjectionError()
583   */
setProjectionErrorComputation(const bool & flag)584   virtual void setProjectionErrorComputation(const bool &flag) { computeProjError = flag; }
585 
586   /*!
587     Display or not gradient and model orientation when computing the projection error.
588   */
setProjectionErrorDisplay(bool display)589   virtual void setProjectionErrorDisplay(bool display) { m_projectionErrorDisplay = display; }
590 
591   /*!
592     Arrow length used to display gradient and model orientation for projection error computation.
593   */
setProjectionErrorDisplayArrowLength(unsigned int length)594   virtual void setProjectionErrorDisplayArrowLength(unsigned int length) { m_projectionErrorDisplayLength = length; }
595 
596   /*!
597     Arrow thickness used to display gradient and model orientation for projection error computation.
598   */
setProjectionErrorDisplayArrowThickness(unsigned int thickness)599   virtual void setProjectionErrorDisplayArrowThickness(unsigned int thickness) { m_projectionErrorDisplayThickness = thickness; }
600 
setScanLineVisibilityTest(const bool & v)601   virtual void setScanLineVisibilityTest(const bool &v) { useScanLine = v; }
602 
603   virtual void setOgreVisibilityTest(const bool &v);
604 
605   void savePose(const std::string &filename) const;
606 
607 #ifdef VISP_HAVE_OGRE
608   /*!
609     Set the ratio of visibility attempts that has to be successful to consider
610     a polygon as visible.
611 
612     \sa setNbRayCastingAttemptsForVisibility(const unsigned int &)
613 
614     \param ratio : Ratio of succesful attempts that has to be considered.
615     Value has to be between 0.0 (0%) and 1.0 (100%).
616   */
setGoodNbRayCastingAttemptsRatio(const double & ratio)617   virtual void setGoodNbRayCastingAttemptsRatio(const double &ratio) { faces.setGoodNbRayCastingAttemptsRatio(ratio); }
618   /*!
619     Set the number of rays that will be sent toward each polygon for
620     visibility test. Each ray will go from the optic center of the camera to a
621     random point inside the considered polygon.
622 
623     \sa setGoodNbRayCastingAttemptsRatio(const unsigned int &)
624 
625     \param attempts Number of rays to be sent.
626   */
setNbRayCastingAttemptsForVisibility(const unsigned int & attempts)627   virtual void setNbRayCastingAttemptsForVisibility(const unsigned int &attempts)
628   {
629     faces.setNbRayCastingAttemptsForVisibility(attempts);
630   }
631 #endif
632 
633   /*!
634     Enable/Disable the appearance of Ogre config dialog on startup.
635 
636     \warning This method has only effect when Ogre is used and Ogre visibility
637     test is enabled using setOgreVisibilityTest() with true parameter.
638 
639     \param showConfigDialog : if true, shows Ogre dialog window (used to set
640     Ogre rendering options) when Ogre visibility is enabled. By default, this
641     functionality is turned off.
642   */
setOgreShowConfigDialog(bool showConfigDialog)643   inline virtual void setOgreShowConfigDialog(bool showConfigDialog) { ogreShowConfigDialog = showConfigDialog; }
644 
645   /*!
646     Set the filename used to save the initial pose computed using the
647     initClick() method. It is also used to read a previous pose in the same
648     method. If the file is not set then, the initClick() method will create a
649     .0.pos file in the root directory. This directory is the path to the file
650     given to the method initClick() used to know the coordinates in the object
651     frame.
652 
653     \param filename : The new filename.
654   */
setPoseSavingFilename(const std::string & filename)655   inline void setPoseSavingFilename(const std::string &filename) { poseSavingFilename = filename; }
656 
657   /* PURE VIRTUAL METHODS */
658 
659   /*!
660     Display the 3D model at a given position using the given camera parameters
661     on a grey level image.
662 
663     \param I : The image.
664     \param cMo : Pose used to project the 3D model into the image.
665     \param cam : The camera parameters.
666     \param col : The desired color.
667     \param thickness : The thickness of the lines.
668     \param displayFullModel : If true, the full model is displayed (even the
669     non visible surfaces).
670   */
671   virtual void display(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
672                        const vpColor &col, unsigned int thickness = 1, bool displayFullModel = false) = 0;
673   /*!
674     Display the 3D model at a given position using the given camera parameters
675     on a color (RGBa) image.
676 
677     \param I : The image.
678     \param cMo : Pose used to project the 3D model into the image.
679     \param cam : The camera parameters.
680     \param col : The desired color.
681     \param thickness : The thickness of the lines.
682     \param displayFullModel : If true, the full model is displayed (even the
683     non visible surfaces).
684   */
685   virtual void display(const vpImage<vpRGBa> &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
686                        const vpColor &col, unsigned int thickness = 1, bool displayFullModel = false) = 0;
687 
688   virtual std::vector<std::vector<double> > getModelForDisplay(unsigned int width, unsigned int height,
689                                                                const vpHomogeneousMatrix &cMo,
690                                                                const vpCameraParameters &cam,
691                                                                bool displayFullModel=false)=0;
692 
693   /*!
694     Initialise the tracking.
695 
696     \param I : Input image.
697   */
698   virtual void init(const vpImage<unsigned char> &I) = 0;
699 
700   /*!
701     Load a config file to parameterise the behavior of the tracker.
702 
703     Virtual method to adapt to each tracker.
704 
705     \param configFile : An xml config file to parse.
706     \param verbose : verbose flag.
707   */
708   virtual void loadConfigFile(const std::string &configFile, bool verbose=true);
709 
710   /*!
711     Reset the tracker.
712   */
713   virtual void resetTracker() = 0;
714 
715   /*!
716     Set the pose to be used in entry of the next call to the track() function.
717     This pose will be just used once.
718 
719     \warning This function has to be called after the initialisation of the
720     tracker.
721 
722     \param I : grayscale image corresponding to the desired pose.
723     \param cdMo : Pose to affect.
724   */
725   virtual void setPose(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cdMo) = 0;
726 
727   /*!
728     Set the pose to be used in entry of the next call to the track() function.
729     This pose will be just used once.
730 
731     \warning This function has to be called after the initialisation of the
732     tracker.
733 
734     \param I_color : color image corresponding to the desired pose.
735     \param cdMo : Pose to affect.
736   */
737   virtual void setPose(const vpImage<vpRGBa> &I_color, const vpHomogeneousMatrix &cdMo) = 0;
738 
739   /*!
740     Test the quality of the tracking.
741 
742     \throw vpException if the test fail.
743   */
744   virtual void testTracking() = 0;
745 
746   /*!
747     Track the object in the given image
748 
749     \param I : The current image.
750   */
751   virtual void track(const vpImage<unsigned char> &I) = 0;
752 
753   /*!
754     Track the object in the given image
755 
756     \param I : The current image.
757   */
758   virtual void track(const vpImage<vpRGBa> &I) = 0;
759 
760 protected:
761   /** @name Protected Member Functions Inherited from vpMbTracker */
762   void addPolygon(const std::vector<vpPoint> &corners, int idFace = -1, const std::string &polygonName = "",
763                   bool useLod = false, double minPolygonAreaThreshold = 2500.0,
764                   double minLineLengthThreshold = 50.0);
765   void addPolygon(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace = -1,
766                   const std::string &polygonName = "", bool useLod = false,
767                   double minPolygonAreaThreshold = 2500.0);
768   void addPolygon(const vpPoint &p1, const vpPoint &p2, int idFace = -1, const std::string &polygonName = "",
769                   bool useLod = false, double minLineLengthThreshold = 50);
770   void addPolygon(const std::vector<std::vector<vpPoint> > &listFaces, int idFace = -1,
771                   const std::string &polygonName = "", bool useLod = false,
772                   double minLineLengthThreshold = 50);
773 
774   void addProjectionErrorCircle(const vpPoint &P1, const vpPoint &P2, const vpPoint &P3, double r, int idFace = -1,
775                                 const std::string &name = "");
776   void addProjectionErrorCylinder(const vpPoint &P1, const vpPoint &P2, double r, int idFace = -1, const std::string &name = "");
777   void addProjectionErrorLine(vpPoint &p1, vpPoint &p2, int polygon = -1, std::string name = "");
778 
779   void addProjectionErrorPolygon(const std::vector<vpPoint> &corners, int idFace = -1, const std::string &polygonName = "",
780                                  bool useLod = false, double minPolygonAreaThreshold = 2500.0,
781                                  const double minLineLengthThreshold = 50.0);
782   void addProjectionErrorPolygon(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius, int idFace = -1,
783                                  const std::string &polygonName = "", bool useLod = false,
784                                  double minPolygonAreaThreshold = 2500.0);
785   void addProjectionErrorPolygon(const vpPoint &p1, const vpPoint &p2, int idFace = -1, const std::string &polygonName = "",
786                                  bool useLod = false, double minLineLengthThreshold = 50);
787   void addProjectionErrorPolygon(const std::vector<std::vector<vpPoint> > &listFaces, int idFace = -1,
788                                  const std::string &polygonName = "", bool useLod = false,
789                                  double minLineLengthThreshold = 50);
790 
791   void createCylinderBBox(const vpPoint &p1, const vpPoint &p2, const double &radius,
792                           std::vector<std::vector<vpPoint> > &listFaces);
793 
794   virtual void computeCovarianceMatrixVVS(const bool isoJoIdentity_, const vpColVector &w_true,
795                                           const vpHomogeneousMatrix &cMoPrev, const vpMatrix &L_true,
796                                           const vpMatrix &LVJ_true, const vpColVector &error);
797 
798   void computeJTR(const vpMatrix &J, const vpColVector &R, vpColVector &JTR) const;
799 
800   double computeProjectionErrorImpl(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &_cMo,
801                                     const vpCameraParameters &_cam, unsigned int &nbFeatures);
802 
803   virtual void computeVVSCheckLevenbergMarquardt(unsigned int iter, vpColVector &error,
804                                                  const vpColVector &m_error_prev, const vpHomogeneousMatrix &cMoPrev,
805                                                  double &mu, bool &reStartFromLastIncrement,
806                                                  vpColVector *const w = NULL, const vpColVector *const m_w_prev = NULL);
807   virtual void computeVVSInit() = 0;
808   virtual void computeVVSInteractionMatrixAndResidu() = 0;
809   virtual void computeVVSPoseEstimation(const bool isoJoIdentity_, unsigned int iter, vpMatrix &L, vpMatrix &LTL,
810                                         vpColVector &R, const vpColVector &error, vpColVector &error_prev,
811                                         vpColVector &LTR, double &mu, vpColVector &v, const vpColVector *const w = NULL,
812                                         vpColVector *const m_w_prev = NULL);
813   virtual void computeVVSWeights(vpRobust &robust, const vpColVector &error, vpColVector &w);
814 
815 #ifdef VISP_HAVE_COIN3D
816   virtual void extractGroup(SoVRMLGroup *sceneGraphVRML2, vpHomogeneousMatrix &transform, int &idFace);
817   virtual void extractFaces(SoVRMLIndexedFaceSet *face_set, vpHomogeneousMatrix &transform, int &idFace,
818                             const std::string &polygonName = "");
819   virtual void extractLines(SoVRMLIndexedLineSet *line_set, int &idFace, const std::string &polygonName = "");
820   virtual void extractCylinders(SoVRMLIndexedFaceSet *face_set, vpHomogeneousMatrix &transform, int &idFace,
821                                 const std::string &polygonName = "");
822 #endif
823 
824   vpPoint getGravityCenter(const std::vector<vpPoint> &_pts) const;
825 
826   /*!
827     Add a circle to track from its center, 3 points (including the center)
828     defining the plane that contain the circle and its radius.
829 
830     \param p1 : Center of the circle.
831     \param p2 : A point on the plane containing the circle.
832     \param p3 : An other point on the plane containing the circle. With the
833     center of the circle \e p1, \e p2 and \e p3 we have 3 points defining the
834     plane that contains the circle.
835     \param radius : Radius of the circle.
836     \param idFace : Id of the face associated to the circle.
837     \param name : Name of the circle.
838   */
839   virtual void initCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius,
840                           int idFace = 0, const std::string &name = "") = 0;
841 
842 #ifdef VISP_HAVE_MODULE_GUI
843   virtual void initClick(const vpImage<unsigned char> * const I, const vpImage<vpRGBa> * const I_color, const std::string &initFile,
844                          bool displayHelp = false, const vpHomogeneousMatrix &T = vpHomogeneousMatrix());
845 
846   virtual void initClick(const vpImage<unsigned char> * const I, const vpImage<vpRGBa> * const I_color,
847                          const std::vector<vpPoint> &points3D_list, const std::string &displayFile = "");
848 #endif
849 
850   virtual void initFromPoints(const vpImage<unsigned char> * const I, const vpImage<vpRGBa> * const I_color,
851                               const std::string &initFile);
852 
853   virtual void initFromPoints(const vpImage<unsigned char> * const I, const vpImage<vpRGBa> * const I_color,
854                               const std::vector<vpImagePoint> &points2D_list, const std::vector<vpPoint> &points3D_list);
855 
856   virtual void initFromPose(const vpImage<unsigned char> * const I, const vpImage<vpRGBa> * const I_color,
857                             const std::string &initFile);
858 
859   /*!
860     Add a cylinder to track from two points on the axis (defining the length
861     of the cylinder) and its radius.
862 
863     \param p1 : First point on the axis.
864     \param p2 : Second point on the axis.
865     \param radius : Radius of the cylinder.
866     \param idFace : Id of the face associated to the cylinder.
867     \param name : Name of the cylinder.
868   */
869   virtual void initCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace = 0,
870                             const std::string &name = "") = 0;
871 
872   /*!
873     Add the lines to track from the polygon description. If the polygon has
874     only two points, it defines a single line that is always visible. If it
875     has three or more corners, it defines a face. In that case the visibility
876     of the face is computed in order to track the corresponding lines only if
877     the face is visible.
878 
879     The id of the polygon is supposed to be set prior calling this function.
880 
881     \param polygon : The polygon describing the set of lines that has to be
882     tracked.
883   */
884   virtual void initFaceFromCorners(vpMbtPolygon &polygon) = 0;
885   virtual void initFaceFromLines(vpMbtPolygon &polygon) = 0;
886 
887   void initProjectionErrorCircle(const vpPoint &p1, const vpPoint &p2, const vpPoint &p3, double radius,
888                                  int idFace = 0, const std::string &name = "");
889   void initProjectionErrorCylinder(const vpPoint &p1, const vpPoint &p2, double radius, int idFace = 0,
890                                    const std::string &name = "");
891   void initProjectionErrorFaceFromCorners(vpMbtPolygon &polygon);
892   void initProjectionErrorFaceFromLines(vpMbtPolygon &polygon);
893 
894   virtual void loadVRMLModel(const std::string &modelFile);
895   virtual void loadCAOModel(const std::string &modelFile, std::vector<std::string> &vectorOfModelFilename,
896                             int &startIdFace, bool verbose = false, bool parent = true,
897                             const vpHomogeneousMatrix &T=vpHomogeneousMatrix());
898 
899   void projectionErrorInitMovingEdge(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &_cMo);
900   void projectionErrorResetMovingEdges();
901   void projectionErrorVisibleFace(unsigned int width, unsigned int height, const vpHomogeneousMatrix &_cMo);
902 
903   void removeComment(std::ifstream &fileId);
904 
905   std::map<std::string, std::string> parseParameters(std::string &endLine);
906 
907   bool samePoint(const vpPoint &P1, const vpPoint &P2) const;
908 };
909 
910 #endif
911