Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
mbtGenericTrackingDepthOnly.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 tracking with vpGenericTracker on Castel.
32 */
33
39
40#include <cstdlib>
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 "X:M:i:n:dchfolwvpT:e:u:"
62
63#define USE_SMALL_DATASET 1 // small depth dataset in ViSP-images
64
65#ifdef ENABLE_VISP_NAMESPACE
66using namespace VISP_NAMESPACE_NAME;
67#endif
68
69namespace
70{
71void usage(const char *name, const char *badparam)
72{
73 fprintf(stdout, "\n\
74 Example of tracking with vpGenericTracker.\n\
75 \n\
76 SYNOPSIS\n\
77 %s [-i <test image path>] [-X <config file depth>]\n\
78 [-M <model name depth>] [-n <initialisation file base name>]\n\
79 [-f] [-c] [-d] [-h] [-o] [-w] [-l] [-v] [-p]\n\
80 [-T <tracker type>] [-e <last frame index>]\n\
81 [-u <disable face>]\n",
82 name);
83
84 fprintf(stdout, "\n\
85 OPTIONS: \n\
86 -i <input image path> \n\
87 Set image input path.\n\
88 These images come from ViSP-images-x.y.z.tar.gz available \n\
89 on the ViSP website.\n\
90 Setting the VISP_INPUT_IMAGE_PATH environment\n\
91 variable produces the same behavior than using\n\
92 this option.\n\
93 \n\
94 -X <config file> \n\
95 Set the config file (the xml file) to use for the depth sensor.\n\
96 The config file is used to specify the parameters of the tracker.\n\
97 \n\
98 -M <model name> \n\
99 Specify the name of the file of the model for the depth sensor.\n\
100 The model can either be a vrml model (.wrl) or a .cao file.\n\
101 \n\
102 -n <initialisation file base name> \n\
103 Base name of the initialisation file. The file will be 'base_name'.init .\n\
104 This base name is also used for the optional picture specifying where to \n\
105 click (a .ppm picture).\n\
106 \n\
107 -f \n\
108 Turn off the display of the visual features. \n\
109 \n\
110 -d \n\
111 Turn off the display.\n\
112 \n\
113 -c\n\
114 Disable the mouse click. Useful to automate the \n\
115 execution of this program without human intervention.\n\
116 \n\
117 -o\n\
118 Use Ogre3D for visibility tests\n\
119 \n\
120 -w\n\
121 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\
122 \n\
123 -l\n\
124 Use the scanline for visibility tests.\n\
125 \n\
126 -v\n\
127 Compute covariance matrix.\n\
128 \n\
129 -p\n\
130 Compute gradient projection error.\n\
131 \n\
132 -T <tracker type>\n\
133 Set tracker type (<4 (Depth normal)>, <8 (Depth dense)>, <12 (both)>) for depth sensor.\n\
134 \n\
135 -e <last frame index>\n\
136 Specify the index of the last frame. Once reached, the tracking is stopped.\n\
137 \n\
138 -u <disable>\n\
139 Disable castle element (1=floor, 2=front_door, 4=slope, 8=tower_front, 16=tower_left, 32=tower_right, 64=tower_back).\n\
140 \n\
141 -h \n\
142 Print the help.\n\n");
143
144 if (badparam)
145 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
146}
147
148bool getOptions(int argc, const char **argv, std::string &ipath, std::string &configFile_depth,
149 std::string &modelFile_depth, std::string &initFile, bool &displayFeatures, bool &click_allowed,
150 bool &display, bool &useOgre, bool &showOgreConfigDialog, bool &useScanline, bool &computeCovariance,
151 bool &projectionError, int &tracker_type_depth, int &lastFrame, int &disable_castle_faces)
152{
153 const char *optarg_;
154 int c;
155 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
156
157 switch (c) {
158 case 'i':
159 ipath = optarg_;
160 break;
161 case 'X':
162 configFile_depth = optarg_;
163 break;
164 case 'M':
165 modelFile_depth = optarg_;
166 break;
167 case 'n':
168 initFile = optarg_;
169 break;
170 case 'f':
171 displayFeatures = false;
172 break;
173 case 'c':
174 click_allowed = false;
175 break;
176 case 'd':
177 display = false;
178 break;
179 case 'o':
180 useOgre = true;
181 break;
182 case 'l':
183 useScanline = true;
184 break;
185 case 'w':
186 showOgreConfigDialog = true;
187 break;
188 case 'v':
189 computeCovariance = true;
190 break;
191 case 'p':
192 projectionError = true;
193 break;
194 case 'T':
195 tracker_type_depth = atoi(optarg_);
196 break;
197 case 'e':
198 lastFrame = atoi(optarg_);
199 break;
200 case 'u':
201 disable_castle_faces = atoi(optarg_);
202 break;
203
204 case 'h':
205 usage(argv[0], nullptr);
206 return false;
207 default:
208 usage(argv[0], optarg_);
209 return false;
210 }
211 }
212
213 if ((c == 1) || (c == -1)) {
214 // standalone param or error
215 usage(argv[0], nullptr);
216 std::cerr << "ERROR: " << std::endl;
217 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
218 return false;
219 }
220
221 return true;
222}
223
224struct vpRealsenseIntrinsics_t
225{
226 float ppx;
228 float ppy;
230 float fx;
232 float fy;
234 float coeffs[5];
235};
236
237void rs_deproject_pixel_to_point(float point[3], const vpRealsenseIntrinsics_t &intrin, const float pixel[2], float depth)
238{
239 float x = (pixel[0] - intrin.ppx) / intrin.fx;
240 float y = (pixel[1] - intrin.ppy) / intrin.fy;
241
242 float r2 = x * x + y * y;
243 float f = 1 + intrin.coeffs[0] * r2 + intrin.coeffs[1] * r2 * r2 + intrin.coeffs[4] * r2 * r2 * r2;
244 float ux = x * f + 2 * intrin.coeffs[2] * x * y + intrin.coeffs[3] * (r2 + 2 * x * x);
245 float uy = y * f + 2 * intrin.coeffs[3] * x * y + intrin.coeffs[2] * (r2 + 2 * y * y);
246
247 x = ux;
248 y = uy;
249
250 point[0] = depth * x;
251 point[1] = depth * y;
252 point[2] = depth;
253}
254
255bool read_data(unsigned int cpt, const std::string &input_directory, vpImage<unsigned char> &I,
256 vpImage<uint16_t> &I_depth_raw, std::vector<vpColVector> &pointcloud, unsigned int &pointcloud_width,
257 unsigned int &pointcloud_height)
258{
259#if defined(VISP_HAVE_DATASET)
260#if VISP_HAVE_DATASET_VERSION >= 0x030600
261 std::string ext("png");
262#else
263 std::string ext("pgm");
264#endif
265#else
266 // We suppose that the user will download a recent dataset
267 std::string ext("png");
268#endif
269 // Read image
270 std::string filename_image = vpIoTools::formatString(input_directory + "/image_%04d." + ext, cpt);
271
272 if (!vpIoTools::checkFilename(filename_image)) {
273 std::cerr << "Cannot read: " << filename_image << std::endl;
274 return false;
275 }
276 vpImageIo::read(I, filename_image);
277
278 // Read raw depth
279 std::string filename_depth = vpIoTools::formatString(input_directory + "/depth_image_%04d.bin", cpt);
280
281 std::ifstream file_depth(filename_depth.c_str(), std::ios::in | std::ios::binary);
282 if (!file_depth.is_open()) {
283 return false;
284 }
285
286 unsigned int height = 0, width = 0;
287 vpIoTools::readBinaryValueLE(file_depth, height);
288 vpIoTools::readBinaryValueLE(file_depth, width);
289
290 I_depth_raw.resize(height, width);
291
292 uint16_t depth_value = 0;
293 for (unsigned int i = 0; i < height; i++) {
294 for (unsigned int j = 0; j < width; j++) {
295 vpIoTools::readBinaryValueLE(file_depth, depth_value);
296 I_depth_raw[i][j] = depth_value;
297 }
298 }
299
300 // Transform pointcloud
301 pointcloud_width = width;
302 pointcloud_height = height;
303 pointcloud.resize(static_cast<size_t>(width * height));
304
305 // Only for Creative SR300
306 const float depth_scale = 0.000124986647f;
307 vpRealsenseIntrinsics_t depth_intrinsic;
308 depth_intrinsic.ppx = 311.484558f;
309 depth_intrinsic.ppy = 246.283234f;
310 depth_intrinsic.fx = 476.053619f;
311 depth_intrinsic.fy = 476.053497f;
312 depth_intrinsic.coeffs[0] = 0.165056542f;
313 depth_intrinsic.coeffs[1] = -0.0508309528f;
314 depth_intrinsic.coeffs[2] = 0.00435937941f;
315 depth_intrinsic.coeffs[3] = 0.00541406544f;
316 depth_intrinsic.coeffs[4] = 0.250085592f;
317
318 for (unsigned int i = 0; i < height; i++) {
319 for (unsigned int j = 0; j < width; j++) {
320 float scaled_depth = I_depth_raw[i][j] * depth_scale;
321 float point[3];
322 float pixel[2] = { static_cast<float>(j), static_cast<float>(i) };
323 rs_deproject_pixel_to_point(point, depth_intrinsic, pixel, scaled_depth);
324
325 vpColVector data_3D(3);
326 data_3D[0] = point[0];
327 data_3D[1] = point[1];
328 data_3D[2] = point[2];
329
330 pointcloud[static_cast<size_t>(i * width + j)] = data_3D;
331 }
332 }
333
334 return true;
335}
336
337void loadConfiguration(vpMbTracker *const tracker, const std::string &
338#if defined(VISP_HAVE_PUGIXML)
339 configFile_depth
340#endif
341)
342{
343#if defined(VISP_HAVE_PUGIXML)
344 // From the xml file
345 dynamic_cast<vpMbGenericTracker *>(tracker)->loadConfigFile(configFile_depth);
346#else
347 // Depth
348 dynamic_cast<vpMbGenericTracker *>(tracker)->setDepthNormalFeatureEstimationMethod(
350 dynamic_cast<vpMbGenericTracker *>(tracker)->setDepthNormalPclPlaneEstimationMethod(2);
351 dynamic_cast<vpMbGenericTracker *>(tracker)->setDepthNormalPclPlaneEstimationRansacMaxIter(200);
352 dynamic_cast<vpMbGenericTracker *>(tracker)->setDepthNormalPclPlaneEstimationRansacThreshold(0.001);
353 dynamic_cast<vpMbGenericTracker *>(tracker)->setDepthNormalSamplingStep(2, 2);
354
355 dynamic_cast<vpMbGenericTracker *>(tracker)->setDepthDenseSamplingStep(4, 4);
356
358 cam.initPersProjWithoutDistortion(476.0536193848, 476.0534973145, 311.4845581055, 246.2832336426);
359
360 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(cam);
361
362 tracker->setAngleAppear(vpMath::rad(70));
363 tracker->setAngleDisappear(vpMath::rad(80));
364
365 // Specify the clipping to
366 tracker->setNearClippingDistance(0.01);
367 tracker->setFarClippingDistance(2.0);
368 tracker->setClipping(tracker->getClipping() | vpMbtPolygon::FOV_CLIPPING);
369// tracker->setClipping(tracker->getClipping() | vpMbtPolygon::LEFT_CLIPPING
370// | vpMbtPolygon::RIGHT_CLIPPING | vpMbtPolygon::UP_CLIPPING |
371// vpMbtPolygon::DOWN_CLIPPING); // Equivalent to FOV_CLIPPING
372#endif
373}
374
375std::vector<std::string> getCastleElementNames(const int element)
376{
377 std::vector<std::string> element_names;
378
379 if (element & 0x1)
380 element_names.push_back("floor");
381 if (element & 0x2)
382 element_names.push_back("front_door");
383 if (element & 0x4)
384 element_names.push_back("slope");
385 if (element & 0x8)
386 element_names.push_back("tower_front");
387 if (element & 0x10)
388 element_names.push_back("tower_left");
389 if (element & 0x20)
390 element_names.push_back("tower_right");
391 if (element & 0x40)
392 element_names.push_back("tower_back");
393
394 return element_names;
395}
396} // namespace
397
398int main(int argc, const char **argv)
399{
400 try {
401 std::string env_ipath;
402 std::string opt_ipath;
403 std::string ipath;
404 std::string opt_configFile_depth;
405 std::string opt_modelFile_depth;
406 std::string opt_initFile;
407 std::string initFile;
408 bool displayFeatures = true;
409 bool opt_click_allowed = true;
410 bool opt_display = true;
411 bool useOgre = false;
412 bool showOgreConfigDialog = false;
413 bool useScanline = false;
414 bool computeCovariance = false;
415 bool projectionError = false;
416 int trackerType_depth = vpMbGenericTracker::DEPTH_DENSE_TRACKER;
417#if defined(__mips__) || defined(__mips) || defined(mips) || defined(__MIPS__)
418 // To avoid Debian test timeout
419 int opt_lastFrame = 5;
420#else
421 int opt_lastFrame = -1;
422#endif
423 int disable_castle_faces = 0;
424
425 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
426 // environment variable value
428
429 // Set the default input path
430 if (!env_ipath.empty())
431 ipath = env_ipath;
432
433 // Read the command line options
434 if (!getOptions(argc, argv, opt_ipath, opt_configFile_depth, opt_modelFile_depth, opt_initFile, displayFeatures,
435 opt_click_allowed, opt_display, useOgre, showOgreConfigDialog, useScanline, computeCovariance,
436 projectionError, trackerType_depth, opt_lastFrame, disable_castle_faces)) {
437 return EXIT_FAILURE;
438 }
439
440 // Test if an input path is set
441 if (opt_ipath.empty() && env_ipath.empty()) {
442 usage(argv[0], nullptr);
443 std::cerr << std::endl << "ERROR:" << std::endl;
444 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
445 << " environment variable to specify the location of the " << std::endl
446 << " image path where test images are located." << std::endl
447 << std::endl;
448
449 return EXIT_FAILURE;
450 }
451
452 // Get the option values
453 ipath = vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath, "mbt-depth/castel/castel");
454
455 std::string dir_path = vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath, "mbt-depth");
456 if (!vpIoTools::checkDirectory(dir_path)) {
457 std::cerr << "ViSP-images does not contain the folder: " << dir_path << "!" << std::endl;
458 return EXIT_SUCCESS;
459 }
460
461 std::string configFile_depth;
462 if (!opt_configFile_depth.empty())
463 configFile_depth = opt_configFile_depth;
464 else
465 configFile_depth =
466 vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath, "mbt-depth/castel/chateau_depth.xml");
467
468 std::string modelFile_depth;
469 if (!opt_modelFile_depth.empty())
470 modelFile_depth = opt_modelFile_depth;
471 else
472 modelFile_depth =
473 vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath, "mbt-depth/castel/chateau.cao");
474
475 std::string vrml_ext = ".wrl";
476 bool use_vrml =
477 (modelFile_depth.compare(modelFile_depth.length() - vrml_ext.length(), vrml_ext.length(), vrml_ext) == 0);
478
479 if (use_vrml) {
480#if defined(VISP_HAVE_COIN3D) && (COIN_MAJOR_VERSION == 2 || COIN_MAJOR_VERSION == 3 || COIN_MAJOR_VERSION == 4)
481 std::cout << "use_vrml: " << use_vrml << std::endl;
482#else
483 std::cerr << "Error: vrml model file is only supported if ViSP is "
484 "build with Coin3D 3rd party"
485 << std::endl;
486 return EXIT_FAILURE;
487#endif
488 }
489
490 if (!opt_initFile.empty())
491 initFile = opt_initFile;
492 else
493 initFile = vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath, "mbt-depth/castel/chateau.init");
494
496 vpImage<uint16_t> I_depth_raw;
497 std::vector<vpColVector> pointcloud;
498 unsigned int pointcloud_width, pointcloud_height;
499 if (!read_data(0, ipath, I, I_depth_raw, pointcloud, pointcloud_width, pointcloud_height)) {
500 std::cerr << "Cannot open sequence: " << ipath << std::endl;
501 return EXIT_FAILURE;
502 }
503
504 vpImageConvert::createDepthHistogram(I_depth_raw, I_depth);
505
506// initialise a display
507#if defined(VISP_HAVE_X11)
508 vpDisplayX display, display2;
509#elif defined(VISP_HAVE_GDI)
510 vpDisplayGDI display, display2;
511#elif defined(HAVE_OPENCV_HIGHGUI)
512 vpDisplayOpenCV display, display2;
513#elif defined(VISP_HAVE_D3D9)
514 vpDisplayD3D display, display2;
515#elif defined(VISP_HAVE_GTK)
516 vpDisplayGTK display, display2;
517#else
518 opt_display = false;
519#endif
520 if (opt_display) {
521#if defined(VISP_HAVE_DISPLAY)
522 display.setDownScalingFactor(vpDisplay::SCALE_AUTO);
523 display.init(I_depth, 100, 100, "Depth");
525 display2.init(I, I_depth.getWidth() + 100, 100, "Image");
526#endif
527 vpDisplay::display(I_depth);
529 vpDisplay::flush(I_depth);
531 }
532
533 // Object pointer to check that inheritance is ok
534 vpMbTracker *tracker = new vpMbGenericTracker(1, trackerType_depth);
537
538 loadConfiguration(tracker, configFile_depth);
539
540 // Display the moving edges, and the Klt points
541 tracker->setDisplayFeatures(displayFeatures);
542
543 // Tells if the tracker has to use Ogre3D for visibility tests
544 tracker->setOgreVisibilityTest(useOgre);
545 if (useOgre)
546 tracker->setOgreShowConfigDialog(showOgreConfigDialog);
547
548 // Tells if the tracker has to use the scanline visibility tests
549 tracker->setScanLineVisibilityTest(useScanline);
550
551 // Tells if the tracker has to compute the covariance matrix
552 tracker->setCovarianceComputation(computeCovariance);
553
554 // Tells if the tracker has to compute the projection error
555 tracker->setProjectionErrorComputation(projectionError);
556
557 // For generic projection error computation
558 tracker->setProjectionErrorDisplay(true);
559 tracker->setProjectionErrorDisplayArrowLength(30);
560 tracker->setProjectionErrorDisplayArrowThickness(2);
561
562 // Retrieve the camera parameters from the tracker
563 dynamic_cast<vpMbGenericTracker *>(tracker)->getCameraParameters(cam);
564
566 cam_color.initPersProjWithoutDistortion(615.1674804688, 615.1675415039, 312.1889953613, 243.4373779297);
568 std::string depth_M_color_filename =
569 vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath, "mbt-depth/castel/depth_M_color.txt");
570 {
571 std::ifstream depth_M_color_file(depth_M_color_filename.c_str());
572 depth_M_color.load(depth_M_color_file);
573 }
574
575 // Loop to position the object
576 if (opt_display && opt_click_allowed) {
577 while (!vpDisplay::getClick(I_depth, false)) {
578 vpDisplay::display(I_depth);
579 vpDisplay::displayText(I_depth, 15, 10, "click after positioning the object", vpColor::red);
580 vpDisplay::flush(I_depth);
581 }
582 }
583
584 // Load the 3D model (either a vrml file or a .cao file)
585 dynamic_cast<vpMbGenericTracker *>(tracker)->loadModel(modelFile_depth);
586
587 if (opt_display && opt_click_allowed) {
588 // Initialise the tracker by clicking on the image
589 dynamic_cast<vpMbGenericTracker *>(tracker)->initClick(I_depth, initFile, true);
590 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(cMo);
591 // display the 3D model at the given pose
592 dynamic_cast<vpMbGenericTracker *>(tracker)->display(I_depth, cMo, cam, vpColor::red);
593 }
594 else {
595 vpHomogeneousMatrix cMoi(0.04431452054, 0.09294637757, 0.3357760654, -2.677922443, 0.121297639, -0.6028463357);
596 dynamic_cast<vpMbGenericTracker *>(tracker)->initFromPose(I_depth, cMoi);
597 }
598
599 // track the model
600 {
601 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
602 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
603 mapOfPointclouds["Camera"] = &pointcloud;
604 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
605 mapOfWidths["Camera"] = pointcloud_width;
606 mapOfHeights["Camera"] = pointcloud_height;
607
608 dynamic_cast<vpMbGenericTracker *>(tracker)->track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
609 }
610 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(cMo);
611
612 if (opt_display) {
613 vpDisplay::flush(I_depth);
614 }
615
616 bool quit = false, click = false;
617 unsigned int frame_index = 0;
618 std::vector<double> time_vec;
619 while (read_data(frame_index, ipath, I, I_depth_raw, pointcloud, pointcloud_width, pointcloud_height) && !quit &&
620 (opt_lastFrame > 0 ? static_cast<int>(frame_index) <= opt_lastFrame : true)) {
621 vpImageConvert::createDepthHistogram(I_depth_raw, I_depth);
622
623 if (opt_display) {
624 vpDisplay::display(I_depth);
626
627 std::stringstream ss;
628 ss << "Num frame: " << frame_index;
629 vpDisplay::displayText(I_depth, 40, 20, ss.str(), vpColor::red);
630 }
631
632 // Test reset the tracker
633 if (frame_index == 10) {
634 std::cout << "----------Test reset tracker----------" << std::endl;
635 if (opt_display) {
636 vpDisplay::display(I_depth);
637 }
638
639 tracker->resetTracker();
640
641 loadConfiguration(tracker, configFile_depth);
642 dynamic_cast<vpMbGenericTracker *>(tracker)->loadModel(modelFile_depth);
643 dynamic_cast<vpMbGenericTracker *>(tracker)->setCameraParameters(cam);
644 tracker->setOgreVisibilityTest(useOgre);
645 tracker->setScanLineVisibilityTest(useScanline);
646 tracker->setCovarianceComputation(computeCovariance);
647 tracker->setProjectionErrorComputation(projectionError);
648 dynamic_cast<vpMbGenericTracker *>(tracker)->initFromPose(I_depth, cMo);
649 }
650
651 // Test set an initial pose
652#if USE_SMALL_DATASET
653 if (frame_index == 20) {
654 cMo.buildFrom(0.05319520317, 0.09223511976, 0.3380095812, -2.71438192, 0.07141055397, -0.3810081638);
655#else
656 if (frame_index == 50) {
657 cMo.buildFrom(0.06865933578, 0.09494713501, 0.3260555142, -2.730027451, 0.03498390135, 0.01989831338);
658#endif
659 std::cout << "Test set pose" << std::endl;
660 dynamic_cast<vpMbGenericTracker *>(tracker)->setPose(I_depth, cMo);
661 }
662
663#if USE_SMALL_DATASET
664 // track the object: stop tracking from frame 15 to 20
665 if (frame_index < 15 || frame_index >= 20) {
666#else
667 // track the object: stop tracking from frame 30 to 50
668 if (frame_index < 30 || frame_index >= 50) {
669#endif
670 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
671 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
672 mapOfPointclouds["Camera"] = &pointcloud;
673 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
674 mapOfWidths["Camera"] = pointcloud_width;
675 mapOfHeights["Camera"] = pointcloud_height;
676
677 if (disable_castle_faces) {
678 std::vector<std::string> element_names = getCastleElementNames(disable_castle_faces);
679 std::cout << "Disable: ";
680 for (size_t idx = 0; idx < element_names.size(); idx++) {
681 std::cout << element_names[idx];
682 if (idx + 1 < element_names.size())
683 std::cout << ", ";
684
685 if (trackerType_depth & vpMbGenericTracker::DEPTH_DENSE_TRACKER)
686 dynamic_cast<vpMbGenericTracker *>(tracker)->setUseDepthDenseTracking(element_names[idx], false);
687 if (trackerType_depth & vpMbGenericTracker::DEPTH_NORMAL_TRACKER)
688 dynamic_cast<vpMbGenericTracker *>(tracker)->setUseDepthNormalTracking(element_names[idx], false);
689 }
690 std::cout << std::endl;
691 }
692
693 double t = vpTime::measureTimeMs();
694 dynamic_cast<vpMbGenericTracker *>(tracker)->track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
696 time_vec.push_back(t);
697
698 dynamic_cast<vpMbGenericTracker *>(tracker)->getPose(cMo);
699
700 if (opt_display) {
701 // display the 3D model
702 dynamic_cast<vpMbGenericTracker *>(tracker)->display(I_depth, cMo, cam, vpColor::darkRed);
703 // display the frame
704 vpDisplay::displayFrame(I_depth, cMo, cam, 0.05);
705 // computation time
706 std::stringstream ss;
707 ss << "Computation time: " << t << " ms";
708 vpDisplay::displayText(I_depth, 60, 20, ss.str(), vpColor::red);
709 // nb features
710 ss.str("");
711 ss << "nb features: " << tracker->getError().getRows();
712 vpDisplay::displayText(I_depth, 80, 20, ss.str(), vpColor::red);
713
714 // generic projection error computed on image from the RGB camera
715 double projection_error = tracker->computeCurrentProjectionError(I, depth_M_color.inverse() * cMo, cam_color);
716 ss.str("");
717 ss << "Projection error: " << projection_error;
718 vpDisplay::displayText(I, 20, 20, ss.str(), vpColor::red);
719 }
720 }
721
722 if (opt_click_allowed && opt_display) {
723 vpDisplay::displayText(I_depth, 10, 10, "Click to quit", vpColor::red);
725 if (vpDisplay::getClick(I_depth, button, click)) {
726 switch (button) {
728 quit = !click;
729 break;
730
732 click = !click;
733 break;
734
735 default:
736 break;
737 }
738 }
739 }
740
741 if (computeCovariance) {
742 std::cout << "Covariance matrix: \n" << tracker->getCovarianceMatrix() << std::endl << std::endl;
743 }
744
745 if (projectionError) {
746 std::cout << "Projection error: " << tracker->getProjectionError() << std::endl << std::endl;
747 }
748
749 if (opt_display) {
750 vpDisplay::flush(I_depth);
752 }
753
754 frame_index++;
755 }
756
757 std::cout << "\nFinal poses, cMo:\n" << cMo << std::endl;
758 std::cout << "\nComputation time, Mean: " << vpMath::getMean(time_vec)
759 << " ms ; Median: " << vpMath::getMedian(time_vec) << " ms ; Std: " << vpMath::getStdev(time_vec) << " ms"
760 << std::endl;
761
762 if (opt_click_allowed && !quit) {
763 vpDisplay::getClick(I_depth);
764 }
765
766 delete tracker;
767 tracker = nullptr;
768
769 return EXIT_SUCCESS;
770 }
771 catch (const vpException &e) {
772 std::cout << "Catch an exception: " << e << std::endl;
773 return EXIT_FAILURE;
774 }
775 }
776
777#elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY))
778int main()
779{
780 std::cout << "Cannot run this example: visp_mbt, visp_gui modules are required." << std::endl;
781 return EXIT_SUCCESS;
782}
783#else
784int main()
785{
786 std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
787 return EXIT_SUCCESS;
788}
789#endif
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
static const vpColor red
Definition vpColor.h:198
static const vpColor darkRed
Definition vpColor.h:199
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)
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.
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:131
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition vpImage.h:544
static std::string getViSPImagesDataPath()
static bool checkFilename(const std::string &filename)
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
static bool checkDirectory(const std::string &dirname)
static std::string formatString(const std::string &name, unsigned int val)
static std::string createFilePath(const std::string &parent, const std::string &child)
static double rad(double deg)
Definition vpMath.h:129
static double getMedian(const std::vector< double > &v)
Definition vpMath.cpp:343
static double getStdev(const std::vector< double > &v, bool useBesselCorrection=false)
Definition vpMath.cpp:374
static double getMean(const std::vector< double > &v)
Definition vpMath.cpp:323
Real-time 6D object pose tracking using its CAD model.
Main methods for a model-based tracker.
@ ROBUST_FEATURE_ESTIMATION
Robust scheme to estimate the normal of the plane.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
read_data(CameraParameters|None cam_depth, ImageGray I, rs.pipeline pipe)
VISP_EXPORT double measureTimeMs()