Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
trackMeNurbs.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 nurbs.
33  *
34  * Authors:
35  * Nicolas Melchior
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
52 #include <visp3/core/vpConfig.h>
53 #include <visp3/core/vpDebug.h>
54 
55 #include <iomanip>
56 #include <sstream>
57 #include <stdio.h>
58 #include <stdlib.h>
59 
60 #if defined(VISP_HAVE_MODULE_ME) && \
61  (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV))
62 
63 #include <visp3/core/vpColor.h>
64 #include <visp3/core/vpImage.h>
65 #include <visp3/core/vpImagePoint.h>
66 #include <visp3/gui/vpDisplayGDI.h>
67 #include <visp3/gui/vpDisplayGTK.h>
68 #include <visp3/gui/vpDisplayOpenCV.h>
69 #include <visp3/gui/vpDisplayX.h>
70 #include <visp3/io/vpImageIo.h>
71 
72 #include <visp3/core/vpIoTools.h>
73 #include <visp3/io/vpParseArgv.h>
74 #include <visp3/io/vpVideoReader.h>
75 #include <visp3/me/vpMeNurbs.h>
76 
77 // List of allowed command line options
78 #define GETOPTARGS "cdi:h"
79 
80 void usage(const char *name, const char *badparam, std::string ipath);
81 bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display);
82 
92 void usage(const char *name, const char *badparam, std::string ipath)
93 {
94  fprintf(stdout, "\n\
95 Tracking of a nurbs using vpMe.\n\
96 \n\
97 SYNOPSIS\n\
98  %s [-i <input image path>] [-c] [-d] [-h]\n", name);
99 
100  fprintf(stdout, "\n\
101 OPTIONS: Default\n\
102  -i <input image path> %s\n\
103  Set image input path.\n\
104  From this path read images \n\
105  \"ellipse-1/image.%%04d.pgm\"\n\
106  Setting the VISP_INPUT_IMAGE_PATH environment\n\
107  variable produces the same behaviour than using\n\
108  this option.\n\
109 \n\
110  -c\n\
111  Disable the mouse click. Useful to automaze the \n\
112  execution of this program without humain intervention.\n\
113 \n\
114  -d \n\
115  Turn off the display.\n\
116 \n\
117  -h\n\
118  Print the help.\n", ipath.c_str());
119 
120  if (badparam)
121  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
122 }
136 bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display)
137 {
138  const char *optarg_;
139  int c;
140  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
141 
142  switch (c) {
143  case 'c':
144  click_allowed = false;
145  break;
146  case 'd':
147  display = false;
148  break;
149  case 'i':
150  ipath = optarg_;
151  break;
152  case 'h':
153  usage(argv[0], NULL, ipath);
154  return false;
155  break;
156 
157  default:
158  usage(argv[0], optarg_, ipath);
159  return false;
160  break;
161  }
162  }
163 
164  if ((c == 1) || (c == -1)) {
165  // standalone param or error
166  usage(argv[0], NULL, ipath);
167  std::cerr << "ERROR: " << std::endl;
168  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
169  return false;
170  }
171 
172  return true;
173 }
174 
175 int main(int argc, const char **argv)
176 {
177  try {
178  std::string env_ipath;
179  std::string opt_ipath;
180  std::string ipath;
181  std::string filename;
182  bool opt_click_allowed = true;
183  bool opt_display = true;
184 
185  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
186  // environment variable value
187  env_ipath = vpIoTools::getViSPImagesDataPath();
188 
189  // Set the default input path
190  if (!env_ipath.empty())
191  ipath = env_ipath;
192 
193  // Read the command line options
194  if (getOptions(argc, argv, opt_ipath, opt_click_allowed, opt_display) == false) {
195  exit(-1);
196  }
197 
198  // Get the option values
199  if (!opt_ipath.empty())
200  ipath = opt_ipath;
201 
202  // Compare ipath and env_ipath. If they differ, we take into account
203  // the input path comming from the command line option
204  if (!opt_ipath.empty() && !env_ipath.empty()) {
205  if (ipath != env_ipath) {
206  std::cout << std::endl << "WARNING: " << std::endl;
207  std::cout << " Since -i <visp image path=" << ipath << "> "
208  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
209  << " we skip the environment variable." << std::endl;
210  }
211  }
212 
213  // Test if an input path is set
214  if (opt_ipath.empty() && env_ipath.empty()) {
215  usage(argv[0], NULL, ipath);
216  std::cerr << std::endl << "ERROR:" << std::endl;
217  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
218  << " environment variable to specify the location of the " << std::endl
219  << " image path where test images are located." << std::endl
220  << std::endl;
221  exit(-1);
222  }
223 
224  // Declare an image, this is a gray level image (unsigned char)
225  // it size is not defined yet, it will be defined when the image is
226  // read on the disk
228 
229  // Set the path location of the image sequence
230  filename = vpIoTools::createFilePath(ipath, "ellipse-1/image.%04d.pgm");
231 
232  // Build the name of the image file
233  vpVideoReader reader;
234  // Initialize the reader and get the first frame.
235  reader.setFileName(filename.c_str());
236  reader.setFirstFrameIndex(1);
237  reader.open(I);
238 
239 // We open a window using either X11, GTK or GDI.
240 #if defined VISP_HAVE_X11
241  vpDisplayX display;
242 #elif defined VISP_HAVE_GTK
243  vpDisplayGTK display;
244 #elif defined VISP_HAVE_GDI
245  vpDisplayGDI display;
246 #elif defined VISP_HAVE_OPENCV
247  vpDisplayOpenCV display;
248 #endif
249 
250  if (opt_display) {
251  // Display size is automatically defined by the image (I) size
252  display.init(I, 100, 100, "Display...");
253  // Display the image
254  // The image class has a member that specify a pointer toward
255  // the display that has been initialized in the display declaration
256  // therefore is is no longuer necessary to make a reference to the
257  // display variable.
259  vpDisplay::flush(I);
260  }
261 
262  vpMeNurbs nurbs;
263 
264  vpMe me;
265  me.setRange(30);
266  me.setSampleStep(5);
267  me.setPointsToTrack(60);
268  me.setThreshold(15000);
269 
270  nurbs.setMe(&me);
272  nurbs.setNbControlPoints(14);
273 
274  if (opt_click_allowed) {
275  std::cout << "Click on points along the edge with the left button." << std::endl;
276  std::cout << "Then click on the right button to continue." << std::endl;
277  nurbs.initTracking(I);
278  } else {
279  // Create a list of points to automate the test
280  std::list<vpImagePoint> list;
281  list.push_back(vpImagePoint(178, 357));
282  list.push_back(vpImagePoint(212, 287));
283  list.push_back(vpImagePoint(236, 210));
284  list.push_back(vpImagePoint(240, 118));
285  list.push_back(vpImagePoint(210, 40));
286 
287  nurbs.initTracking(I, list);
288  }
289  if (opt_display) {
290  nurbs.display(I, vpColor::green);
291  }
292 
293  nurbs.track(I);
294  if (opt_display && opt_click_allowed) {
295  std::cout << "A click to continue..." << std::endl;
297  }
298  std::cout << "------------------------------------------------------------" << std::endl;
299 
300  for (int iter = 1; iter < 40; iter++) {
301  // read the image
302  reader.getFrame(I, iter);
303  if (opt_display) {
304  // Display the image
306  }
307 
308  // Track the nurbs
309  nurbs.track(I);
310 
311  if (opt_display) {
312  nurbs.display(I, vpColor::green);
313  vpDisplay::flush(I);
314  vpTime::wait(100);
315  }
316  }
317  if (opt_display && opt_click_allowed) {
318  std::cout << "A click to exit..." << std::endl;
320  }
321  return 0;
322  } catch (vpException &e) {
323  std::cout << "Catch an exception: " << e.getMessage() << std::endl;
324  return 0;
325  }
326 }
327 #else
328 #include <iostream>
329 
330 int main()
331 {
332  std::cout << "visp_me module or X11, GTK, GDI or OpenCV display "
333  "functionalities are required..."
334  << std::endl;
335 }
336 
337 #endif
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:173
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
void setPointsToTrack(const int &n)
Definition: vpMe.h:264
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
void track(const vpImage< unsigned char > &I)
Definition: vpMeNurbs.cpp:972
void setSampleStep(const double &s)
Definition: vpMe.h:278
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:134
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
error that can be emited by ViSP classes.
Definition: vpException.h:71
void initTracking(const vpImage< unsigned char > &I)
Definition: vpMeNurbs.cpp:248
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
Definition: vpMe.h:60
const char * getMessage() const
Definition: vpException.cpp:90
Class that tracks in an image a edge defined by a Nurbs.
Definition: vpMeNurbs.h:130
static const vpColor green
Definition: vpColor.h:220
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 open(vpImage< vpRGBa > &I)
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670
bool getFrame(vpImage< vpRGBa > &I, long frame)
void setDisplay(vpMeSite::vpMeSiteDisplayType select)
Definition: vpMeTracker.h:152
void display(const vpImage< unsigned char > &I, vpColor col)
Definition: vpMeNurbs.cpp:1028
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:134
void setNbControlPoints(unsigned int nb_point)
Definition: vpMeNurbs.h:169
void setThreshold(const double &t)
Definition: vpMe.h:300
void setFileName(const std::string &filename)
void setFirstFrameIndex(const long first_frame)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:87
void setRange(const unsigned int &r)
Definition: vpMe.h:271
void setMe(vpMe *p_me)
Definition: vpMeTracker.h:173