Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
mbtGenericTracking.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/vpDisplayFactory.h>
52#include <visp3/io/vpImageIo.h>
53#include <visp3/io/vpParseArgv.h>
54#include <visp3/io/vpVideoReader.h>
55#include <visp3/mbt/vpMbGenericTracker.h>
56
57#define GETOPTARGS "cCde:fhi:lm:n:opstT:x:vw"
58
59#ifdef ENABLE_VISP_NAMESPACE
60using namespace VISP_NAMESPACE_NAME;
61#endif
62
63void usage(const char *name, const char *badparam)
64{
65#if defined(VISP_HAVE_DATASET)
66#if VISP_HAVE_DATASET_VERSION >= 0x030600
67 std::string ext("png");
68#else
69 std::string ext("pgm");
70#endif
71#else
72 // We suppose that the user will download a recent dataset
73 std::string ext("png");
74#endif
75
76 fprintf(stdout, "\n\
77Example of tracking based on the 3D model.\n\
78\n\
79SYNOPSIS\n\
80 %s [-i <test image path>] [-x <config file>]\n\
81 [-m <model name>] [-n <initialisation file base name>] [-e <last frame index>]\n\
82 [-t] [-c] [-d] [-h] [-f] [-C] [-o] [-w] [-l] [-v] [-p] [-s]\n\
83 [-T <tracker type>]\n", name);
84
85 fprintf(stdout, "\n\
86OPTIONS: \n\
87 -i <input image path> \n\
88 Set image input path.\n\
89 From this path read images \n\
90 \"mbt/cube/image%%04d.%s\". These \n\
91 images come from visp-images-x.y.z.tar.gz available \n\
92 on the ViSP website.\n\
93 Setting the VISP_INPUT_IMAGE_PATH environment\n\
94 variable produces the same behavior than using\n\
95 this option.\n\
96\n\
97 -x <config file> \n\
98 Set the config file (the xml file) to use.\n\
99 The config file is used to specify the parameters of the tracker.\n\
100\n\
101 -m <model name> \n\
102 Specify the name of the file of the model\n\
103 The model can either be a vrml model (.wrl) or a .cao file.\n\
104\n\
105 -e <last frame index> \n\
106 Specify the index of the last frame. Once reached, the tracking is stopped\n\
107\n\
108 -s \n\
109 Enable step-by-step mode when click is allowed.\n\
110\n\
111 -f \n\
112 Do not use the vrml model, use the .cao one. These two models are \n\
113 equivalent and comes from ViSP-images-x.y.z.tar.gz available on the ViSP\n\
114 website. However, the .cao model allows to use the 3d model based tracker \n\
115 without Coin.\n\
116\n\
117 -C \n\
118 Track only the cube (not the cylinder). In this case the models files are\n\
119 cube.cao or cube.wrl instead of cube_and_cylinder.cao and \n\
120 cube_and_cylinder.wrl.\n\
121\n\
122 -n <initialisation file base name> \n\
123 Base name of the initialisation file. The file will be 'base_name'.init .\n\
124 This base name is also used for the optional picture specifying where to \n\
125 click (a .ppm picture).\n\
126\n\
127 -t \n\
128 Turn off the display of the the moving edges and Klt points. \n\
129\n\
130 -d \n\
131 Turn off the display.\n\
132\n\
133 -c\n\
134 Disable the mouse click. Useful to automate the \n\
135 execution of this program without human intervention.\n\
136\n\
137 -o\n\
138 Use Ogre3D for visibility tests\n\
139\n\
140 -w\n\
141 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\
142\n\
143 -l\n\
144 Use the scanline for visibility tests.\n\
145\n\
146 -v\n\
147 Compute covariance matrix.\n\
148\n\
149 -p\n\
150 Compute gradient projection error.\n\
151\n\
152 -T <tracker type>\n\
153 Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (EdgeKlt)>).\n\
154\n\
155 -h \n\
156 Print the help.\n\n", ext.c_str());
157
158 if (badparam)
159 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
160}
161
162bool getOptions(int argc, const char **argv, std::string &ipath, std::string &configFile, std::string &modelFile,
163 std::string &initFile, long &lastFrame, bool &displayFeatures, bool &click_allowed, bool &display,
164 bool &cao3DModel, bool &trackCylinder, bool &useOgre, bool &showOgreConfigDialog, bool &useScanline,
165 bool &computeCovariance, bool &projectionError, int &trackerType, bool &step_by_step)
166{
167 const char *optarg_;
168 int c;
169 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
170
171 switch (c) {
172 case 's':
173 step_by_step = true;
174 break;
175 case 'e':
176 lastFrame = atol(optarg_);
177 break;
178 case 'i':
179 ipath = optarg_;
180 break;
181 case 'x':
182 configFile = optarg_;
183 break;
184 case 'm':
185 modelFile = optarg_;
186 break;
187 case 'n':
188 initFile = optarg_;
189 break;
190 case 't':
191 displayFeatures = false;
192 break;
193 case 'f':
194 cao3DModel = true;
195 break;
196 case 'c':
197 click_allowed = false;
198 break;
199 case 'd':
200 display = false;
201 break;
202 case 'C':
203 trackCylinder = false;
204 break;
205 case 'o':
206 useOgre = true;
207 break;
208 case 'l':
209 useScanline = true;
210 break;
211 case 'w':
212 showOgreConfigDialog = true;
213 break;
214 case 'v':
215 computeCovariance = true;
216 break;
217 case 'p':
218 projectionError = true;
219 break;
220 case 'T':
221 trackerType = atoi(optarg_);
222 break;
223 case 'h':
224 usage(argv[0], nullptr);
225 return false;
226
227 default:
228 usage(argv[0], optarg_);
229 return false;
230 }
231 }
232
233 if ((c == 1) || (c == -1)) {
234 // standalone param or error
235 usage(argv[0], nullptr);
236 std::cerr << "ERROR: " << std::endl;
237 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
238 return false;
239 }
240
241 return true;
242}
243
244int main(int argc, const char **argv)
245{
246 try {
247 std::string env_ipath;
248 std::string opt_ipath;
249 std::string ipath;
250 std::string opt_configFile;
251 std::string opt_modelFile;
252 std::string modelFile;
253 std::string opt_initFile;
254 std::string initFile;
255 long opt_lastFrame = -1;
256 bool displayFeatures = true;
257 bool opt_click_allowed = true;
258 bool opt_display = true;
259 bool cao3DModel = false;
260 bool trackCylinder = true;
261 bool useOgre = false;
262 bool showOgreConfigDialog = false;
263 bool useScanline = false;
264 bool computeCovariance = false;
265 bool projectionError = false;
266 int trackerType = vpMbGenericTracker::EDGE_TRACKER;
267 bool opt_step_by_step = false;
268
269#if defined(VISP_HAVE_DATASET)
270#if VISP_HAVE_DATASET_VERSION >= 0x030600
271 std::string ext("png");
272#else
273 std::string ext("pgm");
274#endif
275#else
276 // We suppose that the user will download a recent dataset
277 std::string ext("png");
278#endif
279
280 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
281 // environment variable value
283
284 // Set the default input path
285 if (!env_ipath.empty())
286 ipath = env_ipath;
287
288 // Read the command line options
289 if (!getOptions(argc, argv, opt_ipath, opt_configFile, opt_modelFile, opt_initFile, opt_lastFrame, displayFeatures,
290 opt_click_allowed, opt_display, cao3DModel, trackCylinder, useOgre, showOgreConfigDialog,
291 useScanline, computeCovariance, projectionError, trackerType, opt_step_by_step)) {
292 return EXIT_FAILURE;
293 }
294
295 // Test if an input path is set
296 if (opt_ipath.empty() && env_ipath.empty()) {
297 usage(argv[0], nullptr);
298 std::cerr << std::endl << "ERROR:" << std::endl;
299 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
300 << " environment variable to specify the location of the " << std::endl
301 << " image path where test images are located." << std::endl
302 << std::endl;
303
304 return EXIT_FAILURE;
305 }
306
307 // Get the option values
308 if (!opt_ipath.empty())
309 ipath = vpIoTools::createFilePath(opt_ipath, "mbt/cube/image%04d." + ext);
310 else
311 ipath = vpIoTools::createFilePath(env_ipath, "mbt/cube/image%04d." + ext);
312
313#if defined(VISP_HAVE_PUGIXML)
314 std::string configFile;
315 if (!opt_configFile.empty())
316 configFile = opt_configFile;
317 else if (!opt_ipath.empty())
318 configFile = vpIoTools::createFilePath(opt_ipath, "mbt/cube.xml");
319 else
320 configFile = vpIoTools::createFilePath(env_ipath, "mbt/cube.xml");
321#endif
322
323 if (!opt_modelFile.empty()) {
324 modelFile = opt_modelFile;
325 }
326 else {
327 std::string modelFileCao;
328 std::string modelFileWrl;
329 if (trackCylinder) {
330 modelFileCao = "mbt/cube_and_cylinder.cao";
331 modelFileWrl = "mbt/cube_and_cylinder.wrl";
332 }
333 else {
334 modelFileCao = "mbt/cube.cao";
335 modelFileWrl = "mbt/cube.wrl";
336 }
337
338 if (!opt_ipath.empty()) {
339 if (cao3DModel) {
340 modelFile = vpIoTools::createFilePath(opt_ipath, modelFileCao);
341 }
342 else {
343#ifdef VISP_HAVE_COIN3D
344 modelFile = vpIoTools::createFilePath(opt_ipath, modelFileWrl);
345#else
346 std::cerr << "Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
347 modelFile = vpIoTools::createFilePath(opt_ipath, modelFileCao);
348#endif
349 }
350 }
351 else {
352 if (cao3DModel) {
353 modelFile = vpIoTools::createFilePath(env_ipath, modelFileCao);
354 }
355 else {
356#ifdef VISP_HAVE_COIN3D
357 modelFile = vpIoTools::createFilePath(env_ipath, modelFileWrl);
358#else
359 std::cerr << "Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
360 modelFile = vpIoTools::createFilePath(env_ipath, modelFileCao);
361#endif
362 }
363 }
364 }
365
366 if (!opt_initFile.empty())
367 initFile = opt_initFile;
368 else if (!opt_ipath.empty())
369 initFile = vpIoTools::createFilePath(opt_ipath, "mbt/cube");
370 else
371 initFile = vpIoTools::createFilePath(env_ipath, "mbt/cube");
372
374 vpDisplay *display1 = nullptr, *display2 = nullptr;
375 vpVideoReader reader;
376
377 reader.setFileName(ipath);
378 try {
379 reader.open(I1);
380 I2 = I1;
381 }
382 catch (...) {
383 std::cerr << "Cannot open sequence: " << ipath << std::endl;
384 return EXIT_FAILURE;
385 }
386
387 if (opt_lastFrame > 1 && opt_lastFrame < reader.getLastFrameIndex())
388 reader.setLastFrameIndex(opt_lastFrame);
389
390 reader.acquire(I1);
391 I2 = I1;
392
393 if (opt_display) {
394 // We open a window using either X11, GTK, OpenCV or GDI
398 display2->setDownScalingFactor(vpDisplay::SCALE_AUTO);
399 display1->init(I1, 100, 100, "Test tracking (Left)");
400 display2->init(I2, static_cast<int>(I1.getWidth() / vpDisplay::getDownScalingFactor(I1)) + 110, 100, "Test tracking (Right)");
401
406 }
407
408 // Object pointer to check that inheritance is ok
409 vpMbTracker *tracker = new vpMbGenericTracker(2, trackerType);
410 vpHomogeneousMatrix c1Mo, c2Mo;
411 vpCameraParameters cam1, cam2;
412
413 // Initialise the tracker: camera parameters, moving edge and KLT settings
414#if defined(VISP_HAVE_PUGIXML)
415 // From the xml file
416 dynamic_cast<vpMbGenericTracker *>(tracker)->loadConfigFile(configFile, configFile);
417#else
418 // By setting the parameters:
419 cam1.initPersProjWithoutDistortion(547, 542, 338, 234);
420 cam2.initPersProjWithoutDistortion(547, 542, 338, 234);
421
422 vpMe me;
423 me.setMaskSize(5);
424 me.setMaskNumber(180);
425 me.setRange(7);
427 me.setThreshold(10);
428 me.setMu1(0.5);
429 me.setMu2(0.5);
430 me.setSampleStep(4);
431
432#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
433 vpKltOpencv klt;
434 klt.setMaxFeatures(10000);
435 klt.setWindowSize(5);
436 klt.setQuality(0.01);
437 klt.setMinDistance(5);
438 klt.setHarrisFreeParameter(0.01);
439 klt.setBlockSize(3);
440 klt.setPyramidLevels(3);
441
442 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltOpencv(klt);
443 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltMaskBorder(5);
444#endif
445
446 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(cam1, cam2);
447 dynamic_cast<vpMbGenericTracker *>(tracker)->setMovingEdge(me);
448
449 tracker->setAngleAppear(vpMath::rad(65));
450 tracker->setAngleDisappear(vpMath::rad(75));
451
452 // Specify the clipping to
453 tracker->setNearClippingDistance(0.01);
454 tracker->setFarClippingDistance(0.90);
455 tracker->setClipping(tracker->getClipping() | vpMbtPolygon::FOV_CLIPPING);
456 // tracker->setClipping(tracker->getClipping() | vpMbtPolygon::LEFT_CLIPPING
457 // | vpMbtPolygon::RIGHT_CLIPPING | vpMbtPolygon::UP_CLIPPING |
458 // vpMbtPolygon::DOWN_CLIPPING); // Equivalent to FOV_CLIPPING
459#endif
460
461 // Display the moving edges, and the Klt points
462 tracker->setDisplayFeatures(displayFeatures);
463
464 // Tells if the tracker has to use Ogre3D for visibility tests
465 tracker->setOgreVisibilityTest(useOgre);
466 if (useOgre)
467 tracker->setOgreShowConfigDialog(showOgreConfigDialog);
468
469 // Tells if the tracker has to use the scanline visibility tests
470 tracker->setScanLineVisibilityTest(useScanline);
471
472 // Tells if the tracker has to compute the covariance matrix
473 tracker->setCovarianceComputation(computeCovariance);
474
475 // Tells if the tracker has to compute the projection error
476 tracker->setProjectionErrorComputation(projectionError);
477
478 // Retrieve the camera parameters from the tracker
479 dynamic_cast<vpMbGenericTracker *>(tracker)->getCameraParameters(cam1, cam2);
480
481 // Loop to position the cube
482 if (opt_display && opt_click_allowed) {
483 while (!vpDisplay::getClick(I1, false)) {
485 vpDisplay::displayText(I1, 15, 10, "Click after positioning the object", vpColor::red);
487 }
488 }
489
490 // Load the 3D model (either a vrml file or a .cao file)
491 tracker->loadModel(modelFile);
492
493 // Initialise the tracker by clicking on the image
494 // This function looks for
495 // - a ./cube/cube.init file that defines the 3d coordinates (in meter,
496 // in the object basis) of the points used for the initialisation
497 // - a ./cube/cube.ppm file to display where the user have to click
498 // (Optional, set by the third parameter)
499 if (opt_display && opt_click_allowed) {
500 dynamic_cast<vpMbGenericTracker *>(tracker)->initClick(I1, I2, initFile, initFile, true);
501 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(c1Mo, c2Mo);
502 // display the 3D model at the given pose
503 dynamic_cast<vpMbGenericTracker *>(tracker)->display(I1, I2, c1Mo, c2Mo, cam1, cam2, vpColor::red);
504 }
505 else {
506 vpHomogeneousMatrix c1Moi(0.02044769891, 0.1101505452, 0.5078963719, 2.063603907, 1.110231561, -0.4392789872);
507 vpHomogeneousMatrix c2Moi(0.02044769891, 0.1101505452, 0.5078963719, 2.063603907, 1.110231561, -0.4392789872);
508 dynamic_cast<vpMbGenericTracker *>(tracker)->initFromPose(I1, I2, c1Moi, c2Moi);
509 }
510
511 // track the model
512 dynamic_cast<vpMbGenericTracker *>(tracker)->track(I1, I2);
513 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(c1Mo, c2Mo);
514
515 if (opt_display) {
518 }
519
520 bool quit = false;
521 while (!reader.end() && !quit) {
522 // acquire a new image
523 reader.acquire(I1);
524 I2 = I1;
525 // display the image
526 if (opt_display) {
529
530 std::stringstream ss;
531 ss << "Num frame: " << reader.getFrameIndex() << "/" << reader.getLastFrameIndex();
532 vpDisplay::displayText(I1, 40, I1.getWidth() - 150, ss.str(), vpColor::red);
533 }
534
535 // Test to reset the tracker
536 if (reader.getFrameIndex() == reader.getFirstFrameIndex() + 10) {
537 std::cout << "----------Test reset tracker----------" << std::endl;
538 if (opt_display) {
541 }
542
543 tracker->resetTracker();
544#if defined(VISP_HAVE_PUGIXML)
545 dynamic_cast<vpMbGenericTracker *>(tracker)->loadConfigFile(configFile, configFile);
546#else
547 // By setting the parameters:
548 cam1.initPersProjWithoutDistortion(547, 542, 338, 234);
549 cam2.initPersProjWithoutDistortion(547, 542, 338, 234);
550
551 me.setMaskSize(5);
552 me.setMaskNumber(180);
553 me.setRange(7);
555 me.setThreshold(10);
556 me.setMu1(0.5);
557 me.setMu2(0.5);
558 me.setSampleStep(4);
559
560#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
561 klt.setMaxFeatures(10000);
562 klt.setWindowSize(5);
563 klt.setQuality(0.01);
564 klt.setMinDistance(5);
565 klt.setHarrisFreeParameter(0.01);
566 klt.setBlockSize(3);
567 klt.setPyramidLevels(3);
568
569 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltOpencv(klt);
570 dynamic_cast<vpMbGenericTracker *>(tracker)->setKltMaskBorder(5);
571#endif
572
573 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(cam1, cam2);
574 dynamic_cast<vpMbGenericTracker *>(tracker)->setMovingEdge(me);
575 tracker->setAngleAppear(vpMath::rad(65));
576 tracker->setAngleDisappear(vpMath::rad(75));
577
578 // Specify the clipping to
579 tracker->setNearClippingDistance(0.01);
580 tracker->setFarClippingDistance(0.90);
581 tracker->setClipping(tracker->getClipping() | vpMbtPolygon::FOV_CLIPPING);
582 // tracker->setClipping(tracker->getClipping() | vpMbtPolygon::LEFT_CLIPPING
583 // | vpMbtPolygon::RIGHT_CLIPPING | vpMbtPolygon::UP_CLIPPING |
584 // vpMbtPolygon::DOWN_CLIPPING); // Equivalent to FOV_CLIPPING
585#endif
586 tracker->loadModel(modelFile);
587 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(cam1, cam2);
588 tracker->setOgreVisibilityTest(useOgre);
589 tracker->setScanLineVisibilityTest(useScanline);
590 tracker->setCovarianceComputation(computeCovariance);
591 tracker->setProjectionErrorComputation(projectionError);
592 dynamic_cast<vpMbGenericTracker *>(tracker)->initFromPose(I1, I2, c1Mo, c2Mo);
593 }
594
595 // Test to set an initial pose
596 if (reader.getFrameIndex() == reader.getFirstFrameIndex() + 50) {
597 c1Mo.buildFrom(0.0439540832, 0.0845870108, 0.5477322481, 2.179498458, 0.8611798108, -0.3491961946);
598 c2Mo.buildFrom(0.0439540832, 0.0845870108, 0.5477322481, 2.179498458, 0.8611798108, -0.3491961946);
599 std::cout << "Test set pose" << std::endl;
600 dynamic_cast<vpMbGenericTracker *>(tracker)->setPose(I1, I2, c1Mo, c2Mo);
601 }
602
603 // track the object: stop tracking from frame 40 to 50
604 if (reader.getFrameIndex() - reader.getFirstFrameIndex() < 40 ||
605 reader.getFrameIndex() - reader.getFirstFrameIndex() >= 50) {
606 dynamic_cast<vpMbGenericTracker *>(tracker)->track(I1, I2);
607 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(c1Mo, c2Mo);
608 if (opt_display) {
609 // display the 3D model
610 dynamic_cast<vpMbGenericTracker *>(tracker)->display(I1, I2, c1Mo, c2Mo, cam1, cam2, vpColor::darkRed);
611 // display the frame
612 vpDisplay::displayFrame(I1, c1Mo, cam1, 0.05);
613 vpDisplay::displayFrame(I2, c2Mo, cam2, 0.05);
614 }
615 }
616
617 if (opt_click_allowed && opt_display) {
618 vpDisplay::displayText(I1, 20, I1.getWidth() - 150, std::string("Mode: ") + (opt_step_by_step ? std::string("step-by-step") : std::string("continuous")), vpColor::red);
619 vpDisplay::displayText(I1, 20, 10, "Right click to exit", vpColor::red);
620 vpDisplay::displayText(I1, 40, 10, "Middle click to change mode", vpColor::red);
621 if (opt_step_by_step) {
622 vpDisplay::displayText(I1, 60, 10, "Left click to process next image", vpColor::red);
623 }
625 if (vpDisplay::getClick(I1, button, opt_step_by_step)) {
626 if (button == vpMouseButton::button3) {
627 quit = true;
628 }
629 else if (button == vpMouseButton::button2) {
630 opt_step_by_step = !opt_step_by_step;
631 }
632 }
633 }
634
635 if (computeCovariance) {
636 std::cout << "Covariance matrix: \n" << tracker->getCovarianceMatrix() << std::endl << std::endl;
637 }
638
639 if (projectionError) {
640 std::cout << "Projection error: " << tracker->getProjectionError() << std::endl << std::endl;
641 }
642
643 if (opt_display) {
646 }
647 }
648
649 std::cout << "Reached last frame: " << reader.getFrameIndex() << std::endl;
650 std::cout << "\nFinal poses, c1Mo:\n" << c1Mo << "\nc2Mo:\n" << c2Mo << std::endl;
651
652 if (opt_click_allowed && !quit) {
654 }
655 reader.close();
656
657 delete tracker;
658 tracker = nullptr;
659
660 if (display1) {
661 delete display1;
662 }
663 if (display2) {
664 delete display2;
665 }
666 return EXIT_SUCCESS;
667 }
668 catch (const vpException &e) {
669 std::cout << "Catch an exception: " << e << std::endl;
670 return EXIT_FAILURE;
671 }
672}
673
674#elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY))
675int main()
676{
677 std::cout << "Cannot run this example: visp_mbt, visp_gui modules are required." << std::endl;
678 return EXIT_SUCCESS;
679}
680#else
681int main()
682{
683 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
684 return EXIT_SUCCESS;
685}
686#endif
Generic class defining intrinsic camera parameters.
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
static const vpColor red
Definition vpColor.h:198
static const vpColor darkRed
Definition vpColor.h:199
Class that defines generic functionalities for display.
Definition vpDisplay.h:171
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
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
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.