44 #include <visp3/core/vpConfig.h> 46 #if defined(VISP_HAVE_MODULE_MBT) 48 #include <visp3/core/vpIoTools.h> 49 #include <visp3/io/vpParseArgv.h> 50 #include <visp3/io/vpImageIo.h> 51 #include <visp3/gui/vpDisplayX.h> 52 #include <visp3/gui/vpDisplayGDI.h> 53 #include <visp3/gui/vpDisplayOpenCV.h> 54 #include <visp3/gui/vpDisplayD3D.h> 55 #include <visp3/gui/vpDisplayGTK.h> 56 #include <visp3/mbt/vpMbGenericTracker.h> 58 #define GETOPTARGS "i:dclt:e:Dmh" 62 void usage(
const char *name,
const char *badparam)
65 Regression test for vpGenericTracker.\n\ 68 %s [-i <test image path>] [-c] [-d] [-h] [-l] \n\ 69 [-t <tracker type>] [-e <last frame index>] [-D] [-m]\n", name);
73 -i <input image path> \n\ 74 Set image input path.\n\ 75 These images come from ViSP-images-x.y.z.tar.gz available \n\ 76 on the ViSP website.\n\ 77 Setting the VISP_INPUT_IMAGE_PATH environment\n\ 78 variable produces the same behavior than using\n\ 82 Turn off the display.\n\ 85 Disable the mouse click. Useful to automate the \n\ 86 execution of this program without human intervention.\n\ 89 Set tracker type (<1 (Edge)>, <2 (KLT)>, <3 (both)>) for color sensor.\n\ 92 Use the scanline for visibility tests.\n\ 94 -e <last frame index>\n\ 95 Specify the index of the last frame. Once reached, the tracking is stopped.\n\ 101 Set a tracking mask.\n\ 104 Print the help.\n\n");
107 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
110 bool getOptions(
int argc,
const char **argv, std::string &ipath,
bool &click_allowed,
bool &display,
111 bool &useScanline,
int &trackerType,
int &lastFrame,
bool &use_depth,
bool &use_mask)
122 click_allowed =
false;
131 trackerType = atoi(optarg_);
134 lastFrame = atoi(optarg_);
143 usage(argv[0], NULL);
148 usage(argv[0], optarg_);
154 if ((c == 1) || (c == -1)) {
156 usage(argv[0], NULL);
157 std::cerr <<
"ERROR: " << std::endl;
158 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
165 bool read_data(
const std::string &input_directory,
const int cpt,
const vpCameraParameters &cam_depth,
170 sprintf(buffer, std::string(input_directory +
"/Images/Image_%04d.pgm").c_str(), cpt);
171 std::string image_filename = buffer;
173 sprintf(buffer, std::string(input_directory +
"/Depth/Depth_%04d.bin").c_str(), cpt);
174 std::string depth_filename = buffer;
176 sprintf(buffer, std::string(input_directory +
"/CameraPose/Camera_%03d.txt").c_str(), cpt);
177 std::string pose_filename = buffer;
185 unsigned int depth_width = 0, depth_height = 0;
186 std::ifstream file_depth(depth_filename.c_str(), std::ios::in | std::ios::binary);
187 if (!file_depth.is_open())
192 I_depth.
resize(depth_height, depth_width);
193 pointcloud.resize(depth_height*depth_width);
195 const float depth_scale = 0.000030518f;
196 for (
unsigned int i = 0; i < I_depth.
getHeight(); i++) {
197 for (
unsigned int j = 0; j < I_depth.
getWidth(); j++) {
199 double x = 0.0, y = 0.0, Z = I_depth[i][j] * depth_scale;
205 pointcloud[i*I_depth.
getWidth()+j] = pt3d;
209 std::ifstream file_pose(pose_filename.c_str());
210 if (!file_pose.is_open()) {
214 for (
unsigned int i = 0; i < 4; i++) {
215 for (
unsigned int j = 0; j < 4; j++) {
216 file_pose >> cMo[i][j];
224 int main(
int argc,
const char *argv[])
227 std::string env_ipath;
228 std::string opt_ipath =
"";
229 bool opt_click_allowed =
true;
230 bool opt_display =
true;
231 bool useScanline =
false;
233 #if defined(__mips__) || defined(__mips) || defined(mips) || defined(__MIPS__) 235 int opt_lastFrame = 5;
237 int opt_lastFrame = -1;
239 bool use_depth =
false;
240 bool use_mask =
false;
247 if (!getOptions(argc, argv, opt_ipath, opt_click_allowed, opt_display,
248 useScanline, trackerType_image, opt_lastFrame, use_depth,
253 std::cout <<
"trackerType_image: " << trackerType_image << std::endl;
254 std::cout <<
"useScanline: " << useScanline << std::endl;
255 std::cout <<
"use_depth: " << use_depth << std::endl;
256 std::cout <<
"use_mask: " << use_mask << std::endl;
257 #ifdef VISP_HAVE_COIN3D 258 std::cout <<
"COIN3D available." << std::endl;
261 #if !defined(VISP_HAVE_MODULE_KLT) || (!defined(VISP_HAVE_OPENCV) || (VISP_HAVE_OPENCV_VERSION < 0x020100)) 262 if (trackerType_image & 2) {
263 std::cout <<
"KLT features cannot be used: ViSP is not built with " 264 "KLT module or OpenCV is not available.\nTest is not run." 271 if (opt_ipath.empty() && env_ipath.empty()) {
272 usage(argv[0], NULL);
273 std::cerr << std::endl <<
"ERROR:" << std::endl;
274 std::cerr <<
" Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
275 <<
" environment variable to specify the location of the " << std::endl
276 <<
" image path where test images are located." << std::endl
282 std::string input_directory =
vpIoTools::createFilePath(!opt_ipath.empty() ? opt_ipath : env_ipath,
"mbt-depth/Castle-simu");
284 std::cerr <<
"ViSP-images does not contain the folder: " << input_directory <<
"!" << std::endl;
289 #if defined VISP_HAVE_X11 291 #elif defined VISP_HAVE_GDI 293 #elif defined VISP_HAVE_OPENCV 295 #elif defined VISP_HAVE_D3D9 297 #elif defined VISP_HAVE_GTK 303 std::vector<int> tracker_type(2);
304 tracker_type[0] = trackerType_image;
307 #if defined(VISP_HAVE_XML2) 308 tracker.loadConfigFile(input_directory +
"/Config/chateau.xml", input_directory +
"/Config/chateau_depth.xml");
314 tracker.setCameraParameters(cam_color, cam_depth);
326 tracker.setMovingEdge(me);
329 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 331 tracker.setKltMaskBorder(5);
340 tracker.setKltOpencv(klt);
345 tracker.setDepthNormalPclPlaneEstimationMethod(2);
346 tracker.setDepthNormalPclPlaneEstimationRansacMaxIter(200);
347 tracker.setDepthNormalPclPlaneEstimationRansacThreshold(0.001);
348 tracker.setDepthNormalSamplingStep(2, 2);
350 tracker.setDepthDenseSamplingStep(4, 4);
354 tracker.setNearClippingDistance(0.01);
355 tracker.setFarClippingDistance(2.0);
359 #ifdef VISP_HAVE_COIN3D 360 tracker.loadModel(input_directory +
"/Models/chateau.wrl", input_directory +
"/Models/chateau.cao");
362 tracker.loadModel(input_directory +
"/Models/chateau.cao", input_directory +
"/Models/chateau.cao");
373 tracker.loadModel(input_directory +
"/Models/cube.cao",
false, T);
375 tracker.getCameraParameters(cam_color, cam_depth);
376 tracker.setDisplayFeatures(
true);
377 tracker.setScanLineVisibilityTest(useScanline);
379 std::map<int, std::pair<double, double> > map_thresh;
381 #ifdef VISP_HAVE_COIN3D 383 = useScanline ? std::pair<double, double>(0.005, 3.9) :
std::pair<double, double>(0.007, 2.9);
384 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 386 = useScanline ? std::pair<double, double>(0.006, 1.9) :
std::pair<double, double>(0.005, 1.3);
388 = useScanline ? std::pair<double, double>(0.005, 3.2) :
std::pair<double, double>(0.006, 2.8);
391 = useScanline ? std::pair<double, double>(0.003, 1.7) :
std::pair<double, double>(0.002, 0.8);
392 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 394 = std::pair<double, double>(0.002, 0.3);
396 = useScanline ? std::pair<double, double>(0.002, 1.8) :
std::pair<double, double>(0.002, 0.7);
400 = useScanline ? std::pair<double, double>(0.007, 2.3) :
std::pair<double, double>(0.007, 2.1);
401 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 403 = useScanline ? std::pair<double, double>(0.006, 1.7) :
std::pair<double, double>(0.005, 1.4);
405 = useScanline ? std::pair<double, double>(0.004, 1.2) :
std::pair<double, double>(0.004, 1.0);
408 = useScanline ? std::pair<double, double>(0.002, 0.7) :
std::pair<double, double>(0.001, 0.4);
409 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 411 = std::pair<double, double>(0.002, 0.3);
413 = useScanline ? std::pair<double, double>(0.001, 0.5) :
std::pair<double, double>(0.001, 0.4);
420 std::vector<vpColVector> pointcloud;
422 if (!read_data(input_directory, cpt_frame, cam_depth, I, I_depth_raw, pointcloud, cMo_truth)) {
423 std::cerr <<
"Cannot read first frame!" << std::endl;
428 const double roi_step = 7.0;
429 const double roi_step2 = 6.0;
432 for (
unsigned int i = (
unsigned int) (I.
getRows()/roi_step); i < (
unsigned int) (I.
getRows()*roi_step2/roi_step); i++) {
433 for (
unsigned int j = (
unsigned int) (I.
getCols()/roi_step); j < (
unsigned int) (I.
getCols()*roi_step2/roi_step); j++) {
437 tracker.setMask(mask);
442 #ifdef VISP_HAVE_DISPLAY 443 display1.
init(I, 0, 0,
"Image");
449 depth_M_color[0][3] = -0.05;
450 tracker.setCameraTransformationMatrix(
"Camera2", depth_M_color);
451 tracker.initFromPose(I, cMo_truth);
453 bool click =
false, quit =
false;
454 std::vector<double> vec_err_t, vec_err_tu;
455 std::vector<double> time_vec;
456 while (read_data(input_directory, cpt_frame, cam_depth, I, I_depth_raw, pointcloud, cMo_truth) && !quit
457 && (opt_lastFrame > 0 ? (
int)cpt_frame <= opt_lastFrame :
true)) {
466 std::map<std::string, const vpImage<unsigned char> *> mapOfImages;
467 mapOfImages[
"Camera1"] = &I;
468 std::map<std::string, const std::vector<vpColVector> *> mapOfPointclouds;
469 mapOfPointclouds[
"Camera2"] = &pointcloud;
470 std::map<std::string, unsigned int> mapOfWidths, mapOfHeights;
472 mapOfWidths[
"Camera2"] = 0;
473 mapOfHeights[
"Camera2"] = 0;
475 mapOfWidths[
"Camera2"] = I_depth.
getWidth();
476 mapOfHeights[
"Camera2"] = I_depth.
getHeight();
479 tracker.track(mapOfImages, mapOfPointclouds, mapOfWidths, mapOfHeights);
482 time_vec.push_back(t);
485 tracker.display(I, I_depth, cMo, depth_M_color*cMo, cam_color, cam_depth,
vpColor::red, 3);
489 std::stringstream ss;
490 ss <<
"Frame: " << cpt_frame;
493 ss <<
"Nb features: " << tracker.getError().getRows();
501 for (
int i = 0; i < 3; i++) {
502 t_est[i] = pose_est[i];
503 t_truth[i] = pose_truth[i];
504 tu_est[i] = pose_est[i+3];
505 tu_truth[i] = pose_truth[i+3];
508 vpColVector t_err = t_truth-t_est, tu_err = tu_truth-tu_est;
512 vec_err_t.push_back( t_err2 );
513 vec_err_tu.push_back( tu_err2 );
514 if ( !use_mask && (t_err2 > t_thresh || tu_err2 > tu_thresh) ) {
515 std::cerr <<
"Pose estimated exceeds the threshold (t_thresh = " << t_thresh <<
" ; tu_thresh = " << tu_thresh <<
")!" << std::endl;
516 std::cout <<
"t_err: " << t_err2 <<
" ; tu_err: " << tu_err2 << std::endl;
532 if (opt_display && opt_click_allowed) {
553 if (!time_vec.empty())
557 if (!vec_err_t.empty())
558 std::cout <<
"Max translation error: " << *std::max_element(vec_err_t.begin(), vec_err_t.end()) << std::endl;
560 if (!vec_err_tu.empty())
561 std::cout <<
"Max thetau error: " << *std::max_element(vec_err_tu.begin(), vec_err_tu.end()) << std::endl;
563 #if defined(VISP_HAVE_XML2) 569 #if defined(VISP_HAVE_COIN3D) && (COIN_MAJOR_VERSION == 2 || COIN_MAJOR_VERSION == 3) 576 std::cout <<
"Catch an exception: " << e << std::endl;
582 std::cout <<
"Enable MBT module (VISP_HAVE_MODULE_MBT) to launch this test." << std::endl;
unsigned int getCols() const
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static double getStdev(const std::vector< double > &v, const bool useBesselCorrection=false)
void setHarrisFreeParameter(double harris_k)
unsigned int getWidth() const
Implementation of an homogeneous matrix and operations on such kind of matrices.
void setMaskNumber(const unsigned int &a)
static double getMedian(const std::vector< double > &v)
Display for windows using GDI (available on any windows 32 platform).
void setMaxFeatures(const int maxCount)
void setSampleStep(const double &s)
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...
static const vpColor none
void setMinDistance(double minDistance)
error that can be emited by ViSP classes.
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Real-time 6D object pose tracking using its CAD model.
static void flush(const vpImage< unsigned char > &I)
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)
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
static double getMean(const std::vector< double > &v)
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
unsigned int getRows() const
void setMaskSize(const unsigned int &a)
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.
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
void setPyramidLevels(const int pyrMaxLevel)
static double rad(double deg)
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
void setMu2(const double &mu_2)
void setWindowSize(const int winSize)
static double deg(double rad)
static void read(vpImage< unsigned char > &I, const std::string &filename)
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))
Implementation of a pose vector and operations on poses.
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
void setBlockSize(const int blockSize)
void setThreshold(const double &t)
unsigned int getHeight() const
Defines a rectangle in the plane.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void setRange(const unsigned int &r)
static const vpColor yellow
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)