Visual Servoing Platform  version 3.0.1
grabDisk.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  * Read an image sequence from the disk and display it.
32  *
33  * Authors:
34  * Eric Marchand
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
39 
40 #include <visp3/core/vpDebug.h>
41 #include <visp3/core/vpConfig.h>
42 #include <stdlib.h>
43 #if (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
44 
45 #include <visp3/io/vpDiskGrabber.h>
46 #include <visp3/core/vpDisplay.h>
47 #include <visp3/gui/vpDisplayX.h>
48 #include <visp3/gui/vpDisplayGDI.h>
49 #include <visp3/core/vpImage.h>
50 #include <visp3/core/vpIoTools.h>
51 #include <visp3/io/vpParseArgv.h>
52 #include <visp3/core/vpTime.h>
53 
63 // List of allowed command line options
64 #define GETOPTARGS "b:de:f:i:hn:s:z:"
65 
66 void usage(const char *name, const char *badparam, std::string ipath, std::string basename,
67  std::string ext, int first, unsigned int nimages, int step, unsigned int nzero);
68 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename,
69  std::string &ext, int &first, unsigned int &nimages,
70  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,
88  std::string ext, int first, 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 \"ViSP-images/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",
140  ipath.c_str(), basename.c_str(), ext.c_str(), first,
141  nimages, step, nzero);
142 
143  if (badparam)
144  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
145 }
164 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename,
165  std::string &ext, int &first, unsigned int &nimages,
166  int &step, unsigned int &nzero, bool &display)
167 {
168  const char *optarg_;
169  int c;
170  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
171 
172  switch (c) {
173  case 'b': basename = optarg_; break;
174  case 'd': display = false; break;
175  case 'e': ext = optarg_; break;
176  case 'f': first = atoi(optarg_); break;
177  case 'i': ipath = optarg_; break;
178  case 'n': nimages = (unsigned) atoi(optarg_); break;
179  case 's': step = atoi(optarg_); break;
180  case 'z': nzero = (unsigned) atoi(optarg_); break;
181  case 'h': usage(argv[0], NULL, ipath, basename, ext, first, nimages,
182  step, nzero); return false; break;
183 
184  default:
185  usage(argv[0], optarg_, ipath, basename, ext, first, nimages, step, nzero);
186  return false; break;
187  }
188  }
189 
190  if ((c == 1) || (c == -1)) {
191  // standalone param or error
192  usage(argv[0], NULL, ipath, basename, ext, first, nimages, step, nzero);
193  std::cerr << "ERROR: " << std::endl;
194  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
195  return false;
196  }
197 
198  return true;
199 }
200 
201 
211 int main(int argc, const char ** argv)
212 {
213  try {
214  std::string env_ipath;
215  std::string opt_ipath;
216  std::string ipath;
217  std::string opt_basename = "ViSP-images/cube/image.";
218  std::string opt_ext = "pgm";
219  bool opt_display = true;
220 
221  int opt_first = 5;
222  unsigned int opt_nimages = 70;
223  int opt_step = 1;
224  unsigned int opt_nzero = 4;
225 
226  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
227  env_ipath = vpIoTools::getViSPImagesDataPath();
228 
229  // Set the default input path
230  if (! env_ipath.empty())
231  ipath = env_ipath;
232 
233  // Read the command line options
234  if (getOptions(argc, argv, opt_ipath, opt_basename, opt_ext, opt_first,
235  opt_nimages, opt_step, opt_nzero, opt_display) == false) {
236  exit (-1);
237  }
238 
239  // Get the option values
240  if (!opt_ipath.empty())
241  ipath = opt_ipath;
242 
243  // Compare ipath and env_ipath. If they differ, we take into account
244  // the input path comming from the command line option
245  if (!opt_ipath.empty() && !env_ipath.empty()) {
246  if (ipath != env_ipath) {
247  std::cout << std::endl
248  << "WARNING: " << std::endl;
249  std::cout << " Since -i <visp image path=" << ipath << "> "
250  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
251  << " we skip the environment variable." << std::endl;
252  }
253  }
254 
255  // Test if an input path is set
256  if (opt_ipath.empty() && env_ipath.empty()){
257  usage(argv[0], NULL, ipath, opt_basename, opt_ext, opt_first,
258  opt_nimages, opt_step, opt_nzero);
259  std::cerr << std::endl
260  << "ERROR:" << std::endl;
261  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
262  << std::endl
263  << " environment variable to specify the location of the " << std::endl
264  << " image path where test images are located." << std::endl << std::endl;
265  exit(-1);
266  }
267 
268 
269  // Declare an image, this is a gray level image (unsigned char)
270  // it size is not defined yet, it will be defined when the image will
271  // read on the disk
273 
274 
275  // Declare a framegrabber able to read a sequence of successive
276  // images from the disk
277  vpDiskGrabber g;
278 
279  // Set the path to the directory containing the sequence
280  g.setDirectory(ipath.c_str());
281  // Set the image base name. The directory and the base name constitute
282  // the constant part of the full filename
283  g.setBaseName(opt_basename.c_str());
284  // Set the step between two images of the sequence
285  g.setStep(opt_step);
286  // Set the number of digits to build the image number
287  g.setNumberOfZero(opt_nzero);
288  // Set the first frame number of the sequence
289  g.setImageNumber(opt_first);
290  // Set the image extension
291  g.setExtension(opt_ext.c_str());
292 
293  // Open the framegrabber by loading the first image of the sequence
294  g.open(I) ;
295 
296  std::cout << "Image size: width : " << I.getWidth() << " height: "
297  << I.getHeight() << std::endl;
298 
299  // We open a window using either X11 or GDI.
300  // Its size is automatically defined by the image (I) size
301 #if defined(VISP_HAVE_X11)
302  vpDisplayX display(I);
303 #elif defined(VISP_HAVE_GDI)
304  vpDisplayGDI display(I);
305 #else
306  std::cout << "No image viewer is available..." << std::endl;
307 #endif
308 
309  if (opt_display) {
310  display.init(I,100,100,"Disk Framegrabber");
311 
312  // display the image
313  // The image class has a member that specify a pointer toward
314  // the display that has been initialized in the display declaration
315  // therefore is is no longuer necessary to make a reference to the
316  // display variable.
317  vpDisplay::display(I) ;
318  vpDisplay::flush(I) ;
319  }
320 
321  unsigned cpt = 1;
322  // this is the loop over the image sequence
323 
324  while(cpt ++ < opt_nimages)
325  {
326  double tms = vpTime::measureTimeMs();
327  // read the image and then increment the image counter so that the next
328  // call to acquire(I) will get the next image
329  g.acquire(I) ;
330  if (opt_display) {
331  // Display the image
332  vpDisplay::display(I) ;
333  // Flush the display
334  vpDisplay::flush(I) ;
335  }
336  // Synchronise the loop to 40 ms
337  vpTime::wait(tms, 40) ;
338  }
339  return 0;
340  }
341  catch(vpException &e) {
342  std::cout << "Catch an exception: " << e << std::endl;
343  return 1;
344  }
345 }
346 
347 #else
348 int
349 main()
350 {
351  vpERROR_TRACE("You do not have X11 or GTK display functionalities...");
352 }
353 
354 #endif
355 
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:157
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
#define vpERROR_TRACE
Definition: vpDebug.h:391
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
void setBaseName(const char *name)
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 setDirectory(const char *dir)
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
void setNumberOfZero(unsigned int noz)
void setStep(int a)
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.
void setExtension(const char *ext)
unsigned int getHeight() const
Definition: vpImage.h:175
void acquire(vpImage< unsigned char > &I)
unsigned int getWidth() const
Definition: vpImage.h:226