44 #include <visp3/core/vpConfig.h> 46 #if (defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY)) \ 47 && (defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV)) 49 #include <visp3/core/vpDebug.h> 50 #include <visp3/core/vpHomogeneousMatrix.h> 51 #include <visp3/core/vpIoTools.h> 52 #include <visp3/core/vpMath.h> 53 #include <visp3/gui/vpDisplayD3D.h> 54 #include <visp3/gui/vpDisplayGDI.h> 55 #include <visp3/gui/vpDisplayGTK.h> 56 #include <visp3/gui/vpDisplayOpenCV.h> 57 #include <visp3/gui/vpDisplayX.h> 58 #include <visp3/io/vpImageIo.h> 59 #include <visp3/io/vpParseArgv.h> 60 #include <visp3/io/vpVideoReader.h> 61 #include <visp3/mbt/vpMbGenericTracker.h> 63 #define GETOPTARGS "X:M:i:n:dchfolwvpT:e:u:" 66 #define USE_SMALL_DATASET 1 // small depth dataset in ViSP-images 70 void usage(
const char *name,
const char *badparam)
73 Example of tracking with vpGenericTracker.\n\ 76 %s [-i <test image path>] [-X <config file depth>]\n\ 77 [-M <model name depth>] [-n <initialisation file base name>]\n\ 78 [-f] [-c] [-d] [-h] [-o] [-w] [-l] [-v] [-p]\n\ 79 [-T <tracker type>] [-e <last frame index>]\n\ 80 [-u <disable face>]\n", name);
84 -i <input image path> \n\ 85 Set image input path.\n\ 86 These images come from ViSP-images-x.y.z.tar.gz available \n\ 87 on the ViSP website.\n\ 88 Setting the VISP_INPUT_IMAGE_PATH environment\n\ 89 variable produces the same behavior than using\n\ 93 Set the config file (the xml file) to use for the depth sensor.\n\ 94 The config file is used to specify the parameters of the tracker.\n\ 97 Specify the name of the file of the model for the depth sensor.\n\ 98 The model can either be a vrml model (.wrl) or a .cao file.\n\ 100 -n <initialisation file base name> \n\ 101 Base name of the initialisation file. The file will be 'base_name'.init .\n\ 102 This base name is also used for the optional picture specifying where to \n\ 103 click (a .ppm picture).\n\ 106 Turn off the display of the visual features. \n\ 109 Turn off the display.\n\ 112 Disable the mouse click. Useful to automate the \n\ 113 execution of this program without human intervention.\n\ 116 Use Ogre3D for visibility tests\n\ 119 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\ 122 Use the scanline for visibility tests.\n\ 125 Compute covariance matrix.\n\ 128 Compute gradient projection error.\n\ 131 Set tracker type (<4 (Depth normal)>, <8 (Depth dense)>, <12 (both)>) for depth sensor.\n\ 133 -e <last frame index>\n\ 134 Specify the index of the last frame. Once reached, the tracking is stopped.\n\ 137 Disable castle element (1=floor, 2=front_door, 4=slope, 8=tower_front, 16=tower_left, 32=tower_right, 64=tower_back).\n\ 140 Print the help.\n\n");
143 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
146 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &configFile_depth,
147 std::string &modelFile_depth, std::string &initFile,
bool &displayFeatures,
bool &click_allowed,
148 bool &display,
bool &useOgre,
bool &showOgreConfigDialog,
bool &useScanline,
bool &computeCovariance,
149 bool &projectionError,
int &tracker_type_depth,
int &lastFrame,
int &disable_castle_faces)
160 configFile_depth = optarg_;
163 modelFile_depth = optarg_;
169 displayFeatures =
false;
172 click_allowed =
false;
184 showOgreConfigDialog =
true;
187 computeCovariance =
true;
190 projectionError =
true;
193 tracker_type_depth = atoi(optarg_);
196 lastFrame = atoi(optarg_);
199 disable_castle_faces = atoi(optarg_);
203 usage(argv[0], NULL);
207 usage(argv[0], optarg_);
213 if ((c == 1) || (c == -1)) {
215 usage(argv[0], NULL);
216 std::cerr <<
"ERROR: " << std::endl;
217 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
224 struct rs_intrinsics {
236 void rs_deproject_pixel_to_point(
float point[3],
const rs_intrinsics &intrin,
const float pixel[2],
float depth)
238 float x = (pixel[0] - intrin.ppx) / intrin.fx;
239 float y = (pixel[1] - intrin.ppy) / intrin.fy;
241 float r2 = x * x + y * y;
242 float f = 1 + intrin.coeffs[0] * r2 + intrin.coeffs[1] * r2 * r2 + intrin.coeffs[4] * r2 * r2 * r2;
243 float ux = x * f + 2 * intrin.coeffs[2] * x * y + intrin.coeffs[3] * (r2 + 2 * x * x);
244 float uy = y * f + 2 * intrin.coeffs[3] * x * y + intrin.coeffs[2] * (r2 + 2 * y * y);
249 point[0] = depth * x;
250 point[1] = depth * y;
255 std::vector<vpColVector> &pointcloud,
unsigned int &pointcloud_width,
unsigned int &pointcloud_height)
260 std::stringstream ss;
261 ss << input_directory <<
"/image_%04d.pgm";
262 sprintf(buffer, ss.str().c_str(), cpt);
263 std::string filename_image = buffer;
266 std::cerr <<
"Cannot read: " << filename_image << std::endl;
273 ss << input_directory <<
"/depth_image_%04d.bin";
274 sprintf(buffer, ss.str().c_str(), cpt);
275 std::string filename_depth = buffer;
277 std::ifstream file_depth(filename_depth.c_str(), std::ios::in | std::ios::binary);
278 if (!file_depth.is_open()) {
282 unsigned int height = 0, width = 0;
286 I_depth_raw.
resize(height, width);
288 uint16_t depth_value = 0;
289 for (
unsigned int i = 0; i < height; i++) {
290 for (
unsigned int j = 0; j < width; j++) {
292 I_depth_raw[i][j] = depth_value;
297 pointcloud_width = width;
298 pointcloud_height = height;
299 pointcloud.
resize((
size_t)width * height);
302 const float depth_scale = 0.000124986647f;
303 rs_intrinsics depth_intrinsic;
304 depth_intrinsic.ppx = 311.484558f;
305 depth_intrinsic.ppy = 246.283234f;
306 depth_intrinsic.fx = 476.053619f;
307 depth_intrinsic.fy = 476.053497f;
308 depth_intrinsic.coeffs[0] = 0.165056542f;
309 depth_intrinsic.coeffs[1] = -0.0508309528f;
310 depth_intrinsic.coeffs[2] = 0.00435937941f;
311 depth_intrinsic.coeffs[3] = 0.00541406544f;
312 depth_intrinsic.coeffs[4] = 0.250085592f;
314 for (
unsigned int i = 0; i < height; i++) {
315 for (
unsigned int j = 0; j < width; j++) {
316 float scaled_depth = I_depth_raw[i][j] * depth_scale;
318 float pixel[2] = {(float)j, (
float)i};
319 rs_deproject_pixel_to_point(point, depth_intrinsic, pixel, scaled_depth);
322 data_3D[0] = point[0];
323 data_3D[1] = point[1];
324 data_3D[2] = point[2];
326 pointcloud[(size_t)(i * width + j)] = data_3D;
333 void loadConfiguration(
vpMbTracker *
const tracker,
const std::string &
346 dynamic_cast<vpMbGenericTracker *
>(tracker)->setDepthNormalPclPlaneEstimationMethod(2);
347 dynamic_cast<vpMbGenericTracker *
>(tracker)->setDepthNormalPclPlaneEstimationRansacMaxIter(200);
348 dynamic_cast<vpMbGenericTracker *
>(tracker)->setDepthNormalPclPlaneEstimationRansacThreshold(0.001);
371 std::vector<std::string> getCastleElementNames(
const int element)
373 std::vector<std::string> element_names;
376 element_names.push_back(
"floor");
378 element_names.push_back(
"front_door");
380 element_names.push_back(
"slope");
382 element_names.push_back(
"tower_front");
384 element_names.push_back(
"tower_left");
386 element_names.push_back(
"tower_right");
388 element_names.push_back(
"tower_back");
390 return element_names;
394 int main(
int argc,
const char **argv)
397 std::string env_ipath;
398 std::string opt_ipath;
400 std::string opt_configFile_depth;
401 std::string opt_modelFile_depth;
402 std::string opt_initFile;
403 std::string initFile;
404 bool displayFeatures =
true;
405 bool opt_click_allowed =
true;
406 bool opt_display =
true;
407 bool useOgre =
false;
408 bool showOgreConfigDialog =
false;
409 bool useScanline =
false;
410 bool computeCovariance =
false;
411 bool projectionError =
false;
413 #if defined(__mips__) || defined(__mips) || defined(mips) || defined(__MIPS__) 415 int opt_lastFrame = 5;
417 int opt_lastFrame = -1;
419 int disable_castle_faces = 0;
426 if (!env_ipath.empty())
430 if (!getOptions(argc, argv, opt_ipath, opt_configFile_depth, opt_modelFile_depth, opt_initFile, displayFeatures,
431 opt_click_allowed, opt_display, useOgre, showOgreConfigDialog, useScanline, computeCovariance,
432 projectionError, trackerType_depth, opt_lastFrame, disable_castle_faces)) {
437 if (opt_ipath.empty() && env_ipath.empty()) {
438 usage(argv[0], NULL);
439 std::cerr << std::endl <<
"ERROR:" << std::endl;
440 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
441 <<
" environment variable to specify the location of the " << std::endl
442 <<
" image path where test images are located." << std::endl
453 std::cerr <<
"ViSP-images does not contain the folder: " << dir_path <<
"!" << std::endl;
457 std::string configFile_depth;
458 if (!opt_configFile_depth.empty())
459 configFile_depth = opt_configFile_depth;
464 std::string modelFile_depth;
465 if (!opt_modelFile_depth.empty())
466 modelFile_depth = opt_modelFile_depth;
471 std::string vrml_ext =
".wrl";
473 (modelFile_depth.compare(modelFile_depth.length() - vrml_ext.length(), vrml_ext.length(), vrml_ext) == 0);
476 #if defined(VISP_HAVE_COIN3D) && (COIN_MAJOR_VERSION == 2 || COIN_MAJOR_VERSION == 3 || COIN_MAJOR_VERSION == 4) 477 std::cout <<
"use_vrml: " << use_vrml << std::endl;
479 std::cerr <<
"Error: vrml model file is only supported if ViSP is " 480 "build with Coin3D 3rd party" 486 if (!opt_initFile.empty())
487 initFile = opt_initFile;
493 std::vector<vpColVector> pointcloud;
494 unsigned int pointcloud_width, pointcloud_height;
495 if (!read_data(0, ipath, I, I_depth_raw, pointcloud, pointcloud_width, pointcloud_height)) {
496 std::cerr <<
"Cannot open sequence: " << ipath << std::endl;
503 #if defined VISP_HAVE_X11 505 #elif defined VISP_HAVE_GDI 507 #elif defined VISP_HAVE_OPENCV 509 #elif defined VISP_HAVE_D3D9 511 #elif defined VISP_HAVE_GTK 517 #if defined(VISP_HAVE_DISPLAY) 519 display.
init(I_depth, 100, 100,
"Depth");
521 display2.
init(I, I_depth.getWidth()+100, 100,
"Image");
534 loadConfiguration(tracker, configFile_depth);
564 std::string depth_M_color_filename =
567 std::ifstream depth_M_color_file(depth_M_color_filename.c_str());
568 depth_M_color.
load(depth_M_color_file);
572 if (opt_display && opt_click_allowed) {
583 if (opt_display && opt_click_allowed) {
590 vpHomogeneousMatrix cMoi(0.04431452054, 0.09294637757, 0.3357760654, -2.677922443, 0.121297639, -0.6028463357);
596 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
597 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
598 mapOfPointclouds[
"Camera"] = &pointcloud;
599 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
600 mapOfWidths[
"Camera"] = pointcloud_width;
601 mapOfHeights[
"Camera"] = pointcloud_height;
603 dynamic_cast<vpMbGenericTracker *
>(tracker)->track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
611 bool quit =
false, click =
false;
612 unsigned int frame_index = 0;
613 std::vector<double> time_vec;
614 while (read_data(frame_index, ipath, I, I_depth_raw, pointcloud, pointcloud_width, pointcloud_height) && !quit &&
615 (opt_lastFrame > 0 ? (
int)frame_index <= opt_lastFrame :
true)) {
622 std::stringstream ss;
623 ss <<
"Num frame: " << frame_index;
628 if (frame_index == 10) {
629 std::cout <<
"----------Test reset tracker----------" << std::endl;
636 loadConfiguration(tracker, configFile_depth);
647 #if USE_SMALL_DATASET 648 if (frame_index == 20) {
649 cMo.
buildFrom(0.05319520317, 0.09223511976, 0.3380095812, -2.71438192, 0.07141055397, -0.3810081638);
651 if (frame_index == 50) {
652 cMo.
buildFrom(0.06865933578, 0.09494713501, 0.3260555142, -2.730027451, 0.03498390135, 0.01989831338);
654 std::cout <<
"Test set pose" << std::endl;
658 #if USE_SMALL_DATASET 660 if (frame_index < 15 || frame_index >= 20) {
663 if (frame_index < 30 || frame_index >= 50) {
665 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
666 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
667 mapOfPointclouds[
"Camera"] = &pointcloud;
668 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
669 mapOfWidths[
"Camera"] = pointcloud_width;
670 mapOfHeights[
"Camera"] = pointcloud_height;
672 if (disable_castle_faces) {
673 std::vector<std::string> element_names = getCastleElementNames(disable_castle_faces);
674 std::cout <<
"Disable: ";
675 for (
size_t idx = 0; idx < element_names.size(); idx++) {
676 std::cout << element_names[idx];
677 if (idx + 1 < element_names.size())
681 dynamic_cast<vpMbGenericTracker *
>(tracker)->setUseDepthDenseTracking(element_names[idx],
false);
683 dynamic_cast<vpMbGenericTracker *
>(tracker)->setUseDepthNormalTracking(element_names[idx],
false);
685 std::cout << std::endl;
689 dynamic_cast<vpMbGenericTracker *
>(tracker)->track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
691 time_vec.push_back(t);
701 std::stringstream ss;
702 ss <<
"Computation time: " << t <<
" ms";
712 ss <<
"Projection error: " << projection_error;
717 if (opt_click_allowed && opt_display) {
736 if (computeCovariance) {
737 std::cout <<
"Covariance matrix: \n" << tracker->
getCovarianceMatrix() << std::endl << std::endl;
740 if (projectionError) {
741 std::cout <<
"Projection error: " << tracker->
getProjectionError() << std::endl << std::endl;
752 std::cout <<
"\nFinal poses, cMo:\n" << cMo << std::endl;
757 if (opt_click_allowed && !quit) {
766 std::cout <<
"Catch an exception: " << e << std::endl;
771 #elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY)) 774 std::cout <<
"Cannot run this example: visp_mbt, visp_gui modules are required." 781 std::cout <<
"Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
virtual unsigned int getClipping() const
virtual void setCovarianceComputation(const bool &flag)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
virtual void setAngleDisappear(const double &a)
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Implementation of an homogeneous matrix and operations on such kind of matrices.
virtual void setDownScalingFactor(unsigned int scale)
static double getMedian(const std::vector< double > &v)
static const vpColor darkRed
Display for windows using GDI (available on any windows 32 platform).
static double getStdev(const std::vector< double > &v, bool useBesselCorrection=false)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
virtual void setOgreShowConfigDialog(bool showConfigDialog)
virtual double getProjectionError() const
error that can be emited by ViSP classes.
unsigned int getRows() const
vpHomogeneousMatrix inverse() const
Real-time 6D object pose tracking using its CAD model.
virtual void resetTracker()=0
static void flush(const vpImage< unsigned char > &I)
void load(std::ifstream &f)
VISP_EXPORT double measureTimeMs()
virtual void setProjectionErrorDisplayArrowLength(unsigned int length)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
static double getMean(const std::vector< double > &v)
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Generic class defining intrinsic camera parameters.
void init(vpImage< unsigned char > &I, int win_x=-1, int win_y=-1, const std::string &win_title="")
Main methods for a model-based tracker.
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
virtual void setAngleAppear(const double &a)
void buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
static double rad(double deg)
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
virtual void setProjectionErrorDisplay(bool display)
virtual void setProjectionErrorDisplayArrowThickness(unsigned int thickness)
virtual void setOgreVisibilityTest(const bool &v)
virtual double computeCurrentProjectionError(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &_cMo, const vpCameraParameters &_cam)
Implementation of column vector and the associated operations.
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))
virtual vpMatrix getCovarianceMatrix() const
virtual void setScanLineVisibilityTest(const bool &v)
virtual void setClipping(const unsigned int &flags)
virtual void setFarClippingDistance(const double &dist)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
virtual void setDisplayFeatures(bool displayF)
virtual void setProjectionErrorComputation(const bool &flag)
virtual vpColVector getError() const =0
virtual void setNearClippingDistance(const double &dist)