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