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:de:chtfColwvpT:"
65 #ifdef ENABLE_VISP_NAMESPACE
69 void usage(
const char *name,
const char *badparam)
71 #if VISP_HAVE_DATASET_VERSION >= 0x030600
72 std::string ext(
"png");
74 std::string ext(
"pgm");
77 Example of tracking based on the 3D model.\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]\n\
83 [-T <tracker type>]\n",
88 -i <input image path> \n\
89 Set image input path.\n\
90 From this path read images \n\
91 \"mbt/cube/image%%04d.%s\". These \n\
92 images come from visp-images-x.y.z.tar.gz available \n\
93 on the ViSP website.\n\
94 Setting the VISP_INPUT_IMAGE_PATH environment\n\
95 variable produces the same behavior than using\n\
99 Set the config file (the xml file) to use.\n\
100 The config file is used to specify the parameters of the tracker.\n\
103 Specify the name of the file of the model\n\
104 The model can either be a vrml model (.wrl) or a .cao file.\n\
106 -e <last frame index> \n\
107 Specify the index of the last frame. Once reached, the tracking is stopped\n\
110 Do not use the vrml model, use the .cao one. These two models are \n\
111 equivalent and comes from ViSP-images-x.y.z.tar.gz available on the ViSP\n\
112 website. However, the .cao model allows to use the 3d model based tracker \n\
116 Track only the cube (not the cylinder). In this case the models files are\n\
117 cube.cao or cube.wrl instead of cube_and_cylinder.cao and \n\
118 cube_and_cylinder.wrl.\n\
120 -n <initialisation file base name> \n\
121 Base name of the initialisation file. The file will be 'base_name'.init .\n\
122 This base name is also used for the optional picture specifying where to \n\
123 click (a .ppm picture).\n\
126 Turn off the display of the the moving edges and Klt points. \n\
129 Turn off the display.\n\
132 Disable the mouse click. Useful to automate the \n\
133 execution of this program without human intervention.\n\
136 Use Ogre3D for visibility tests\n\
139 When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\
142 Use the scanline for visibility tests.\n\
145 Compute covariance matrix.\n\
148 Compute gradient projection error.\n\
151 Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (EdgeKlt)>).\n\
154 Print the help.\n\n", ext.c_str());
157 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
160 bool getOptions(
int argc,
const char **argv, std::string &ipath, std::string &configFile, std::string &modelFile,
161 std::string &initFile,
long &lastFrame,
bool &displayFeatures,
bool &click_allowed,
bool &display,
162 bool &cao3DModel,
bool &trackCylinder,
bool &useOgre,
bool &showOgreConfigDialog,
bool &useScanline,
163 bool &computeCovariance,
bool &projectionError,
int &trackerType)
171 lastFrame = atol(optarg_);
177 configFile = optarg_;
186 displayFeatures =
false;
192 click_allowed =
false;
198 trackCylinder =
false;
207 showOgreConfigDialog =
true;
210 computeCovariance =
true;
213 projectionError =
true;
216 trackerType = atoi(optarg_);
219 usage(argv[0],
nullptr);
224 usage(argv[0], optarg_);
230 if ((c == 1) || (c == -1)) {
232 usage(argv[0],
nullptr);
233 std::cerr <<
"ERROR: " << std::endl;
234 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
241 int main(
int argc,
const char **argv)
244 std::string env_ipath;
245 std::string opt_ipath;
247 std::string opt_configFile;
248 std::string opt_modelFile;
249 std::string modelFile;
250 std::string opt_initFile;
251 std::string initFile;
252 long opt_lastFrame = -1;
253 bool displayFeatures =
true;
254 bool opt_click_allowed =
true;
255 bool opt_display =
true;
256 bool cao3DModel =
false;
257 bool trackCylinder =
true;
258 bool useOgre =
false;
259 bool showOgreConfigDialog =
false;
260 bool useScanline =
false;
261 bool computeCovariance =
false;
262 bool projectionError =
false;
265 #if VISP_HAVE_DATASET_VERSION >= 0x030600
266 std::string ext(
"png");
268 std::string ext(
"pgm");
276 if (!env_ipath.empty())
280 if (!getOptions(argc, argv, opt_ipath, opt_configFile, opt_modelFile, opt_initFile, opt_lastFrame, displayFeatures,
281 opt_click_allowed, opt_display, cao3DModel, trackCylinder, useOgre, showOgreConfigDialog,
282 useScanline, computeCovariance, projectionError, trackerType)) {
287 if (opt_ipath.empty() && env_ipath.empty()) {
288 usage(argv[0],
nullptr);
289 std::cerr << std::endl <<
"ERROR:" << std::endl;
290 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
291 <<
" environment variable to specify the location of the " << std::endl
292 <<
" image path where test images are located." << std::endl
299 if (!opt_ipath.empty())
304 #if defined(VISP_HAVE_PUGIXML)
305 std::string configFile;
306 if (!opt_configFile.empty())
307 configFile = opt_configFile;
308 else if (!opt_ipath.empty())
314 if (!opt_modelFile.empty()) {
315 modelFile = opt_modelFile;
318 std::string modelFileCao;
319 std::string modelFileWrl;
321 modelFileCao =
"mbt/cube_and_cylinder.cao";
322 modelFileWrl =
"mbt/cube_and_cylinder.wrl";
325 modelFileCao =
"mbt/cube.cao";
326 modelFileWrl =
"mbt/cube.wrl";
329 if (!opt_ipath.empty()) {
334 #ifdef VISP_HAVE_COIN3D
337 std::cerr <<
"Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
347 #ifdef VISP_HAVE_COIN3D
350 std::cerr <<
"Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
357 if (!opt_initFile.empty())
358 initFile = opt_initFile;
359 else if (!opt_ipath.empty())
364 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
375 std::cerr <<
"Cannot open sequence: " << ipath << std::endl;
386 mapOfImages[
"Camera1"] = &I1;
387 mapOfImages[
"Camera2"] = &I2;
388 mapOfImages[
"Camera3"] = &I3;
391 #if defined(VISP_HAVE_X11)
392 vpDisplayX display1, display2, display3;
393 #elif defined(VISP_HAVE_GDI)
395 #elif defined(HAVE_OPENCV_HIGHGUI)
397 #elif defined(VISP_HAVE_D3D9)
399 #elif defined(VISP_HAVE_GTK)
406 #if defined(VISP_HAVE_DISPLAY)
411 display1.init(I1, 100, 100,
"Test tracking (Cam1)");
426 std::map<std::string, vpHomogeneousMatrix> mapOfCameraPoses;
427 std::map<std::string, vpCameraParameters> mapOfCameraParams;
430 #if defined(VISP_HAVE_PUGIXML)
432 std::map<std::string, std::string> mapOfConfigFiles;
433 mapOfConfigFiles[
"Camera1"] = configFile;
434 mapOfConfigFiles[
"Camera2"] = configFile;
435 mapOfConfigFiles[
"Camera3"] = configFile;
441 mapOfCameraParams[
"Camera1"] = cam;
442 mapOfCameraParams[
"Camera2"] = cam;
443 mapOfCameraParams[
"Camera3"] = cam;
454 std::map<std::string, vpMe> mapOfMe;
455 mapOfMe[
"Camera1"] = me;
456 mapOfMe[
"Camera2"] = me;
457 mapOfMe[
"Camera3"] = me;
459 #if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
468 std::map<std::string, vpKltOpencv> mapOfKlt;
469 mapOfKlt[
"Camera1"] = klt;
470 mapOfKlt[
"Camera2"] = klt;
471 mapOfKlt[
"Camera3"] = klt;
486 std::map<std::string, unsigned int> mapOfClippingFlags;
488 for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin(); it != mapOfClippingFlags.end();
520 if (opt_display && opt_click_allowed) {
537 if (opt_display && opt_click_allowed) {
538 std::map<std::string, std::string> mapOfInitFiles;
539 mapOfInitFiles[
"Camera1"] = initFile;
541 dynamic_cast<vpMbGenericTracker *
>(tracker)->initClick(mapOfImages, mapOfInitFiles,
true);
545 dynamic_cast<vpMbGenericTracker *
>(tracker)->display(mapOfImages, mapOfCameraPoses, mapOfCameraParams,
549 vpHomogeneousMatrix c1Moi(0.02044769891, 0.1101505452, 0.5078963719, 2.063603907, 1.110231561, -0.4392789872);
550 std::map<std::string, vpHomogeneousMatrix> mapOfInitPoses;
551 mapOfInitPoses[
"Camera1"] = c1Moi;
553 dynamic_cast<vpMbGenericTracker *
>(tracker)->initFromPose(mapOfImages, mapOfInitPoses);
566 bool quit =
false, click =
false;
567 while (!reader.
end() && !quit) {
572 mapOfImages[
"Camera1"] = &I1;
573 mapOfImages[
"Camera2"] = &I2;
574 mapOfImages[
"Camera3"] = &I3;
582 std::stringstream ss;
589 std::cout <<
"----------Test reset tracker----------" << std::endl;
597 #if defined(VISP_HAVE_PUGIXML)
602 mapOfCameraParams[
"Camera1"] = cam;
603 mapOfCameraParams[
"Camera2"] = cam;
604 mapOfCameraParams[
"Camera3"] = cam;
615 mapOfMe[
"Camera1"] = me;
616 mapOfMe[
"Camera2"] = me;
617 mapOfMe[
"Camera3"] = me;
619 #if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
628 mapOfKlt[
"Camera1"] = klt;
629 mapOfKlt[
"Camera2"] = klt;
630 mapOfKlt[
"Camera3"] = klt;
646 for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin();
647 it != mapOfClippingFlags.end(); ++it) {
662 dynamic_cast<vpMbGenericTracker *
>(tracker)->initFromPose(mapOfImages, mapOfCameraPoses);
668 c1Moi.
buildFrom(0.0439540832, 0.0845870108, 0.5477322481, 2.179498458, 0.8611798108, -0.3491961946);
669 std::map<std::string, vpHomogeneousMatrix> mapOfSetPoses;
670 mapOfSetPoses[
"Camera1"] = c1Moi;
672 std::cout <<
"Test set pose" << std::endl;
684 std::map<std::string, const vpImage<unsigned char> *> mapOfSubImages;
685 mapOfSubImages[
"Camera1"] = &I1;
686 mapOfSubImages[
"Camera2"] = &I2;
688 dynamic_cast<vpMbGenericTracker *
>(tracker)->display(mapOfSubImages, mapOfCameraPoses, mapOfCameraParams,
692 dynamic_cast<vpMbGenericTracker *
>(tracker)->display(mapOfImages, mapOfCameraPoses, mapOfCameraParams,
702 if (opt_click_allowed && opt_display) {
721 if (computeCovariance) {
722 std::cout <<
"Covariance matrix: \n" << tracker->
getCovarianceMatrix() << std::endl << std::endl;
725 if (projectionError) {
726 std::cout <<
"Projection error: " << tracker->
getProjectionError() << std::endl << std::endl;
736 std::cout <<
"Reached last frame: " << reader.
getFrameIndex() << std::endl;
737 std::cout <<
"\nFinal poses, c1Mo:\n"
738 << mapOfCameraPoses[
"Camera1"] <<
"\nc2Mo:\n"
739 << mapOfCameraPoses[
"Camera2"] <<
"\nc3Mo:\n"
740 << mapOfCameraPoses[
"Camera3"] << std::endl;
742 if (opt_click_allowed && !quit) {
753 std::cout <<
"Catch an exception: " << e << std::endl;
758 #elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY))
761 std::cout <<
"Cannot run this example: visp_mbt, visp_gui modules are required." << std::endl;
767 std::cout <<
"Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
Generic class defining intrinsic camera parameters.
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
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...
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()
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.
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpHomogeneousMatrix & buildFrom(const vpTranslationVector &t, const vpRotationMatrix &R)
unsigned int getWidth() const
unsigned int getHeight() const
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
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)
Real-time 6D object pose tracking using its CAD model.
Main methods for a model-based tracker.
virtual void resetTracker()=0
virtual void setOgreShowConfigDialog(bool showConfigDialog)
virtual void setDisplayFeatures(bool displayF)
virtual void setAngleDisappear(const double &a)
virtual void setCovarianceComputation(const bool &flag)
virtual void setScanLineVisibilityTest(const bool &v)
virtual void setOgreVisibilityTest(const bool &v)
virtual vpMatrix getCovarianceMatrix() const
virtual void setNearClippingDistance(const double &dist)
virtual void setFarClippingDistance(const double &dist)
virtual double getProjectionError() const
virtual void setProjectionErrorComputation(const bool &flag)
virtual void loadModel(const std::string &modelFile, bool verbose=false, const vpHomogeneousMatrix &T=vpHomogeneousMatrix())
virtual void setAngleAppear(const double &a)
void setMu1(const double &mu_1)
void setRange(const unsigned int &range)
void setLikelihoodThresholdType(const vpLikelihoodThresholdType likelihood_threshold_type)
void setMaskNumber(const unsigned int &mask_number)
void setThreshold(const double &threshold)
void setSampleStep(const double &sample_step)
void setMaskSize(const unsigned int &mask_size)
void setMu2(const double &mu_2)
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 acquire(vpImage< vpRGBa > &I)
void setLastFrameIndex(const long last_frame)
void open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
long getFirstFrameIndex()
long getFrameIndex() const