42#include <visp3/core/vpConfig.h>
44#if (defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY)) && \
45 (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
47#include <visp3/core/vpDebug.h>
48#include <visp3/core/vpHomogeneousMatrix.h>
49#include <visp3/core/vpIoTools.h>
50#include <visp3/core/vpMath.h>
51#include <visp3/gui/vpDisplayD3D.h>
52#include <visp3/gui/vpDisplayGDI.h>
53#include <visp3/gui/vpDisplayGTK.h>
54#include <visp3/gui/vpDisplayOpenCV.h>
55#include <visp3/gui/vpDisplayX.h>
56#include <visp3/io/vpImageIo.h>
57#include <visp3/io/vpParseArgv.h>
58#include <visp3/io/vpVideoReader.h>
59#include <visp3/mbt/vpMbGenericTracker.h>
61#define GETOPTARGS "cCde:fhi:lm:n:opstT:x:vw"
63#ifdef ENABLE_VISP_NAMESPACE
67void usage(
const char *name,
const char *badparam)
69#if defined(VISP_HAVE_DATASET)
70#if VISP_HAVE_DATASET_VERSION >= 0x030600
71 std::string ext(
"png");
73 std::string ext(
"pgm");
77 std::string ext(
"png");
80Example of tracking based on the 3D model.\n\
83 %s [-i <test image path>] [-x <config file>]\n\
84 [-m <model name>] [-n <initialisation file base name>] [-e <last frame index>]\n\
85 [-t] [-c] [-d] [-h] [-f] [-C] [-o] [-w] [-l] [-v] [-p] [-s]\n\
86 [-T <tracker type>]\n",
91 -i <input image path> \n\
92 Set image input path.\n\
93 From this path read images \n\
94 \"mbt/cube/image%%04d.%s\". These \n\
95 images come from visp-images-x.y.z.tar.gz available \n\
96 on the ViSP website.\n\
97 Setting the VISP_INPUT_IMAGE_PATH environment\n\
98 variable produces the same behavior than using\n\
102 Set the config file (the xml file) to use.\n\
103 The config file is used to specify the parameters of the tracker.\n\
106 Specify the name of the file of the model\n\
107 The model can either be a vrml model (.wrl) or a .cao file.\n\
109 -e <last frame index> \n\
110 Specify the index of the last frame. Once reached, the tracking is stopped\n\
113 Enable step-by-step mode when click is allowed.\n\
116 Do not use the vrml model, use the .cao one. These two models are \n\
117 equivalent and comes from ViSP-images-x.y.z.tar.gz available on the ViSP\n\
118 website. However, the .cao model allows to use the 3d model based tracker \n\
122 Track only the cube (not the cylinder). In this case the models files are\n\
123 cube.cao or cube.wrl instead of cube_and_cylinder.cao and \n\
124 cube_and_cylinder.wrl.\n\
126 -n <initialisation file base name> \n\
127 Base name of the initialisation file. The file will be 'base_name'.init .\n\
128 This base name is also used for the optional picture specifying where to \n\
129 click (a .ppm picture).\n\
132 Turn off the display of the the moving edges and Klt points. \n\
135 Turn off the display.\n\
138 Disable the mouse click. Useful to automate the \n\
139 execution of this program without human intervention.\n\
142 Use Ogre3D for visibility tests\n\
145 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\
148 Use the scanline for visibility tests.\n\
151 Compute covariance matrix.\n\
154 Compute gradient projection error.\n\
157 Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (EdgeKlt)>).\n\
160 Print the help.\n\n", ext.c_str());
163 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
166bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &configFile, std::string &modelFile,
167 std::string &initFile,
long &lastFrame,
bool &displayFeatures,
bool &click_allowed,
bool &display,
168 bool &cao3DModel,
bool &trackCylinder,
bool &useOgre,
bool &showOgreConfigDialog,
bool &useScanline,
169 bool &computeCovariance,
bool &projectionError,
int &trackerType,
bool &step_by_step)
180 lastFrame = atol(optarg_);
186 configFile = optarg_;
195 displayFeatures =
false;
201 click_allowed =
false;
207 trackCylinder =
false;
216 showOgreConfigDialog =
true;
219 computeCovariance =
true;
222 projectionError =
true;
225 trackerType = atoi(optarg_);
228 usage(argv[0],
nullptr);
232 usage(argv[0], optarg_);
237 if ((c == 1) || (c == -1)) {
239 usage(argv[0],
nullptr);
240 std::cerr <<
"ERROR: " << std::endl;
241 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
248int main(
int argc,
const char **argv)
251 std::string env_ipath;
252 std::string opt_ipath;
254 std::string opt_configFile;
255 std::string opt_modelFile;
256 std::string modelFile;
257 std::string opt_initFile;
258 std::string initFile;
259 long opt_lastFrame = -1;
260 bool displayFeatures =
true;
261 bool opt_click_allowed =
true;
262 bool opt_display =
true;
263 bool cao3DModel =
false;
264 bool trackCylinder =
true;
265 bool useOgre =
false;
266 bool showOgreConfigDialog =
false;
267 bool useScanline =
false;
268 bool computeCovariance =
false;
269 bool projectionError =
false;
271 bool opt_step_by_step =
false;
273#if defined(VISP_HAVE_DATASET)
274#if VISP_HAVE_DATASET_VERSION >= 0x030600
275 std::string ext(
"png");
277 std::string ext(
"pgm");
281 std::string ext(
"png");
289 if (!env_ipath.empty())
293 if (!getOptions(argc, argv, opt_ipath, opt_configFile, opt_modelFile, opt_initFile, opt_lastFrame, displayFeatures,
294 opt_click_allowed, opt_display, cao3DModel, trackCylinder, useOgre, showOgreConfigDialog,
295 useScanline, computeCovariance, projectionError, trackerType, opt_step_by_step)) {
300 if (opt_ipath.empty() && env_ipath.empty()) {
301 usage(argv[0],
nullptr);
302 std::cerr << std::endl <<
"ERROR:" << std::endl;
303 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
304 <<
" environment variable to specify the location of the " << std::endl
305 <<
" image path where test images are located." << std::endl
312 if (!opt_ipath.empty())
317#if defined(VISP_HAVE_PUGIXML)
318 std::string configFile;
319 if (!opt_configFile.empty())
320 configFile = opt_configFile;
321 else if (!opt_ipath.empty())
327 if (!opt_modelFile.empty()) {
328 modelFile = opt_modelFile;
331 std::string modelFileCao;
332 std::string modelFileWrl;
334 modelFileCao =
"mbt/cube_and_cylinder.cao";
335 modelFileWrl =
"mbt/cube_and_cylinder.wrl";
338 modelFileCao =
"mbt/cube.cao";
339 modelFileWrl =
"mbt/cube.wrl";
342 if (!opt_ipath.empty()) {
347#ifdef VISP_HAVE_COIN3D
350 std::cerr <<
"Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
360#ifdef VISP_HAVE_COIN3D
363 std::cerr <<
"Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
370 if (!opt_initFile.empty())
371 initFile = opt_initFile;
372 else if (!opt_ipath.empty())
377 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
388 std::cerr <<
"Cannot open sequence: " << ipath << std::endl;
399 mapOfImages[
"Camera1"] = &I1;
400 mapOfImages[
"Camera2"] = &I2;
401 mapOfImages[
"Camera3"] = &I3;
404#if defined(VISP_HAVE_X11)
406#elif defined(VISP_HAVE_GDI)
408#elif defined(HAVE_OPENCV_HIGHGUI)
410#elif defined(VISP_HAVE_D3D9)
412#elif defined(VISP_HAVE_GTK)
419#if defined(VISP_HAVE_DISPLAY)
424 display1.
init(I1, 100, 100,
"Test tracking (Cam1)");
439 std::map<std::string, vpHomogeneousMatrix> mapOfCameraPoses;
440 std::map<std::string, vpCameraParameters> mapOfCameraParams;
443#if defined(VISP_HAVE_PUGIXML)
445 std::map<std::string, std::string> mapOfConfigFiles;
446 mapOfConfigFiles[
"Camera1"] = configFile;
447 mapOfConfigFiles[
"Camera2"] = configFile;
448 mapOfConfigFiles[
"Camera3"] = configFile;
453 cam.initPersProjWithoutDistortion(547, 542, 338, 234);
454 mapOfCameraParams[
"Camera1"] =
cam;
455 mapOfCameraParams[
"Camera2"] =
cam;
456 mapOfCameraParams[
"Camera3"] =
cam;
467 std::map<std::string, vpMe> mapOfMe;
468 mapOfMe[
"Camera1"] = me;
469 mapOfMe[
"Camera2"] = me;
470 mapOfMe[
"Camera3"] = me;
472#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
481 std::map<std::string, vpKltOpencv> mapOfKlt;
482 mapOfKlt[
"Camera1"] = klt;
483 mapOfKlt[
"Camera2"] = klt;
484 mapOfKlt[
"Camera3"] = klt;
496 tracker->setNearClippingDistance(0.01);
497 tracker->setFarClippingDistance(0.90);
499 std::map<std::string, unsigned int> mapOfClippingFlags;
501 for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin(); it != mapOfClippingFlags.end();
513 tracker->setDisplayFeatures(displayFeatures);
516 tracker->setOgreVisibilityTest(useOgre);
518 tracker->setOgreShowConfigDialog(showOgreConfigDialog);
521 tracker->setScanLineVisibilityTest(useScanline);
524 tracker->setCovarianceComputation(computeCovariance);
527 tracker->setProjectionErrorComputation(projectionError);
533 if (opt_display && opt_click_allowed) {
550 if (opt_display && opt_click_allowed) {
551 std::map<std::string, std::string> mapOfInitFiles;
552 mapOfInitFiles[
"Camera1"] = initFile;
562 vpHomogeneousMatrix c1Moi(0.02044769891, 0.1101505452, 0.5078963719, 2.063603907, 1.110231561, -0.4392789872);
563 std::map<std::string, vpHomogeneousMatrix> mapOfInitPoses;
564 mapOfInitPoses[
"Camera1"] = c1Moi;
580 while (!reader.
end() && !quit) {
585 mapOfImages[
"Camera1"] = &I1;
586 mapOfImages[
"Camera2"] = &I2;
587 mapOfImages[
"Camera3"] = &I3;
595 std::stringstream ss;
602 std::cout <<
"----------Test reset tracker----------" << std::endl;
610#if defined(VISP_HAVE_PUGIXML)
614 cam.initPersProjWithoutDistortion(547, 542, 338, 234);
615 mapOfCameraParams[
"Camera1"] =
cam;
616 mapOfCameraParams[
"Camera2"] =
cam;
617 mapOfCameraParams[
"Camera3"] =
cam;
628 mapOfMe[
"Camera1"] = me;
629 mapOfMe[
"Camera2"] = me;
630 mapOfMe[
"Camera3"] = me;
632#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
641 mapOfKlt[
"Camera1"] = klt;
642 mapOfKlt[
"Camera2"] = klt;
643 mapOfKlt[
"Camera3"] = klt;
655 tracker->setNearClippingDistance(0.01);
656 tracker->setFarClippingDistance(0.90);
659 for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin();
660 it != mapOfClippingFlags.end(); ++it) {
671 tracker->setOgreVisibilityTest(useOgre);
672 tracker->setScanLineVisibilityTest(useScanline);
673 tracker->setCovarianceComputation(computeCovariance);
674 tracker->setProjectionErrorComputation(projectionError);
681 c1Moi.
buildFrom(0.0439540832, 0.0845870108, 0.5477322481, 2.179498458, 0.8611798108, -0.3491961946);
682 std::map<std::string, vpHomogeneousMatrix> mapOfSetPoses;
683 mapOfSetPoses[
"Camera1"] = c1Moi;
685 std::cout <<
"Test set pose" << std::endl;
697 std::map<std::string, const vpImage<unsigned char> *> mapOfSubImages;
698 mapOfSubImages[
"Camera1"] = &I1;
699 mapOfSubImages[
"Camera2"] = &I2;
715 if (opt_click_allowed && opt_display) {
719 if (opt_step_by_step) {
728 opt_step_by_step = !opt_step_by_step;
733 if (computeCovariance) {
734 std::cout <<
"Covariance matrix: \n" <<
tracker->getCovarianceMatrix() << std::endl << std::endl;
737 if (projectionError) {
738 std::cout <<
"Projection error: " <<
tracker->getProjectionError() << std::endl << std::endl;
748 std::cout <<
"Reached last frame: " << reader.
getFrameIndex() << std::endl;
749 std::cout <<
"\nFinal poses, c1Mo:\n"
750 << mapOfCameraPoses[
"Camera1"] <<
"\nc2Mo:\n"
751 << mapOfCameraPoses[
"Camera2"] <<
"\nc3Mo:\n"
752 << mapOfCameraPoses[
"Camera3"] << std::endl;
754 if (opt_click_allowed && !quit) {
765 std::cout <<
"Catch an exception: " <<
e << std::endl;
770#elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY))
773 std::cout <<
"Cannot run this example: visp_mbt, visp_gui modules are required." << std::endl;
779 std::cout <<
"Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
Generic class defining intrinsic camera parameters.
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
void init(vpImage< unsigned char > &I, int win_x=-1, int win_y=-1, const std::string &win_title="") VP_OVERRIDE
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
virtual void setDownScalingFactor(unsigned int scale)
static void display(const vpImage< unsigned char > &I)
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, const vpImagePoint &offset=vpImagePoint(0, 0), const std::string &frameName="", const vpColor &textColor=vpColor::black, const vpImagePoint &textOffset=vpImagePoint(15, 15))
static void flush(const vpImage< unsigned char > &I)
unsigned int getDownScalingFactor()
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
error that can be emitted by ViSP classes.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
void setBlockSize(int blockSize)
void setQuality(double qualityLevel)
void setHarrisFreeParameter(double harris_k)
void setMaxFeatures(int maxCount)
void setMinDistance(double minDistance)
void setWindowSize(int winSize)
void setPyramidLevels(int pyrMaxLevel)
static double rad(double deg)
Real-time 6D object pose tracking using its CAD model.
Main methods for a model-based tracker.
void setMu1(const double &mu_1)
void setRange(const unsigned int &range)
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
void setMaskNumber(const unsigned int &mask_number)
void setThreshold(const double &threshold)
void setSampleStep(const double &sample_step)
void setMaskSize(const unsigned int &mask_size)
void setMu2(const double &mu_2)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void setLastFrameIndex(const long last_frame)
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
long getFirstFrameIndex()
long getFrameIndex() const
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE