Example of tracking with vpGenericTracker on an image sequence containing a cube.
#include <iostream>
#include <visp3/core/vpConfig.h>
#if (defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY)) && \
(defined(VISP_HAVE_LAPACK) || defined(VISP_HAVE_EIGEN3) || defined(VISP_HAVE_OPENCV))
#include <visp3/core/vpDebug.h>
#include <visp3/core/vpHomogeneousMatrix.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/core/vpMath.h>
#include <visp3/gui/vpDisplayD3D.h>
#include <visp3/gui/vpDisplayGDI.h>
#include <visp3/gui/vpDisplayGTK.h>
#include <visp3/gui/vpDisplayOpenCV.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/io/vpImageIo.h>
#include <visp3/io/vpParseArgv.h>
#include <visp3/io/vpVideoReader.h>
#include <visp3/mbt/vpMbGenericTracker.h>
#define GETOPTARGS "x:m:i:n:de:chtfColwvpT:"
#ifdef ENABLE_VISP_NAMESPACE
#endif
void usage(const char *name, const char *badparam)
{
#if VISP_HAVE_DATASET_VERSION >= 0x030600
std::string ext("png");
#else
std::string ext("pgm");
#endif
fprintf(stdout, "\n\
Example of tracking based on the 3D model.\n\
\n\
SYNOPSIS\n\
%s [-i <test image path>] [-x <config file>]\n\
[-m <model name>] [-n <initialisation file base name>] [-e <last frame index>]\n\
[-t] [-c] [-d] [-h] [-f] [-C] [-o] [-w] [-l] [-v] [-p]\n\
[-T <tracker type>]\n",
name);
fprintf(stdout, "\n\
OPTIONS: \n\
-i <input image path> \n\
Set image input path.\n\
From this path read images \n\
\"mbt/cube/image%%04d.%s\". These \n\
images come from visp-images-x.y.z.tar.gz available \n\
on the ViSP website.\n\
Setting the VISP_INPUT_IMAGE_PATH environment\n\
variable produces the same behavior than using\n\
this option.\n\
\n\
-x <config file> \n\
Set the config file (the xml file) to use.\n\
The config file is used to specify the parameters of the tracker.\n\
\n\
-m <model name> \n\
Specify the name of the file of the model\n\
The model can either be a vrml model (.wrl) or a .cao file.\n\
\n\
-e <last frame index> \n\
Specify the index of the last frame. Once reached, the tracking is stopped\n\
\n\
-f \n\
Do not use the vrml model, use the .cao one. These two models are \n\
equivalent and comes from ViSP-images-x.y.z.tar.gz available on the ViSP\n\
website. However, the .cao model allows to use the 3d model based tracker \n\
without Coin.\n\
\n\
-C \n\
Track only the cube (not the cylinder). In this case the models files are\n\
cube.cao or cube.wrl instead of cube_and_cylinder.cao and \n\
cube_and_cylinder.wrl.\n\
\n\
-n <initialisation file base name> \n\
Base name of the initialisation file. The file will be 'base_name'.init .\n\
This base name is also used for the optional picture specifying where to \n\
click (a .ppm picture).\n\
\n\
-t \n\
Turn off the display of the the moving edges and Klt points. \n\
\n\
-d \n\
Turn off the display.\n\
\n\
-c\n\
Disable the mouse click. Useful to automate the \n\
execution of this program without human intervention.\n\
\n\
-o\n\
Use Ogre3D for visibility tests\n\
\n\
-w\n\
When Ogre3D is enable [-o] show Ogre3D configuration dialog that allows to set the renderer.\n\
\n\
-l\n\
Use the scanline for visibility tests.\n\
\n\
-v\n\
Compute covariance matrix.\n\
\n\
-p\n\
Compute gradient projection error.\n\
\n\
-T <tracker type>\n\
Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (EdgeKlt)>).\n\
\n\
-h \n\
Print the help.\n\n", ext.c_str());
if (badparam)
fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
}
bool getOptions(int argc, const char **argv, std::string &ipath, std::string &configFile, std::string &modelFile,
std::string &initFile, long &lastFrame, bool &displayFeatures, bool &click_allowed, bool &display,
bool &cao3DModel, bool &trackCylinder, bool &useOgre, bool &showOgreConfigDialog, bool &useScanline,
bool &computeCovariance, bool &projectionError, int &trackerType)
{
const char *optarg_;
int c;
switch (c) {
case 'e':
lastFrame = atol(optarg_);
break;
case 'i':
ipath = optarg_;
break;
case 'x':
configFile = optarg_;
break;
case 'm':
modelFile = optarg_;
break;
case 'n':
initFile = optarg_;
break;
case 't':
displayFeatures = false;
break;
case 'f':
cao3DModel = true;
break;
case 'c':
click_allowed = false;
break;
case 'd':
display = false;
break;
case 'C':
trackCylinder = false;
break;
case 'o':
useOgre = true;
break;
case 'l':
useScanline = true;
break;
case 'w':
showOgreConfigDialog = true;
break;
case 'v':
computeCovariance = true;
break;
case 'p':
projectionError = true;
break;
case 'T':
trackerType = atoi(optarg_);
break;
case 'h':
usage(argv[0], nullptr);
return false;
break;
default:
usage(argv[0], optarg_);
return false;
break;
}
}
if ((c == 1) || (c == -1)) {
usage(argv[0], nullptr);
std::cerr << "ERROR: " << std::endl;
std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
return false;
}
return true;
}
int main(int argc, const char **argv)
{
try {
std::string env_ipath;
std::string opt_ipath;
std::string ipath;
std::string opt_configFile;
std::string opt_modelFile;
std::string modelFile;
std::string opt_initFile;
std::string initFile;
long opt_lastFrame = -1;
bool displayFeatures = true;
bool opt_click_allowed = true;
bool opt_display = true;
bool cao3DModel = false;
bool trackCylinder = true;
bool useOgre = false;
bool showOgreConfigDialog = false;
bool useScanline = false;
bool computeCovariance = false;
bool projectionError = false;
#if VISP_HAVE_DATASET_VERSION >= 0x030600
std::string ext("png");
#else
std::string ext("pgm");
#endif
if (!env_ipath.empty())
ipath = env_ipath;
if (!getOptions(argc, argv, opt_ipath, opt_configFile, opt_modelFile, opt_initFile, opt_lastFrame, displayFeatures,
opt_click_allowed, opt_display, cao3DModel, trackCylinder, useOgre, showOgreConfigDialog,
useScanline, computeCovariance, projectionError, trackerType)) {
return EXIT_FAILURE;
}
if (opt_ipath.empty() && env_ipath.empty()) {
usage(argv[0], nullptr);
std::cerr << std::endl << "ERROR:" << std::endl;
std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
<< " environment variable to specify the location of the " << std::endl
<< " image path where test images are located." << std::endl
<< std::endl;
return EXIT_FAILURE;
}
if (!opt_ipath.empty())
else
#if defined(VISP_HAVE_PUGIXML)
std::string configFile;
if (!opt_configFile.empty())
configFile = opt_configFile;
else if (!opt_ipath.empty())
else
#endif
if (!opt_modelFile.empty()) {
modelFile = opt_modelFile;
}
else {
std::string modelFileCao;
std::string modelFileWrl;
if (trackCylinder) {
modelFileCao = "mbt/cube_and_cylinder.cao";
modelFileWrl = "mbt/cube_and_cylinder.wrl";
}
else {
modelFileCao = "mbt/cube.cao";
modelFileWrl = "mbt/cube.wrl";
}
if (!opt_ipath.empty()) {
if (cao3DModel) {
}
else {
#ifdef VISP_HAVE_COIN3D
#else
std::cerr << "Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
#endif
}
}
else {
if (cao3DModel) {
}
else {
#ifdef VISP_HAVE_COIN3D
#else
std::cerr << "Coin is not detected in ViSP. Use the .cao model instead." << std::endl;
#endif
}
}
}
if (!opt_initFile.empty())
initFile = opt_initFile;
else if (!opt_ipath.empty())
else
std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
try {
I2 = I1;
I3 = I1;
}
catch (...) {
std::cerr << "Cannot open sequence: " << ipath << std::endl;
return EXIT_FAILURE;
}
I2 = I1;
I3 = I1;
mapOfImages["Camera1"] = &I1;
mapOfImages["Camera2"] = &I2;
mapOfImages["Camera3"] = &I3;
#if defined(VISP_HAVE_X11)
vpDisplayX display1, display2, display3;
#elif defined(VISP_HAVE_GDI)
#elif defined(HAVE_OPENCV_HIGHGUI)
#elif defined(VISP_HAVE_D3D9)
#elif defined(VISP_HAVE_GTK)
#else
opt_display = false;
#endif
if (opt_display) {
#if defined(VISP_HAVE_DISPLAY)
display1.init(I1, 100, 100, "Test tracking (Cam1)");
#endif
}
std::map<std::string, vpHomogeneousMatrix> mapOfCameraPoses;
std::map<std::string, vpCameraParameters> mapOfCameraParams;
#if defined(VISP_HAVE_PUGIXML)
std::map<std::string, std::string> mapOfConfigFiles;
mapOfConfigFiles["Camera1"] = configFile;
mapOfConfigFiles["Camera2"] = configFile;
mapOfConfigFiles["Camera3"] = configFile;
#else
mapOfCameraParams["Camera1"] = cam;
mapOfCameraParams["Camera2"] = cam;
mapOfCameraParams["Camera3"] = cam;
std::map<std::string, vpMe> mapOfMe;
mapOfMe["Camera1"] = me;
mapOfMe["Camera2"] = me;
mapOfMe["Camera3"] = me;
#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
std::map<std::string, vpKltOpencv> mapOfKlt;
mapOfKlt["Camera1"] = klt;
mapOfKlt["Camera2"] = klt;
mapOfKlt["Camera3"] = klt;
#endif
std::map<std::string, unsigned int> mapOfClippingFlags;
for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin(); it != mapOfClippingFlags.end();
++it) {
}
#endif
if (useOgre)
if (opt_display && opt_click_allowed) {
}
}
if (opt_display && opt_click_allowed) {
std::map<std::string, std::string> mapOfInitFiles;
mapOfInitFiles["Camera1"] = initFile;
dynamic_cast<vpMbGenericTracker *
>(tracker)->initClick(mapOfImages, mapOfInitFiles,
true);
dynamic_cast<vpMbGenericTracker *
>(tracker)->display(mapOfImages, mapOfCameraPoses, mapOfCameraParams,
}
else {
vpHomogeneousMatrix c1Moi(0.02044769891, 0.1101505452, 0.5078963719, 2.063603907, 1.110231561, -0.4392789872);
std::map<std::string, vpHomogeneousMatrix> mapOfInitPoses;
mapOfInitPoses["Camera1"] = c1Moi;
}
if (opt_display) {
}
bool quit = false, click = false;
while (!reader.
end() && !quit) {
I2 = I1;
I3 = I1;
mapOfImages["Camera1"] = &I1;
mapOfImages["Camera2"] = &I2;
mapOfImages["Camera3"] = &I3;
if (opt_display) {
std::stringstream ss;
}
std::cout << "----------Test reset tracker----------" << std::endl;
if (opt_display) {
}
#if defined(VISP_HAVE_PUGIXML)
#else
mapOfCameraParams["Camera1"] = cam;
mapOfCameraParams["Camera2"] = cam;
mapOfCameraParams["Camera3"] = cam;
mapOfMe["Camera1"] = me;
mapOfMe["Camera2"] = me;
mapOfMe["Camera3"] = me;
#if defined(VISP_HAVE_MODULE_KLT) && defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_VIDEO)
mapOfKlt["Camera1"] = klt;
mapOfKlt["Camera2"] = klt;
mapOfKlt["Camera3"] = klt;
#endif
for (std::map<std::string, unsigned int>::iterator it = mapOfClippingFlags.begin();
it != mapOfClippingFlags.end(); ++it) {
}
#endif
}
c1Moi.
buildFrom(0.0439540832, 0.0845870108, 0.5477322481, 2.179498458, 0.8611798108, -0.3491961946);
std::map<std::string, vpHomogeneousMatrix> mapOfSetPoses;
mapOfSetPoses["Camera1"] = c1Moi;
std::cout << "Test set pose" << std::endl;
}
if (opt_display) {
std::map<std::string, const vpImage<unsigned char> *> mapOfSubImages;
mapOfSubImages["Camera1"] = &I1;
mapOfSubImages["Camera2"] = &I2;
dynamic_cast<vpMbGenericTracker *
>(tracker)->display(mapOfSubImages, mapOfCameraPoses, mapOfCameraParams,
}
else {
dynamic_cast<vpMbGenericTracker *
>(tracker)->display(mapOfImages, mapOfCameraPoses, mapOfCameraParams,
}
}
}
if (opt_click_allowed && opt_display) {
switch (button) {
quit = !click;
break;
click = !click;
break;
default:
break;
}
}
}
if (computeCovariance) {
std::cout <<
"Covariance matrix: \n" << tracker->
getCovarianceMatrix() << std::endl << std::endl;
}
if (projectionError) {
std::cout <<
"Projection error: " << tracker->
getProjectionError() << std::endl << std::endl;
}
if (opt_display) {
}
}
std::cout <<
"Reached last frame: " << reader.
getFrameIndex() << std::endl;
std::cout << "\nFinal poses, c1Mo:\n"
<< mapOfCameraPoses["Camera1"] << "\nc2Mo:\n"
<< mapOfCameraPoses["Camera2"] << "\nc3Mo:\n"
<< mapOfCameraPoses["Camera3"] << std::endl;
if (opt_click_allowed && !quit) {
}
delete tracker;
tracker = nullptr;
return EXIT_SUCCESS;
}
std::cout << "Catch an exception: " << e << std::endl;
return EXIT_FAILURE;
}
}
#elif !(defined(VISP_HAVE_MODULE_MBT) && defined(VISP_HAVE_DISPLAY))
int main()
{
std::cout << "Cannot run this example: visp_mbt, visp_gui modules are required." << std::endl;
return EXIT_SUCCESS;
}
#else
int main()
{
std::cout << "Cannot run this example: install Lapack, Eigen3 or OpenCV" << std::endl;
return EXIT_SUCCESS;
}
#endif
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