Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
trackMeLine.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Tracking of a line.
33  *
34  * Authors:
35  * Eric Marchand
36  * Fabien Spindler
37  *
38  *****************************************************************************/
51 #include <visp3/core/vpConfig.h>
52 #include <visp3/core/vpDebug.h>
53 
54 #include <iomanip>
55 #include <sstream>
56 #include <stdio.h>
57 #include <stdlib.h>
58 
59 #if defined(VISP_HAVE_MODULE_ME) && \
60  (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
61 
62 #include <visp3/core/vpColor.h>
63 #include <visp3/core/vpImage.h>
64 #include <visp3/core/vpImagePoint.h>
65 #include <visp3/gui/vpDisplayGDI.h>
66 #include <visp3/gui/vpDisplayGTK.h>
67 #include <visp3/gui/vpDisplayOpenCV.h>
68 #include <visp3/gui/vpDisplayX.h>
69 #include <visp3/io/vpImageIo.h>
70 
71 #include <visp3/me/vpMeLine.h>
72 
73 #include <visp3/visual_features/vpFeatureBuilder.h>
74 #include <visp3/visual_features/vpFeatureLine.h>
75 
76 #include <visp3/core/vpIoTools.h>
77 #include <visp3/io/vpParseArgv.h>
78 
79 // List of allowed command line options
80 #define GETOPTARGS "cdi:h"
81 
82 void usage(const char *name, const char *badparam, std::string ipath);
83 bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display);
84 
94 void usage(const char *name, const char *badparam, std::string ipath)
95 {
96  fprintf(stdout, "\n\
97 Tracking of a line.\n\
98 \n\
99 SYNOPSIS\n\
100  %s [-i <input image path>] [-c] [-d] [-h]\n", name);
101 
102  fprintf(stdout, "\n\
103 OPTIONS: Default\n\
104  -i <input image path> %s\n\
105  Set image input path.\n\
106  From this path read \"line/image.%%04d.pgm\"\n\
107  images. \n\
108  Setting the VISP_INPUT_IMAGE_PATH environment\n\
109  variable produces the same behaviour than using\n\
110  this option.\n\
111 \n\
112  -c\n\
113  Disable the mouse click. Useful to automaze the \n\
114  execution of this program without humain intervention.\n\
115 \n\
116  -d \n\
117  Turn off the display.\n\
118 \n\
119  -h\n\
120  Print the help.\n", ipath.c_str());
121 
122  if (badparam)
123  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
124 }
138 bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display)
139 {
140  const char *optarg_;
141  int c;
142  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
143 
144  switch (c) {
145  case 'c':
146  click_allowed = false;
147  break;
148  case 'd':
149  display = false;
150  break;
151  case 'i':
152  ipath = optarg_;
153  break;
154  case 'h':
155  usage(argv[0], NULL, ipath);
156  return false;
157  break;
158 
159  default:
160  usage(argv[0], optarg_, ipath);
161  return false;
162  break;
163  }
164  }
165 
166  if ((c == 1) || (c == -1)) {
167  // standalone param or error
168  usage(argv[0], NULL, ipath);
169  std::cerr << "ERROR: " << std::endl;
170  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
171  return false;
172  }
173 
174  return true;
175 }
176 
177 int main(int argc, const char **argv)
178 {
179  try {
180  std::string env_ipath;
181  std::string opt_ipath;
182  std::string ipath;
183  std::string dirname;
184  std::string filename;
185  bool opt_click_allowed = true;
186  bool opt_display = true;
187 
188  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
189  // environment variable value
190  env_ipath = vpIoTools::getViSPImagesDataPath();
191 
192  // Set the default input path
193  if (!env_ipath.empty())
194  ipath = env_ipath;
195 
196  // Read the command line options
197  if (getOptions(argc, argv, opt_ipath, opt_click_allowed, opt_display) == false) {
198  exit(-1);
199  }
200 
201  // Get the option values
202  if (!opt_ipath.empty())
203  ipath = opt_ipath;
204 
205  // Compare ipath and env_ipath. If they differ, we take into account
206  // the input path comming from the command line option
207  if (!opt_ipath.empty() && !env_ipath.empty()) {
208  if (ipath != env_ipath) {
209  std::cout << std::endl << "WARNING: " << std::endl;
210  std::cout << " Since -i <visp image path=" << ipath << "> "
211  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
212  << " we skip the environment variable." << std::endl;
213  }
214  }
215 
216  // Test if an input path is set
217  if (opt_ipath.empty() && env_ipath.empty()) {
218  usage(argv[0], NULL, ipath);
219  std::cerr << std::endl << "ERROR:" << std::endl;
220  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
221  << " environment variable to specify the location of the " << std::endl
222  << " image path where test images are located." << std::endl
223  << std::endl;
224  exit(-1);
225  }
226 
227  // Declare an image, this is a gray level image (unsigned char)
228  // it size is not defined yet, it will be defined when the image will
229  // read on the disk
231 
232  // Set the path location of the image sequence
233  dirname = vpIoTools::createFilePath(ipath, "line");
234 
235  // Build the name of the image file
236  unsigned int iter = 1; // Image number
237  std::ostringstream s;
238  s.setf(std::ios::right, std::ios::adjustfield);
239  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
240  filename = vpIoTools::createFilePath(dirname, s.str());
241 
242  // Read the PGM image named "filename" on the disk, and put the
243  // bitmap into the image structure I. I is initialized to the
244  // correct size
245  //
246  // exception readPGM may throw various exception if, for example,
247  // the file does not exist, or if the memory cannot be allocated
248  try {
249  vpCTRACE << "Load: " << filename << std::endl;
250 
251  vpImageIo::read(I, filename);
252  } catch (...) {
253  // an exception is throwned if an exception from readPGM has been
254  // catched here this will result in the end of the program Note that
255  // another error message has been printed from readPGM to give more
256  // information about the error
257  std::cerr << std::endl << "ERROR:" << std::endl;
258  std::cerr << " Cannot read " << filename << std::endl;
259  std::cerr << " Check your -i " << ipath << " option " << std::endl
260  << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl;
261  exit(-1);
262  }
263 
264 // We open a window using either X11, GTK or GDI.
265 #if defined VISP_HAVE_X11
266  vpDisplayX display;
267 #elif defined VISP_HAVE_GTK
268  vpDisplayGTK display;
269 #elif defined VISP_HAVE_GDI
270  vpDisplayGDI display;
271 #elif defined VISP_HAVE_OPENCV
272  vpDisplayOpenCV display;
273 #endif
274 
275  if (opt_display) {
276  // Display size is automatically defined by the image (I) size
277  display.init(I, 100, 100, "Display...");
278  // Display the image
279  // The image class has a member that specify a pointer toward
280  // the display that has been initialized in the display declaration
281  // therefore is is no longuer necessary to make a reference to the
282  // display variable.
284  vpDisplay::flush(I);
285  }
286 
287  vpMeLine L1;
288 
289  vpMe me;
290  me.setRange(15);
291  me.setPointsToTrack(160);
292  me.setThreshold(15000);
293 
294  L1.setMe(&me);
296 
297  if (opt_display && opt_click_allowed)
298  L1.initTracking(I);
299  else {
300  vpImagePoint ip1, ip2;
301  ip1.set_i(96);
302  ip1.set_j(191);
303  ip2.set_i(122);
304  ip2.set_j(211);
305  L1.initTracking(I, ip1, ip2);
306  }
307 
308  if (opt_display)
309  L1.display(I, vpColor::green);
310 
311  L1.track(I);
312  if (opt_display && opt_click_allowed) {
313  std::cout << "A click to continue..." << std::endl;
315  }
316  std::cout << "----------------------------------------------------------" << std::endl;
317 
318  vpFeatureLine l;
319 
320  vpCameraParameters cam;
321  vpImage<vpRGBa> Ic;
322  for (iter = 1; iter < 30; iter++) {
323  std::cout << "----------------------------------------------------------" << std::endl;
324  // set the new image name
325  s.str("");
326  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
327  filename = vpIoTools::createFilePath(dirname, s.str());
328  // read the image
329  vpImageIo::read(I, filename);
330  if (opt_display) {
331  // Display the image
333  }
334 
335  std::cout << "Tracking on image: " << filename << std::endl;
336  L1.track(I);
337 
338  vpTRACE("L1 : %f %f", L1.getRho(), vpMath::deg(L1.getTheta()));
339  vpFeatureBuilder::create(l, cam, L1);
340  vpTRACE("L1 : %f %f", l.getRho(), vpMath::deg(l.getTheta()));
341 
342  if (opt_display) {
343  L1.display(I, vpColor::green);
344  vpDisplay::flush(I);
345  if (opt_click_allowed) {
346  std::cout << "A click to continue..." << std::endl;
348  }
349  }
350  }
351  if (opt_display && opt_click_allowed) {
352  std::cout << "A click to exit..." << std::endl;
354  }
355  return EXIT_SUCCESS;
356  } catch (const vpException &e) {
357  std::cout << "Catch an exception: " << e << std::endl;
358  return EXIT_FAILURE;
359  }
360 }
361 
362 #else
363 #include <iostream>
364 
365 int main()
366 {
367  std::cout << "visp_me module or X11, GTK, GDI or OpenCV display "
368  "functionalities are required..."
369  << std::endl;
370  return EXIT_SUCCESS;
371 }
372 
373 #endif
double getTheta() const
Definition: vpMeLine.cpp:961
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1292
void setPointsToTrack(const int &n)
Definition: vpMe.h:264
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
double getRho() const
Definition: vpMeLine.cpp:956
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:150
double getRho() const
error that can be emited by ViSP classes.
Definition: vpException.h:71
void track(const vpImage< unsigned char > &Im)
Definition: vpMeLine.cpp:747
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Definition: vpMe.h:60
static const vpColor green
Definition: vpColor.h:182
static void flush(const vpImage< unsigned char > &I)
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
void display(const vpImage< unsigned char > &I, vpColor col)
Definition: vpMeLine.cpp:224
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1537
void set_i(double ii)
Definition: vpImagePoint.h:167
#define vpTRACE
Definition: vpDebug.h:416
void setDisplay(vpMeSite::vpMeSiteDisplayType select)
Definition: vpMeTracker.h:105
static void display(const vpImage< unsigned char > &I)
Class that tracks in an image a line moving edges.
Definition: vpMeLine.h:151
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Generic class defining intrinsic camera parameters.
Class that defines a 2D line visual feature which is composed by two parameters that are and ...
double getTheta() const
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:137
void initTracking(const vpImage< unsigned char > &I)
Definition: vpMeLine.cpp:236
void set_j(double jj)
Definition: vpImagePoint.h:178
static double deg(double rad)
Definition: vpMath.h:101
#define vpCTRACE
Definition: vpDebug.h:338
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:243
void setThreshold(const double &t)
Definition: vpMe.h:300
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
void setRange(const unsigned int &r)
Definition: vpMe.h:271
void setMe(vpMe *p_me)
Definition: vpMeTracker.h:145