Visual Servoing Platform  version 3.4.0
grabDisk.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  * Read an image sequence from the disk and display it.
33  *
34  * Authors:
35  * Eric Marchand
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
40 #include <stdlib.h>
41 #include <visp3/core/vpConfig.h>
42 #include <visp3/core/vpDebug.h>
43 #if (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
44 
45 #include <visp3/core/vpDisplay.h>
46 #include <visp3/core/vpImage.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/core/vpTime.h>
49 #include <visp3/gui/vpDisplayGDI.h>
50 #include <visp3/gui/vpDisplayX.h>
51 #include <visp3/io/vpDiskGrabber.h>
52 #include <visp3/io/vpParseArgv.h>
53 
64 // List of allowed command line options
65 #define GETOPTARGS "b:de:f:i:hn:s:z:"
66 
67 void usage(const char *name, const char *badparam, std::string ipath, std::string basename, std::string ext, int first,
68  unsigned int nimages, int step, unsigned int nzero);
69 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename, std::string &ext, int &first,
70  unsigned int &nimages, int &step, unsigned int &nzero, bool &display);
71 
72 /*
73 
74  Print the program options.
75 
76  \param name : Program name.
77  \param badparam : Bad parameter name.
78  \param ipath : Input image path.
79  \param basename : Input image base name.
80  \param ext : Input image extension.
81  \param first : First image number to read.
82  \param nimages : Number of images to read.
83  \param step : Step between two successive images to read.
84  \param nzero : Number of zero for the image number coding.
85 
86  */
87 void usage(const char *name, const char *badparam, std::string ipath, std::string basename, std::string ext, int first,
88  unsigned int nimages, int step, unsigned int nzero)
89 {
90  fprintf(stdout, "\n\
91 Read an image sequence from the disk. Display it using X11 or GTK.\n\
92 The sequence is made of separate images. Each image corresponds\n\
93 to a PGM file.\n\
94 \n\
95 SYNOPSIS\n\
96  %s [-i <input image path>] [-b <base name>] [-e <extension>] \n\
97  [-f <first frame>] [-n <number of images> [-s <step>] \n\
98  [-z <number of zero>] [-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 \"cube/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  -b <base name> %s\n\
111  Specify the base name of the files of the sequence\n\
112  containing the images to process. \n\
113  By image sequence, we mean one file per image.\n\
114  The following image file formats PNM (PGM P5, PPM P6)\n\
115  are supported. The format is selected by analysing \n\
116  the filename extension.\n\
117 \n\
118  -e <extension> %s\n\
119  Specify the extension of the files.\n\
120  Not taken into account for the moment. Will be a\n\
121  future feature...\n\
122 \n\
123  -f <first frame> %d\n\
124  First frame number of the sequence\n\
125 \n\
126  -n <number of images> %u\n\
127  Number of images to load from the sequence.\n\
128 \n\
129  -s <step> %d\n\
130  Step between two images.\n\
131 \n\
132  -z <number of zero> %u\n\
133  Number of digits to encode the image number.\n\
134 \n\
135  -d \n\
136  Turn off the display.\n\
137 \n\
138  -h \n\
139  Print the help.\n\n", ipath.c_str(), basename.c_str(), ext.c_str(), first, nimages, step, nzero);
140 
141  if (badparam)
142  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
143 }
162 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename, std::string &ext, int &first,
163  unsigned int &nimages, int &step, unsigned int &nzero, bool &display)
164 {
165  const char *optarg_;
166  int c;
167  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
168 
169  switch (c) {
170  case 'b':
171  basename = optarg_;
172  break;
173  case 'd':
174  display = false;
175  break;
176  case 'e':
177  ext = optarg_;
178  break;
179  case 'f':
180  first = atoi(optarg_);
181  break;
182  case 'i':
183  ipath = optarg_;
184  break;
185  case 'n':
186  nimages = (unsigned)atoi(optarg_);
187  break;
188  case 's':
189  step = atoi(optarg_);
190  break;
191  case 'z':
192  nzero = (unsigned)atoi(optarg_);
193  break;
194  case 'h':
195  usage(argv[0], NULL, ipath, basename, ext, first, nimages, step, nzero);
196  return false;
197  break;
198 
199  default:
200  usage(argv[0], optarg_, ipath, basename, ext, first, nimages, step, nzero);
201  return false;
202  break;
203  }
204  }
205 
206  if ((c == 1) || (c == -1)) {
207  // standalone param or error
208  usage(argv[0], NULL, ipath, basename, ext, first, nimages, step, nzero);
209  std::cerr << "ERROR: " << std::endl;
210  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
211  return false;
212  }
213 
214  return true;
215 }
216 
226 int main(int argc, const char **argv)
227 {
228  try {
229  std::string env_ipath;
230  std::string opt_ipath;
231  std::string ipath;
232  std::string opt_basename = "cube/image.";
233  std::string opt_ext = "pgm";
234  bool opt_display = true;
235 
236  int opt_first = 5;
237  unsigned int opt_nimages = 70;
238  int opt_step = 1;
239  unsigned int opt_nzero = 4;
240 
241  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
242  // environment variable value
243  env_ipath = vpIoTools::getViSPImagesDataPath();
244 
245  // Set the default input path
246  if (!env_ipath.empty())
247  ipath = env_ipath;
248 
249  // Read the command line options
250  if (getOptions(argc, argv, opt_ipath, opt_basename, opt_ext, opt_first, opt_nimages, opt_step, opt_nzero,
251  opt_display) == false) {
252  exit(-1);
253  }
254 
255  // Get the option values
256  if (!opt_ipath.empty())
257  ipath = opt_ipath;
258 
259  // Compare ipath and env_ipath. If they differ, we take into account
260  // the input path comming from the command line option
261  if (!opt_ipath.empty() && !env_ipath.empty()) {
262  if (ipath != env_ipath) {
263  std::cout << std::endl << "WARNING: " << std::endl;
264  std::cout << " Since -i <visp image path=" << ipath << "> "
265  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
266  << " we skip the environment variable." << std::endl;
267  }
268  }
269 
270  // Test if an input path is set
271  if (opt_ipath.empty() && env_ipath.empty()) {
272  usage(argv[0], NULL, ipath, opt_basename, opt_ext, opt_first, opt_nimages, opt_step, opt_nzero);
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
277  << std::endl;
278  exit(-1);
279  }
280 
281  // Declare an image, this is a gray level image (unsigned char)
282  // it size is not defined yet, it will be defined when the image will
283  // read on the disk
285 
286  // Declare a framegrabber able to read a sequence of successive
287  // images from the disk
288  vpDiskGrabber g;
289 
290  // Set the path to the directory containing the sequence
291  g.setDirectory(ipath.c_str());
292  // Set the image base name. The directory and the base name constitute
293  // the constant part of the full filename
294  g.setBaseName(opt_basename.c_str());
295  // Set the step between two images of the sequence
296  g.setStep(opt_step);
297  // Set the number of digits to build the image number
298  g.setNumberOfZero(opt_nzero);
299  // Set the first frame number of the sequence
300  g.setImageNumber(opt_first);
301  // Set the image extension
302  g.setExtension(opt_ext.c_str());
303 
304  // Open the framegrabber by loading the first image of the sequence
305  g.open(I);
306 
307  std::cout << "Image size: width : " << I.getWidth() << " height: " << I.getHeight() << std::endl;
308 
309 // We open a window using either X11 or GDI.
310 // Its size is automatically defined by the image (I) size
311 #if defined(VISP_HAVE_X11)
312  vpDisplayX display(I);
313 #elif defined(VISP_HAVE_GDI)
314  vpDisplayGDI display(I);
315 #else
316  std::cout << "No image viewer is available..." << std::endl;
317 #endif
318 
319  if (opt_display) {
320  display.init(I, 100, 100, "Disk Framegrabber");
321 
322  // display the image
323  // The image class has a member that specify a pointer toward
324  // the display that has been initialized in the display declaration
325  // therefore is is no longuer necessary to make a reference to the
326  // display variable.
328  vpDisplay::flush(I);
329  }
330 
331  unsigned cpt = 1;
332  // this is the loop over the image sequence
333 
334  while (cpt++ < opt_nimages) {
335  double tms = vpTime::measureTimeMs();
336  // read the image and then increment the image counter so that the next
337  // call to acquire(I) will get the next image
338  g.acquire(I);
339  if (opt_display) {
340  // Display the image
342  // Flush the display
343  vpDisplay::flush(I);
344  }
345  // Synchronise the loop to 40 ms
346  vpTime::wait(tms, 40);
347  }
348  return EXIT_SUCCESS;
349  } catch (const vpException &e) {
350  std::cout << "Catch an exception: " << e << std::endl;
351  return EXIT_FAILURE;
352  }
353 }
354 
355 #else
356 int main()
357 {
358  std::cout << "You do not have X11, or GDI (Graphical Device Interface) functionalities to display images..." << std::endl;
359  std::cout << "Tip if you are on a unix-like system:" << std::endl;
360  std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
361  std::cout << "Tip if you are on a windows-like system:" << std::endl;
362  std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
363  return EXIT_SUCCESS;
364 }
365 #endif
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:173
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1202
unsigned int getWidth() const
Definition: vpImage.h:246
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:150
void setStep(long step)
error that can be emited by ViSP classes.
Definition: vpException.h:71
void setDirectory(const std::string &dir)
void setBaseName(const std::string &name)
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:126
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
void setExtension(const std::string &ext)
void setNumberOfZero(unsigned int noz)
static void display(const vpImage< unsigned char > &I)
void setImageNumber(long number)
void open(vpImage< unsigned char > &I)
Class to grab (ie. read) images from the disk.
unsigned int getHeight() const
Definition: vpImage.h:188
void acquire(vpImage< unsigned char > &I)