Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
mbtGenericTracking2.cpp
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 * Example of Hybrid Tracking of MBT and MBT KTL.
32 */
33
40
41#include <iostream>
42#include <visp3/core/vpConfig.h>
43
44#if (defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY)) && \
45 (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
46
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>
60
61#define GETOPTARGS "cCde:fhi:lm:n:opstT:x:vw"
62
63#ifdef ENABLE_VISP_NAMESPACE
64using namespace VISP_NAMESPACE_NAME;
65#endif
66
67void usage(const char *name, const char *badparam)
68{
69#if defined(VISP_HAVE_DATASET)
70#if VISP_HAVE_DATASET_VERSION >= 0x030600
71 std::string ext("png");
72#else
73 std::string ext("pgm");
74#endif
75#else
76// We suppose that the user will download a recent dataset
77 std::string ext("png");
78#endif
79 fprintf(stdout, "\n\
80Example of tracking based on the 3D model.\n\
81\n\
82SYNOPSIS\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",
87 name);
88
89 fprintf(stdout, "\n\
90OPTIONS: \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\
99 this option.\n\
100\n\
101 -x <config file> \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\
104\n\
105 -m <model name> \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\
108\n\
109 -e <last frame index> \n\
110 Specify the index of the last frame. Once reached, the tracking is stopped\n\
111\n\
112 -s \n\
113 Enable step-by-step mode when click is allowed.\n\
114\n\
115 -f \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\
119 without Coin.\n\
120\n\
121 -C \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\
125\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\
130\n\
131 -t \n\
132 Turn off the display of the the moving edges and Klt points. \n\
133\n\
134 -d \n\
135 Turn off the display.\n\
136\n\
137 -c\n\
138 Disable the mouse click. Useful to automate the \n\
139 execution of this program without human intervention.\n\
140\n\
141 -o\n\
142 Use Ogre3D for visibility tests\n\
143\n\
144 -w\n\
145 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\
146\n\
147 -l\n\
148 Use the scanline for visibility tests.\n\
149\n\
150 -v\n\
151 Compute covariance matrix.\n\
152\n\
153 -p\n\
154 Compute gradient projection error.\n\
155\n\
156 -T <tracker type>\n\
157 Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (EdgeKlt)>).\n\
158\n\
159 -h \n\
160 Print the help.\n\n", ext.c_str());
161
162 if (badparam)
163 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
164}
165
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)
170{
171 const char *optarg_;
172 int c;
173 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
174
175 switch (c) {
176 case 's':
177 step_by_step = true;
178 break;
179 case 'e':
180 lastFrame = atol(optarg_);
181 break;
182 case 'i':
183 ipath = optarg_;
184 break;
185 case 'x':
186 configFile = optarg_;
187 break;
188 case 'm':
189 modelFile = optarg_;
190 break;
191 case 'n':
192 initFile = optarg_;
193 break;
194 case 't':
195 displayFeatures = false;
196 break;
197 case 'f':
198 cao3DModel = true;
199 break;
200 case 'c':
201 click_allowed = false;
202 break;
203 case 'd':
204 display = false;
205 break;
206 case 'C':
207 trackCylinder = false;
208 break;
209 case 'o':
210 useOgre = true;
211 break;
212 case 'l':
213 useScanline = true;
214 break;
215 case 'w':
216 showOgreConfigDialog = true;
217 break;
218 case 'v':
219 computeCovariance = true;
220 break;
221 case 'p':
222 projectionError = true;
223 break;
224 case 'T':
225 trackerType = atoi(optarg_);
226 break;
227 case 'h':
228 usage(argv[0], nullptr);
229 return false;
230
231 default:
232 usage(argv[0], optarg_);
233 return false;
234 }
235 }
236
237 if ((c == 1) || (c == -1)) {
238 // standalone param or error
239 usage(argv[0], nullptr);
240 std::cerr << "ERROR: " << std::endl;
241 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
242 return false;
243 }
244
245 return true;
246}
247
248int main(int argc, const char **argv)
249{
250 try {
251 std::string env_ipath;
252 std::string opt_ipath;
253 std::string 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;
270 int trackerType = vpMbGenericTracker::EDGE_TRACKER;
271 bool opt_step_by_step = false;
272
273#if defined(VISP_HAVE_DATASET)
274#if VISP_HAVE_DATASET_VERSION >= 0x030600
275 std::string ext("png");
276#else
277 std::string ext("pgm");
278#endif
279#else
280 // We suppose that the user will download a recent dataset
281 std::string ext("png");
282#endif
283
284 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
285 // environment variable value
287
288 // Set the default input path
289 if (!env_ipath.empty())
290 ipath = env_ipath;
291
292 // Read the command line options
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)) {
296 return EXIT_FAILURE;
297 }
298
299 // Test if an input path is set
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
306 << std::endl;
307
308 return EXIT_FAILURE;
309 }
310
311 // Get the option values
312 if (!opt_ipath.empty())
313 ipath = vpIoTools::createFilePath(opt_ipath, "mbt/cube/image%04d." + ext);
314 else
315 ipath = vpIoTools::createFilePath(env_ipath, "mbt/cube/image%04d." + ext);
316
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())
322 configFile = vpIoTools::createFilePath(opt_ipath, "mbt/cube.xml");
323 else
324 configFile = vpIoTools::createFilePath(env_ipath, "mbt/cube.xml");
325#endif
326
327 if (!opt_modelFile.empty()) {
328 modelFile = opt_modelFile;
329 }
330 else {
331 std::string modelFileCao;
332 std::string modelFileWrl;
333 if (trackCylinder) {
334 modelFileCao = "mbt/cube_and_cylinder.cao";
335 modelFileWrl = "mbt/cube_and_cylinder.wrl";
336 }
337 else {
338 modelFileCao = "mbt/cube.cao";
339 modelFileWrl = "mbt/cube.wrl";
340 }
341
342 if (!opt_ipath.empty()) {
343 if (cao3DModel) {
344 modelFile = vpIoTools::createFilePath(opt_ipath, modelFileCao);
345 }
346 else {
347#ifdef VISP_HAVE_COIN3D
348 modelFile = vpIoTools::createFilePath(opt_ipath, modelFileWrl);
349#else
350 std::cerr << "Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
351 modelFile = vpIoTools::createFilePath(opt_ipath, modelFileCao);
352#endif
353 }
354 }
355 else {
356 if (cao3DModel) {
357 modelFile = vpIoTools::createFilePath(env_ipath, modelFileCao);
358 }
359 else {
360#ifdef VISP_HAVE_COIN3D
361 modelFile = vpIoTools::createFilePath(env_ipath, modelFileWrl);
362#else
363 std::cerr << "Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
364 modelFile = vpIoTools::createFilePath(env_ipath, modelFileCao);
365#endif
366 }
367 }
368 }
369
370 if (!opt_initFile.empty())
371 initFile = opt_initFile;
372 else if (!opt_ipath.empty())
373 initFile = vpIoTools::createFilePath(opt_ipath, "mbt/cube");
374 else
375 initFile = vpIoTools::createFilePath(env_ipath, "mbt/cube");
376
377 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
378 vpImage<unsigned char> I1, I2, I3;
379 vpVideoReader reader;
380
381 reader.setFileName(ipath);
382 try {
383 reader.open(I1);
384 I2 = I1;
385 I3 = I1;
386 }
387 catch (...) {
388 std::cerr << "Cannot open sequence: " << ipath << std::endl;
389 return EXIT_FAILURE;
390 }
391
392 if (opt_lastFrame > 1 && opt_lastFrame < reader.getLastFrameIndex())
393 reader.setLastFrameIndex(opt_lastFrame);
394
395 reader.acquire(I1);
396 I2 = I1;
397 I3 = I1;
398
399 mapOfImages["Camera1"] = &I1;
400 mapOfImages["Camera2"] = &I2;
401 mapOfImages["Camera3"] = &I3;
402
403 // initialise a display
404#if defined(VISP_HAVE_X11)
405 vpDisplayX display1, display2, display3;
406#elif defined(VISP_HAVE_GDI)
407 vpDisplayGDI display1, display2, display3;
408#elif defined(HAVE_OPENCV_HIGHGUI)
409 vpDisplayOpenCV display1, display2, display3;
410#elif defined(VISP_HAVE_D3D9)
411 vpDisplayD3D display1, display2, display3;
412#elif defined(VISP_HAVE_GTK)
413 vpDisplayGTK display1, display2, display3;
414#else
415 opt_display = false;
416#endif
417
418 if (opt_display) {
419#if defined(VISP_HAVE_DISPLAY)
423
424 display1.init(I1, 100, 100, "Test tracking (Cam1)");
425 display2.init(I2, static_cast<int>(I1.getWidth() / vpDisplay::getDownScalingFactor(I1)) + 110, 100, "Test tracking (Cam2)");
426 display3.init(I3, 100, static_cast<int>(I1.getHeight() / vpDisplay::getDownScalingFactor(I1)) + 110, "Test tracking (Cam3)");
427#endif
431
435 }
436
437 // Object pointer to check that inheritance is ok
438 vpMbTracker *tracker = new vpMbGenericTracker(3, trackerType);
439 std::map<std::string, vpHomogeneousMatrix> mapOfCameraPoses;
440 std::map<std::string, vpCameraParameters> mapOfCameraParams;
441
442 // Initialise the tracker: camera parameters, moving edge and KLT settings
443#if defined(VISP_HAVE_PUGIXML)
444 // From the xml file
445 std::map<std::string, std::string> mapOfConfigFiles;
446 mapOfConfigFiles["Camera1"] = configFile;
447 mapOfConfigFiles["Camera2"] = configFile;
448 mapOfConfigFiles["Camera3"] = configFile;
449 dynamic_cast<vpMbGenericTracker *>(tracker)->loadConfigFile(mapOfConfigFiles);
450#else
451 // By setting the parameters:
453 cam.initPersProjWithoutDistortion(547, 542, 338, 234);
454 mapOfCameraParams["Camera1"] = cam;
455 mapOfCameraParams["Camera2"] = cam;
456 mapOfCameraParams["Camera3"] = cam;
457
458 vpMe me;
459 me.setMaskSize(5);
460 me.setMaskNumber(180);
461 me.setRange(7);
463 me.setThreshold(10);
464 me.setMu1(0.5);
465 me.setMu2(0.5);
466 me.setSampleStep(4);
467 std::map<std::string, vpMe> mapOfMe;
468 mapOfMe["Camera1"] = me;
469 mapOfMe["Camera2"] = me;
470 mapOfMe["Camera3"] = me;
471
472#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
473 vpKltOpencv klt;
474 klt.setMaxFeatures(10000);
475 klt.setWindowSize(5);
476 klt.setQuality(0.01);
477 klt.setMinDistance(5);
478 klt.setHarrisFreeParameter(0.01);
479 klt.setBlockSize(3);
480 klt.setPyramidLevels(3);
481 std::map<std::string, vpKltOpencv> mapOfKlt;
482 mapOfKlt["Camera1"] = klt;
483 mapOfKlt["Camera2"] = klt;
484 mapOfKlt["Camera3"] = klt;
485
486 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltOpencv(mapOfKlt);
487 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltMaskBorder(5);
488#endif
489
490 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(mapOfCameraParams);
491 dynamic_cast<vpMbGenericTracker *>(tracker)->setMovingEdge(mapOfMe);
492 tracker->setAngleAppear(vpMath::rad(65));
493 tracker->setAngleDisappear(vpMath::rad(75));
494
495 // Specify the clipping to
496 tracker->setNearClippingDistance(0.01);
497 tracker->setFarClippingDistance(0.90);
498
499 std::map<std::string, unsigned int> mapOfClippingFlags;
500 dynamic_cast<vpMbGenericTracker *>(tracker)->getClipping(mapOfClippingFlags);
501 for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin(); it != mapOfClippingFlags.end();
502 ++it) {
503 it->second = (it->second | vpMbtPolygon::FOV_CLIPPING);
504 }
505
506 dynamic_cast<vpMbGenericTracker *>(tracker)->setClipping(mapOfClippingFlags);
507 // tracker->setClipping(tracker->getClipping() | vpMbtPolygon::LEFT_CLIPPING
508 // | vpMbtPolygon::RIGHT_CLIPPING | vpMbtPolygon::UP_CLIPPING |
509 // vpMbtPolygon::DOWN_CLIPPING); // Equivalent to FOV_CLIPPING
510#endif
511
512 // Display the moving edges, and the Klt points
513 tracker->setDisplayFeatures(displayFeatures);
514
515 // Tells if the tracker has to use Ogre3D for visibility tests
516 tracker->setOgreVisibilityTest(useOgre);
517 if (useOgre)
518 tracker->setOgreShowConfigDialog(showOgreConfigDialog);
519
520 // Tells if the tracker has to use the scanline visibility tests
521 tracker->setScanLineVisibilityTest(useScanline);
522
523 // Tells if the tracker has to compute the covariance matrix
524 tracker->setCovarianceComputation(computeCovariance);
525
526 // Tells if the tracker has to compute the projection error
527 tracker->setProjectionErrorComputation(projectionError);
528
529 // Retrieve the camera parameters from the tracker
530 dynamic_cast<vpMbGenericTracker *>(tracker)->getCameraParameters(mapOfCameraParams);
531
532 // Loop to position the cube
533 if (opt_display && opt_click_allowed) {
534 while (!vpDisplay::getClick(I1, false)) {
536 vpDisplay::displayText(I1, 15, 10, "Click after positioning the object", vpColor::red);
538 }
539 }
540
541 // Load the 3D model (either a vrml file or a .cao file)
542 tracker->loadModel(modelFile);
543
544 // Initialise the tracker by clicking on the image
545 // This function looks for
546 // - a ./cube/cube.init file that defines the 3d coordinates (in meter,
547 // in the object basis) of the points used for the initialisation
548 // - a ./cube/cube.ppm file to display where the user have to click
549 // (Optional, set by the third parameter)
550 if (opt_display && opt_click_allowed) {
551 std::map<std::string, std::string> mapOfInitFiles;
552 mapOfInitFiles["Camera1"] = initFile;
553
554 dynamic_cast<vpMbGenericTracker *>(tracker)->initClick(mapOfImages, mapOfInitFiles, true);
555 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(mapOfCameraPoses);
556
557 // display the 3D model at the given pose
558 dynamic_cast<vpMbGenericTracker *>(tracker)->display(mapOfImages, mapOfCameraPoses, mapOfCameraParams,
560 }
561 else {
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;
565
566 dynamic_cast<vpMbGenericTracker *>(tracker)->initFromPose(mapOfImages, mapOfInitPoses);
567 }
568
569 // track the model
570 dynamic_cast<vpMbGenericTracker *>(tracker)->track(mapOfImages);
571 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(mapOfCameraPoses);
572
573 if (opt_display) {
577 }
578
579 bool quit = false;
580 while (!reader.end() && !quit) {
581 // acquire a new image
582 reader.acquire(I1);
583 I2 = I1;
584 I3 = I1;
585 mapOfImages["Camera1"] = &I1;
586 mapOfImages["Camera2"] = &I2;
587 mapOfImages["Camera3"] = &I3;
588
589 // display the image
590 if (opt_display) {
594
595 std::stringstream ss;
596 ss << "Num frame: " << reader.getFrameIndex() << "/" << reader.getLastFrameIndex();
597 vpDisplay::displayText(I1, 40, I1.getWidth() - 150, ss.str(), vpColor::red);
598 }
599
600 // Test to reset the tracker
601 if (reader.getFrameIndex() == reader.getFirstFrameIndex() + 10) {
602 std::cout << "----------Test reset tracker----------" << std::endl;
603 if (opt_display) {
607 }
608
609 tracker->resetTracker();
610#if defined(VISP_HAVE_PUGIXML)
611 dynamic_cast<vpMbGenericTracker *>(tracker)->loadConfigFile(mapOfConfigFiles);
612#else
613 // By setting the parameters:
614 cam.initPersProjWithoutDistortion(547, 542, 338, 234);
615 mapOfCameraParams["Camera1"] = cam;
616 mapOfCameraParams["Camera2"] = cam;
617 mapOfCameraParams["Camera3"] = cam;
618
619 me.setMaskSize(5);
620 me.setMaskNumber(180);
621 me.setRange(7);
623 me.setThreshold(10);
624 me.setMu1(0.5);
625 me.setMu2(0.5);
626 me.setSampleStep(4);
627
628 mapOfMe["Camera1"] = me;
629 mapOfMe["Camera2"] = me;
630 mapOfMe["Camera3"] = me;
631
632#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
633 klt.setMaxFeatures(10000);
634 klt.setWindowSize(5);
635 klt.setQuality(0.01);
636 klt.setMinDistance(5);
637 klt.setHarrisFreeParameter(0.01);
638 klt.setBlockSize(3);
639 klt.setPyramidLevels(3);
640
641 mapOfKlt["Camera1"] = klt;
642 mapOfKlt["Camera2"] = klt;
643 mapOfKlt["Camera3"] = klt;
644
645 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltOpencv(mapOfKlt);
646 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltMaskBorder(5);
647#endif
648
649 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(mapOfCameraParams);
650 dynamic_cast<vpMbGenericTracker *>(tracker)->setMovingEdge(mapOfMe);
651 tracker->setAngleAppear(vpMath::rad(65));
652 tracker->setAngleDisappear(vpMath::rad(75));
653
654 // Specify the clipping to
655 tracker->setNearClippingDistance(0.01);
656 tracker->setFarClippingDistance(0.90);
657
658 dynamic_cast<vpMbGenericTracker *>(tracker)->getClipping(mapOfClippingFlags);
659 for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin();
660 it != mapOfClippingFlags.end(); ++it) {
661 it->second = (it->second | vpMbtPolygon::FOV_CLIPPING);
662 }
663
664 dynamic_cast<vpMbGenericTracker *>(tracker)->setClipping(mapOfClippingFlags);
665 // tracker->setClipping(tracker->getClipping() | vpMbtPolygon::LEFT_CLIPPING
666 // | vpMbtPolygon::RIGHT_CLIPPING | vpMbtPolygon::UP_CLIPPING |
667 // vpMbtPolygon::DOWN_CLIPPING); // Equivalent to FOV_CLIPPING
668#endif
669 tracker->loadModel(modelFile);
670 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(mapOfCameraParams);
671 tracker->setOgreVisibilityTest(useOgre);
672 tracker->setScanLineVisibilityTest(useScanline);
673 tracker->setCovarianceComputation(computeCovariance);
674 tracker->setProjectionErrorComputation(projectionError);
675 dynamic_cast<vpMbGenericTracker *>(tracker)->initFromPose(mapOfImages, mapOfCameraPoses);
676 }
677
678 // Test to set an initial pose
679 if (reader.getFrameIndex() == reader.getFirstFrameIndex() + 50) {
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;
684
685 std::cout << "Test set pose" << std::endl;
686 dynamic_cast<vpMbGenericTracker *>(tracker)->setPose(mapOfImages, mapOfSetPoses);
687 }
688
689 // track the object: stop tracking from frame 40 to 50
690 if (reader.getFrameIndex() - reader.getFirstFrameIndex() < 40 ||
691 reader.getFrameIndex() - reader.getFirstFrameIndex() >= 50) {
692 dynamic_cast<vpMbGenericTracker *>(tracker)->track(mapOfImages);
693 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(mapOfCameraPoses);
694 if (opt_display) {
695 // display the 3D model
696 if (reader.getFrameIndex() - reader.getFirstFrameIndex() >= 50) {
697 std::map<std::string, const vpImage<unsigned char> *> mapOfSubImages;
698 mapOfSubImages["Camera1"] = &I1;
699 mapOfSubImages["Camera2"] = &I2;
700
701 dynamic_cast<vpMbGenericTracker *>(tracker)->display(mapOfSubImages, mapOfCameraPoses, mapOfCameraParams,
702 vpColor::red, 3);
703 }
704 else {
705 dynamic_cast<vpMbGenericTracker *>(tracker)->display(mapOfImages, mapOfCameraPoses, mapOfCameraParams,
706 vpColor::red, 3);
707 }
708 // display the frame
709 vpDisplay::displayFrame(I1, mapOfCameraPoses["Camera1"], mapOfCameraParams["Camera1"], 0.05);
710 vpDisplay::displayFrame(I2, mapOfCameraPoses["Camera2"], mapOfCameraParams["Camera2"], 0.05);
711 vpDisplay::displayFrame(I3, mapOfCameraPoses["Camera3"], mapOfCameraParams["Camera3"], 0.05);
712 }
713 }
714
715 if (opt_click_allowed && opt_display) {
716 vpDisplay::displayText(I1, 20, I1.getWidth() - 150, std::string("Mode: ") + (opt_step_by_step ? std::string("step-by-step") : std::string("continuous")), vpColor::red);
717 vpDisplay::displayText(I1, 20, 10, "Right click to exit", vpColor::red);
718 vpDisplay::displayText(I1, 40, 10, "Middle click to change mode", vpColor::red);
719 if (opt_step_by_step) {
720 vpDisplay::displayText(I1, 60, 10, "Left click to process next image", vpColor::red);
721 }
723 if (vpDisplay::getClick(I1, button, opt_step_by_step)) {
724 if (button == vpMouseButton::button3) {
725 quit = true;
726 }
727 else if (button == vpMouseButton::button2) {
728 opt_step_by_step = !opt_step_by_step;
729 }
730 }
731 }
732
733 if (computeCovariance) {
734 std::cout << "Covariance matrix: \n" << tracker->getCovarianceMatrix() << std::endl << std::endl;
735 }
736
737 if (projectionError) {
738 std::cout << "Projection error: " << tracker->getProjectionError() << std::endl << std::endl;
739 }
740
741 if (opt_display) {
745 }
746 }
747
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;
753
754 if (opt_click_allowed && !quit) {
756 }
757 reader.close();
758
759 delete tracker;
760 tracker = nullptr;
761
762 return EXIT_SUCCESS;
763 }
764 catch (const vpException &e) {
765 std::cout << "Catch an exception: " << e << std::endl;
766 return EXIT_FAILURE;
767 }
768}
769
770#elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY))
771int main()
772{
773 std::cout << "Cannot run this example: visp_mbt, visp_gui modules are required." << std::endl;
774 return EXIT_SUCCESS;
775}
776#else
777int main()
778{
779 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
780 return EXIT_SUCCESS;
781}
782#endif
Generic class defining intrinsic camera parameters.
static const vpColor red
Definition vpColor.h:198
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...
Definition vpDisplayX.h:135
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()
Definition vpDisplay.h:218
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.
Definition vpException.h:60
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.
Definition vpImage.h:131
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:181
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
Definition vpKltOpencv.h:83
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)
Definition vpMath.h:129
Real-time 6D object pose tracking using its CAD model.
Main methods for a model-based tracker.
Definition vpMe.h:143
void setMu1(const double &mu_1)
Definition vpMe.h:408
void setRange(const unsigned int &range)
Definition vpMe.h:438
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
Definition vpMe.h:531
void setMaskNumber(const unsigned int &mask_number)
Definition vpMe.cpp:555
void setThreshold(const double &threshold)
Definition vpMe.h:489
void setSampleStep(const double &sample_step)
Definition vpMe.h:445
void setMaskSize(const unsigned int &mask_size)
Definition vpMe.cpp:563
void setMu2(const double &mu_2)
Definition vpMe.h:415
@ NORMALIZED_THRESHOLD
Definition vpMe.h:154
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)
long getLastFrameIndex()
void open(vpImage< vpRGBa > &I) VP_OVERRIDE
void setFileName(const std::string &filename)
long getFirstFrameIndex()
void close() VP_OVERRIDE
long getFrameIndex() const
void acquire(vpImage< vpRGBa > &I) VP_OVERRIDE