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:X:m:M:i:n:dchfolwvpt:T:e:" 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>] [-X <config file depth>]\n\ 77 [-m <model name>] [-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>] [-T <tracker type>] [-e <last frame index>]\n", name);
83 -i <input image path> \n\ 84 Set image input path.\n\ 85 These images come from ViSP-images-x.y.z.tar.gz available \n\ 86 on the ViSP website.\n\ 87 Setting the VISP_INPUT_IMAGE_PATH environment\n\ 88 variable produces the same behavior than using\n\ 92 Set the config file (the xml file) to use.\n\ 93 The config file is used to specify the parameters of the tracker.\n\ 96 Set the config file (the xml file) to use for the depth sensor.\n\ 97 The config file is used to specify the parameters of the tracker.\n\ 100 Specify the name of the file of the model.\n\ 101 The model can either be a vrml model (.wrl) or a .cao file.\n\ 104 Specify the name of the file of the model for the depth sensor.\n\ 105 The model can either be a vrml model (.wrl) or a .cao file.\n\ 107 -n <initialisation file base name> \n\ 108 Base name of the initialisation file. The file will be 'base_name'.init .\n\ 109 This base name is also used for the optional picture specifying where to \n\ 110 click (a .ppm picture).\n\ 113 Turn off the display of the the moving edges and Klt points. \n\ 116 Turn off the display.\n\ 119 Disable the mouse click. Useful to automate the \n\ 120 execution of this program without human intervention.\n\ 123 Use Ogre3D for visibility tests\n\ 126 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\ 129 Use the scanline for visibility tests.\n\ 132 Compute covariance matrix.\n\ 135 Compute gradient projection error.\n\ 138 Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (both)>) for color sensor.\n\ 141 Set tracker type (<4 (Depth normal)>, <8 (Depth dense)>, <12 (both)>) for depth sensor.\n\ 143 -e <last frame index>\n\ 144 Specify the index of the last frame. Once reached, the tracking is stopped.\n\ 147 Print the help.\n\n");
150 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
153 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &configFile, std::string &configFile_depth,
154 std::string &modelFile, std::string &modelFile_depth, std::string &initFile,
bool &displayFeatures,
155 bool &click_allowed,
bool &display,
bool &useOgre,
bool &showOgreConfigDialog,
bool &useScanline,
156 bool &computeCovariance,
bool &projectionError,
int &trackerType,
int &tracker_type_depth,
168 configFile = optarg_;
171 configFile_depth = optarg_;
177 modelFile_depth = optarg_;
183 displayFeatures =
false;
186 click_allowed =
false;
198 showOgreConfigDialog =
true;
201 computeCovariance =
true;
204 projectionError =
true;
207 trackerType = atoi(optarg_);
210 tracker_type_depth = atoi(optarg_);
213 lastFrame = atoi(optarg_);
216 usage(argv[0], NULL);
221 usage(argv[0], optarg_);
227 if ((c == 1) || (c == -1)) {
229 usage(argv[0], NULL);
230 std::cerr <<
"ERROR: " << std::endl;
231 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
238 struct rs_intrinsics {
250 void rs_deproject_pixel_to_point(
float point[3],
const rs_intrinsics &intrin,
const float pixel[2],
float depth)
252 float x = (pixel[0] - intrin.ppx) / intrin.fx;
253 float y = (pixel[1] - intrin.ppy) / intrin.fy;
255 float r2 = x * x + y * y;
256 float f = 1 + intrin.coeffs[0] * r2 + intrin.coeffs[1] * r2 * r2 + intrin.coeffs[4] * r2 * r2 * r2;
257 float ux = x * f + 2 * intrin.coeffs[2] * x * y + intrin.coeffs[3] * (r2 + 2 * x * x);
258 float uy = y * f + 2 * intrin.coeffs[3] * x * y + intrin.coeffs[2] * (r2 + 2 * y * y);
263 point[0] = depth * x;
264 point[1] = depth * y;
269 vpImage<uint16_t> &I_depth_raw, std::vector<vpColVector> &pointcloud,
unsigned int &pointcloud_width,
270 unsigned int &pointcloud_height)
275 std::stringstream ss;
276 ss << input_directory <<
"/image_%04d.pgm";
277 sprintf(buffer, ss.str().c_str(), cpt);
278 std::string filename_image = buffer;
281 std::cerr <<
"Cannot read: " << filename_image << std::endl;
288 ss << input_directory <<
"/depth_image_%04d.bin";
289 sprintf(buffer, ss.str().c_str(), cpt);
290 std::string filename_depth = buffer;
292 std::ifstream file_depth(filename_depth.c_str(), std::ios::in | std::ios::binary);
293 if (!file_depth.is_open()) {
297 unsigned int height = 0, width = 0;
301 I_depth_raw.
resize(height, width);
303 uint16_t depth_value = 0;
304 for (
unsigned int i = 0; i < height; i++) {
305 for (
unsigned int j = 0; j < width; j++) {
307 I_depth_raw[i][j] = depth_value;
312 pointcloud_width = width;
313 pointcloud_height = height;
314 pointcloud.
resize((
size_t)width * height);
317 const float depth_scale = 0.000124986647f;
318 rs_intrinsics depth_intrinsic;
319 depth_intrinsic.ppx = 311.484558f;
320 depth_intrinsic.ppy = 246.283234f;
321 depth_intrinsic.fx = 476.053619f;
322 depth_intrinsic.fy = 476.053497f;
323 depth_intrinsic.coeffs[0] = 0.165056542f;
324 depth_intrinsic.coeffs[1] = -0.0508309528f;
325 depth_intrinsic.coeffs[2] = 0.00435937941f;
326 depth_intrinsic.coeffs[3] = 0.00541406544f;
327 depth_intrinsic.coeffs[4] = 0.250085592f;
329 for (
unsigned int i = 0; i < height; i++) {
330 for (
unsigned int j = 0; j < width; j++) {
331 float scaled_depth = I_depth_raw[i][j] * depth_scale;
333 float pixel[2] = {(float)j, (
float)i};
334 rs_deproject_pixel_to_point(point, depth_intrinsic, pixel, scaled_depth);
337 data_3D[0] = point[0];
338 data_3D[1] = point[1];
339 data_3D[2] = point[2];
341 pointcloud[(size_t)(i * width + j)] = data_3D;
362 dynamic_cast<vpMbGenericTracker *
>(tracker)->loadConfigFile(configFile, configFile_depth);
376 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 393 dynamic_cast<vpMbGenericTracker *
>(tracker)->setDepthNormalPclPlaneEstimationMethod(2);
394 dynamic_cast<vpMbGenericTracker *
>(tracker)->setDepthNormalPclPlaneEstimationRansacMaxIter(200);
395 dynamic_cast<vpMbGenericTracker *
>(tracker)->setDepthNormalPclPlaneEstimationRansacThreshold(0.001);
420 int main(
int argc,
const char **argv)
423 std::string env_ipath;
424 std::string opt_ipath;
426 std::string opt_configFile;
427 std::string opt_configFile_depth;
428 std::string opt_modelFile;
429 std::string opt_modelFile_depth;
430 std::string opt_initFile;
431 std::string initFile;
432 bool displayFeatures =
true;
433 bool opt_click_allowed =
true;
434 bool opt_display =
true;
435 bool useOgre =
false;
436 bool showOgreConfigDialog =
false;
437 bool useScanline =
false;
438 bool computeCovariance =
false;
439 bool projectionError =
false;
442 #if defined(__mips__) || defined(__mips) || defined(mips) || defined(__MIPS__) 444 int opt_lastFrame = 5;
446 int opt_lastFrame = -1;
454 if (!env_ipath.empty())
458 if (!getOptions(argc, argv, opt_ipath, opt_configFile, opt_configFile_depth, opt_modelFile, opt_modelFile_depth,
459 opt_initFile, displayFeatures, opt_click_allowed, opt_display, useOgre, showOgreConfigDialog,
460 useScanline, computeCovariance, projectionError, trackerType_image, trackerType_depth,
465 #if !defined(VISP_HAVE_MODULE_KLT) || (!defined(VISP_HAVE_OPENCV) || (VISP_HAVE_OPENCV_VERSION < 0x020100)) 466 if (trackerType_image == 2) {
467 std::cout <<
"KLT only features cannot be used: ViSP is not built with " 468 "KLT module or OpenCV is not available." 475 if (opt_ipath.empty() && env_ipath.empty()) {
476 usage(argv[0], NULL);
477 std::cerr << std::endl <<
"ERROR:" << std::endl;
478 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
479 <<
" environment variable to specify the location of the " << std::endl
480 <<
" image path where test images are located." << std::endl
491 std::cerr <<
"ViSP-images does not contain the folder: " << dir_path <<
"!" << std::endl;
495 std::string configFile, configFile_depth;
496 if (!opt_configFile.empty())
497 configFile = opt_configFile;
502 if (!opt_configFile_depth.empty())
503 configFile_depth = opt_configFile_depth;
508 std::string modelFile, modelFile_depth;
509 if (!opt_modelFile.empty())
510 modelFile = opt_modelFile;
512 #if defined(VISP_HAVE_COIN3D) && (COIN_MAJOR_VERSION == 2 || COIN_MAJOR_VERSION == 3 || COIN_MAJOR_VERSION == 4) 520 if (!opt_modelFile_depth.empty())
521 modelFile_depth = opt_modelFile_depth;
526 std::string vrml_ext =
".wrl";
528 (modelFile.compare(modelFile.length() - vrml_ext.length(), vrml_ext.length(), vrml_ext) == 0) ||
529 (modelFile_depth.compare(modelFile_depth.length() - vrml_ext.length(), vrml_ext.length(), vrml_ext) == 0);
532 #if defined(VISP_HAVE_COIN3D) && (COIN_MAJOR_VERSION == 2 || COIN_MAJOR_VERSION == 3 || COIN_MAJOR_VERSION == 4) 533 std::cout <<
"use_vrml: " << use_vrml << std::endl;
535 std::cerr <<
"Error: vrml model file is only supported if ViSP is " 536 "build with Coin3D 3rd party" 542 if (!opt_initFile.empty())
543 initFile = opt_initFile;
549 std::vector<vpColVector> pointcloud;
550 unsigned int pointcloud_width, pointcloud_height;
551 if (!read_data(0, ipath, I, I_depth_raw, pointcloud, pointcloud_width, pointcloud_height)) {
552 std::cerr <<
"Cannot open sequence: " << ipath << std::endl;
559 #if defined VISP_HAVE_X11 561 #elif defined VISP_HAVE_GDI 563 #elif defined VISP_HAVE_OPENCV 565 #elif defined VISP_HAVE_D3D9 567 #elif defined VISP_HAVE_GTK 573 #if defined(VISP_HAVE_DISPLAY) 576 display1.
init(I, 100, 100,
"Test tracking (Left)");
578 "Test tracking (Right)");
586 std::vector<int> trackerTypes(2);
587 trackerTypes[0] = trackerType_image;
588 trackerTypes[1] = trackerType_depth;
594 loadConfiguration(tracker, configFile, configFile_depth);
597 std::string depth_M_color_filename =
600 std::ifstream depth_M_color_file(depth_M_color_filename.c_str());
601 depth_M_color.
load(depth_M_color_file);
602 std::map<std::string, vpHomogeneousMatrix> mapOfCameraTransformationMatrices;
603 mapOfCameraTransformationMatrices[
"Camera2"] = depth_M_color;
604 dynamic_cast<vpMbGenericTracker *
>(tracker)->setCameraTransformationMatrix(mapOfCameraTransformationMatrices);
628 if (opt_display && opt_click_allowed) {
639 if (opt_display && opt_click_allowed) {
640 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
641 mapOfImages[
"Camera1"] = &I;
642 mapOfImages[
"Camera2"] = &I_depth;
643 std::map<std::string, std::string> mapOfInitFiles;
644 mapOfInitFiles[
"Camera1"] = initFile;
647 dynamic_cast<vpMbGenericTracker *
>(tracker)->initClick(mapOfImages, mapOfInitFiles,
true);
652 vpHomogeneousMatrix c1Moi(0.06846423368, 0.09062570884, 0.3401096693, -2.671882598, 0.1174275908, -0.6011935263);
653 vpHomogeneousMatrix c2Moi(0.04431452054, 0.09294637757, 0.3357760654, -2.677922443, 0.121297639, -0.6028463357);
659 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
660 mapOfImages[
"Camera1"] = &I;
661 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
662 mapOfPointclouds[
"Camera2"] = &pointcloud;
663 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
664 mapOfWidths[
"Camera2"] = pointcloud_width;
665 mapOfHeights[
"Camera2"] = pointcloud_height;
667 dynamic_cast<vpMbGenericTracker *
>(tracker)->track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
676 bool quit =
false, click =
false;
677 unsigned int frame_index = 0;
678 std::vector<double> time_vec;
679 while (read_data(frame_index, ipath, I, I_depth_raw, pointcloud, pointcloud_width, pointcloud_height) && !quit &&
680 (opt_lastFrame > 0 ? (
int)frame_index <= opt_lastFrame :
true)) {
687 std::stringstream ss;
688 ss <<
"Num frame: " << frame_index;
693 if (frame_index == 10) {
694 std::cout <<
"----------Test reset tracker----------" << std::endl;
702 loadConfiguration(tracker, configFile, configFile_depth);
713 #if USE_SMALL_DATASET 714 if (frame_index == 20) {
715 c1Mo.
buildFrom(0.07734634051, 0.08993639906, 0.342344402, -2.708409543, 0.0669276477, -0.3798958303);
716 c2Mo.
buildFrom(0.05319520317, 0.09223511976, 0.3380095812, -2.71438192, 0.07141055397, -0.3810081638);
718 if (frame_index == 50) {
719 c1Mo.
buildFrom(0.09280663035, 0.09277655672, 0.330415149, -2.724431817, 0.0293932671, 0.02027966377);
720 c2Mo.
buildFrom(0.06865933578, 0.09494713501, 0.3260555142, -2.730027451, 0.03498390135, 0.01989831338);
722 std::cout <<
"Test set pose" << std::endl;
726 #if USE_SMALL_DATASET 728 if (frame_index < 15 || frame_index >= 20) {
731 if (frame_index < 30 || frame_index >= 50) {
733 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
734 mapOfImages[
"Camera1"] = &I;
735 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
736 mapOfPointclouds[
"Camera2"] = &pointcloud;
737 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
738 mapOfWidths[
"Camera2"] = pointcloud_width;
739 mapOfHeights[
"Camera2"] = pointcloud_height;
742 dynamic_cast<vpMbGenericTracker *
>(tracker)->track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
744 time_vec.push_back(t);
755 std::stringstream ss;
756 ss <<
"Computation time: " << t <<
" ms";
763 std::stringstream ss;
764 ss <<
"Features: edges " <<
dynamic_cast<vpMbGenericTracker *
>(tracker)->getNbFeaturesEdge()
766 <<
", depth " <<
dynamic_cast<vpMbGenericTracker *
>(tracker)->getNbFeaturesDepthDense();
772 if (opt_click_allowed && opt_display) {
791 if (computeCovariance) {
792 std::cout <<
"Covariance matrix: \n" << tracker->
getCovarianceMatrix() << std::endl << std::endl;
795 if (projectionError) {
796 std::cout <<
"Projection error: " << tracker->
getProjectionError() << std::endl << std::endl;
807 std::cout <<
"\nFinal poses, c1Mo:\n" << c1Mo <<
"\nc2Mo:\n" << c2Mo << std::endl;
812 if (opt_click_allowed && !quit) {
821 std::cout <<
"Catch an exception: " << e << std::endl;
826 #elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY)) 829 std::cout <<
"Cannot run this example: visp_mbt, visp_gui modules are required." 836 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)
void setMaxFeatures(int maxCount)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
void setHarrisFreeParameter(double harris_k)
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.
void setMaskNumber(const unsigned int &a)
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).
void setSampleStep(const double &s)
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
void setMinDistance(double minDistance)
error that can be emited by ViSP classes.
unsigned int getRows() 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()
void setMu1(const double &mu_1)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
void setQuality(double qualityLevel)
static double getMean(const std::vector< double > &v)
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
void setMaskSize(const unsigned int &a)
void setPyramidLevels(int pyrMaxLevel)
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...
void setWindowSize(int winSize)
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)
void setMu2(const double &mu_2)
virtual void setOgreVisibilityTest(const bool &v)
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))
unsigned int getDownScalingFactor()
virtual vpMatrix getCovarianceMatrix() const
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
void setThreshold(const double &t)
virtual void setScanLineVisibilityTest(const bool &v)
virtual void setClipping(const unsigned int &flags)
void setRange(const unsigned int &r)
virtual void setFarClippingDistance(const double &dist)
void setBlockSize(int blockSize)
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)