ViSP
grabDisk.cpp
1 /****************************************************************************
2  *
3  * $Id: grabDisk.cpp 4814 2014-07-31 11:38:39Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Read an image sequence from the disk and display it.
36  *
37  * Authors:
38  * Eric Marchand
39  * Fabien Spindler
40  *
41  *****************************************************************************/
42 
43 
44 #include <visp/vpDebug.h>
45 #include <visp/vpConfig.h>
46 #include <stdlib.h>
47 #if (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
48 
49 #include <visp/vpDiskGrabber.h>
50 #include <visp/vpDisplay.h>
51 #include <visp/vpDisplayX.h>
52 #include <visp/vpDisplayGDI.h>
53 #include <visp/vpImage.h>
54 #include <visp/vpIoTools.h>
55 #include <visp/vpParseArgv.h>
56 #include <visp/vpTime.h>
57 
67 // List of allowed command line options
68 #define GETOPTARGS "b:de:f:i:hn:s:z:"
69 
70 void usage(const char *name, const char *badparam, std::string ipath, std::string basename,
71  std::string ext, int first, unsigned int nimages, int step, unsigned int nzero);
72 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename,
73  std::string &ext, int &first, unsigned int &nimages,
74  int &step, unsigned int &nzero, bool &display);
75 
76 /*
77 
78  Print the program options.
79 
80  \param name : Program name.
81  \param badparam : Bad parameter name.
82  \param ipath : Input image path.
83  \param basename : Input image base name.
84  \param ext : Input image extension.
85  \param first : First image number to read.
86  \param nimages : Number of images to read.
87  \param step : Step between two successive images to read.
88  \param nzero : Number of zero for the image number coding.
89 
90  */
91 void usage(const char *name, const char *badparam, std::string ipath, std::string basename,
92  std::string ext, int first, unsigned int nimages, int step, unsigned int nzero)
93 {
94  fprintf(stdout, "\n\
95 Read an image sequence from the disk. Display it using X11 or GTK.\n\
96 The sequence is made of separate images. Each image corresponds\n\
97 to a PGM file.\n\
98 \n\
99 SYNOPSIS\n\
100  %s [-i <input image path>] [-b <base name>] [-e <extension>] \n\
101  [-f <first frame>] [-n <number of images> [-s <step>] \n\
102  [-z <number of zero>] [-d] [-h]\n", name);
103 
104  fprintf(stdout, "\n\
105 OPTIONS: Default\n\
106  -i <input image path> %s\n\
107  Set image input path.\n\
108  From this path read \"ViSP-images/cube/image.%%04d.pgm\"\n\
109  images.\n\
110  Setting the VISP_INPUT_IMAGE_PATH environment\n\
111  variable produces the same behaviour than using\n\
112  this option.\n\
113 \n\
114  -b <base name> %s\n\
115  Specify the base name of the files of the sequence\n\
116  containing the images to process. \n\
117  By image sequence, we mean one file per image.\n\
118  The following image file formats PNM (PGM P5, PPM P6)\n\
119  are supported. The format is selected by analysing \n\
120  the filename extension.\n\
121 \n\
122  -e <extension> %s\n\
123  Specify the extension of the files.\n\
124  Not taken into account for the moment. Will be a\n\
125  future feature...\n\
126 \n\
127  -f <first frame> %u\n\
128  First frame number of the sequence\n\
129 \n\
130  -n <number of images> %u\n\
131  Number of images to load from the sequence.\n\
132 \n\
133  -s <step> %u\n\
134  Step between two images.\n\
135 \n\
136  -z <number of zero> %u\n\
137  Number of digits to encode the image number.\n\
138 \n\
139  -d \n\
140  Turn off the display.\n\
141 \n\
142  -h \n\
143  Print the help.\n\n",
144  ipath.c_str(), basename.c_str(), ext.c_str(), first,
145  nimages, step, nzero);
146 
147  if (badparam)
148  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
149 }
168 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename,
169  std::string &ext, int &first, unsigned int &nimages,
170  int &step, unsigned int &nzero, bool &display)
171 {
172  const char *optarg_;
173  int c;
174  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
175 
176  switch (c) {
177  case 'b': basename = optarg_; break;
178  case 'd': display = false; break;
179  case 'e': ext = optarg_; break;
180  case 'f': first = atoi(optarg_); break;
181  case 'i': ipath = optarg_; break;
182  case 'n': nimages = (unsigned) atoi(optarg_); break;
183  case 's': step = atoi(optarg_); break;
184  case 'z': nzero = (unsigned) atoi(optarg_); break;
185  case 'h': usage(argv[0], NULL, ipath, basename, ext, first, nimages,
186  step, nzero); return false; break;
187 
188  default:
189  usage(argv[0], optarg_, ipath, basename, ext, first, nimages, step, nzero);
190  return false; break;
191  }
192  }
193 
194  if ((c == 1) || (c == -1)) {
195  // standalone param or error
196  usage(argv[0], NULL, ipath, basename, ext, first, nimages, step, nzero);
197  std::cerr << "ERROR: " << std::endl;
198  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
199  return false;
200  }
201 
202  return true;
203 }
204 
205 
215 int main(int argc, const char ** argv)
216 {
217  try {
218  std::string env_ipath;
219  std::string opt_ipath;
220  std::string ipath;
221  std::string opt_basename = "ViSP-images/cube/image.";
222  std::string opt_ext = "pgm";
223  bool opt_display = true;
224 
225  int opt_first = 5;
226  unsigned int opt_nimages = 70;
227  int opt_step = 1;
228  unsigned int opt_nzero = 4;
229 
230  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
231  env_ipath = vpIoTools::getViSPImagesDataPath();
232 
233  // Set the default input path
234  if (! env_ipath.empty())
235  ipath = env_ipath;
236 
237  // Read the command line options
238  if (getOptions(argc, argv, opt_ipath, opt_basename, opt_ext, opt_first,
239  opt_nimages, opt_step, opt_nzero, opt_display) == false) {
240  exit (-1);
241  }
242 
243  // Get the option values
244  if (!opt_ipath.empty())
245  ipath = opt_ipath;
246 
247  // Compare ipath and env_ipath. If they differ, we take into account
248  // the input path comming from the command line option
249  if (!opt_ipath.empty() && !env_ipath.empty()) {
250  if (ipath != env_ipath) {
251  std::cout << std::endl
252  << "WARNING: " << std::endl;
253  std::cout << " Since -i <visp image path=" << ipath << "> "
254  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
255  << " we skip the environment variable." << std::endl;
256  }
257  }
258 
259  // Test if an input path is set
260  if (opt_ipath.empty() && env_ipath.empty()){
261  usage(argv[0], NULL, ipath, opt_basename, opt_ext, opt_first,
262  opt_nimages, opt_step, opt_nzero);
263  std::cerr << std::endl
264  << "ERROR:" << std::endl;
265  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
266  << std::endl
267  << " environment variable to specify the location of the " << std::endl
268  << " image path where test images are located." << std::endl << std::endl;
269  exit(-1);
270  }
271 
272 
273  // Declare an image, this is a gray level image (unsigned char)
274  // it size is not defined yet, it will be defined when the image will
275  // read on the disk
277 
278 
279  // Declare a framegrabber able to read a sequence of successive
280  // images from the disk
281  vpDiskGrabber g;
282 
283  // Set the path to the directory containing the sequence
284  g.setDirectory(ipath.c_str());
285  // Set the image base name. The directory and the base name constitute
286  // the constant part of the full filename
287  g.setBaseName(opt_basename.c_str());
288  // Set the step between two images of the sequence
289  g.setStep(opt_step);
290  // Set the number of digits to build the image number
291  g.setNumberOfZero(opt_nzero);
292  // Set the first frame number of the sequence
293  g.setImageNumber(opt_first);
294  // Set the image extension
295  g.setExtension(opt_ext.c_str());
296 
297  // Open the framegrabber by loading the first image of the sequence
298  g.open(I) ;
299 
300  std::cout << "Image size: width : " << I.getWidth() << " height: "
301  << I.getHeight() << std::endl;
302 
303  // We open a window using either X11 or GDI.
304  // Its size is automatically defined by the image (I) size
305 #if defined(VISP_HAVE_X11)
306  vpDisplayX display(I);
307 #elif defined(VISP_HAVE_GDI)
308  vpDisplayGDI display(I);
309 #else
310  std::cout << "No image viewer is available..." << std::endl;
311 #endif
312 
313  if (opt_display) {
314  display.init(I,100,100,"Disk Framegrabber");
315 
316  // display the image
317  // The image class has a member that specify a pointer toward
318  // the display that has been initialized in the display declaration
319  // therefore is is no longuer necessary to make a reference to the
320  // display variable.
321  vpDisplay::display(I) ;
322  vpDisplay::flush(I) ;
323  }
324 
325  unsigned cpt = 1;
326  // this is the loop over the image sequence
327 
328  while(cpt ++ < opt_nimages)
329  {
330  double tms = vpTime::measureTimeMs();
331  // read the image and then increment the image counter so that the next
332  // call to acquire(I) will get the next image
333  g.acquire(I) ;
334  if (opt_display) {
335  // Display the image
336  vpDisplay::display(I) ;
337  // Flush the display
338  vpDisplay::flush(I) ;
339  }
340  // Synchronise the loop to 40 ms
341  vpTime::wait(tms, 40) ;
342  }
343  return 0;
344  }
345  catch(vpException e) {
346  std::cout << "Catch an exception: " << e << std::endl;
347  return 1;
348  }
349 }
350 
351 #else
352 int
353 main()
354 {
355  vpERROR_TRACE("You do not have X11 or GTK display functionalities...");
356 }
357 
358 #endif
359 
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1071
unsigned int getWidth() const
Definition: vpImage.h:161
#define vpERROR_TRACE
Definition: vpDebug.h:395
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:132
void setBaseName(const char *name)
Define the X11 console to display images.
Definition: vpDisplayX.h:152
error that can be emited by ViSP classes.
Definition: vpException.h:76
void setDirectory(const char *dir)
static double measureTimeMs()
Definition: vpTime.cpp:86
static int wait(double t0, double t)
Definition: vpTime.cpp:149
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2232
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:80
void setNumberOfZero(unsigned int noz)
void setStep(int a)
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:210
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:152
void acquire(vpImage< unsigned char > &I)