ViSP
displaySequence.cpp
1 /****************************************************************************
2  *
3  * $Id: displaySequence.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  * Anthony Saunier
41  *
42  *****************************************************************************/
55 #include <visp/vpDebug.h>
56 #include <visp/vpConfig.h>
57 #include <visp/vpParseArgv.h>
58 #include <visp/vpIoTools.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <sstream>
62 #include <iomanip>
63 #if (defined (VISP_HAVE_GTK) || defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
64 
65 #include <visp/vpImage.h>
66 #include <visp/vpImageIo.h>
67 
68 #include <visp/vpDisplayGTK.h>
69 #include <visp/vpDisplayX.h>
70 #include <visp/vpDisplayGDI.h>
71 
72 #include <visp/vpTime.h>
73 
84 // List of allowed command line options
85 #define GETOPTARGS "di:p:hf:n:s:w"
86 
87 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath,
88  unsigned first, unsigned nimages, unsigned step);
89 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath,
90  unsigned &first, unsigned &nimages, unsigned &step, bool &display, bool &wait);
91 
105 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath,
106  unsigned first, unsigned nimages, unsigned step)
107 {
108  fprintf(stdout, "\n\
109 Read an image sequence from the disk and display it.\n\
110 The sequence is made of separate images. Each image corresponds\n\
111 to a PGM file.\n\
112 \n\
113 SYNOPSIS\n\
114  %s [-i <test image path>] [-p <personal image path>]\n\
115  [-f <first image>] [-n <number of images>] [-s <step>] \n\
116  [-w] [-d] [-h]\n \
117  ", name);
118 
119  fprintf(stdout, "\n\
120  OPTIONS: Default\n\
121  -i <test image path> %s\n\
122  Set image input path.\n\
123  From this path read \"ViSP-images/cube/image.%%04d.pgm\"\n\
124  images. These images come from ViSP-images-x.y.z.tar.gz\n\
125  available on the ViSP website.\n\
126  Setting the VISP_INPUT_IMAGE_PATH environment\n\
127  variable produces the same behaviour than using\n\
128  this option.\n\
129  \n\
130  -p <personal image path> %s\n\
131  Specify a personal sequence containing images \n\
132  to process.\n\
133  By image sequence, we mean one file per image.\n\
134  The following image file formats PNM (PGM P5, PPM P6)\n\
135  are supported. The format is selected by analysing \n\
136  the filename extension.\n\
137  Example : \"/Temp/ViSP-images/cube/image.%%04d.pgm\"\n\
138  %%04d is for the image numbering.\n\
139  \n\
140  -f <first image> %u\n\
141  First image number of the sequence.\n\
142  \n\
143  -n <number of images> %u\n\
144  Number of images to load from the sequence.\n\
145  \n\
146  -s <step> %u\n\
147  Step between two images.\n\
148 \n\
149  -d \n\
150  Disable the image display. This can be useful \n\
151  for automatic tests using crontab under Unix or \n\
152  using the task manager under Windows.\n\
153 \n\
154  -w\n\
155  Wait for a mouse click between two images.\n\
156  If the image display is disabled (using -d)\n\
157  this option is without effect.\n\
158 \n\
159  -h\n\
160  Print the help.\n\n",
161  ipath.c_str(),ppath.c_str(), first, nimages, step);
162 
163  if (badparam)
164  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
165 }
187 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath,
188  unsigned &first, unsigned &nimages, unsigned &step, bool &display, bool &wait)
189 {
190  const char *optarg_;
191  int c;
192  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
193 
194  switch (c) {
195  case 'd': display = false; break;
196  case 'i': ipath = optarg_; break;
197  case 'p': ppath = optarg_; break;
198  case 'f': first = (unsigned) atoi(optarg_); break;
199  case 'n': nimages = (unsigned) atoi(optarg_); break;
200  case 's': step = (unsigned) atoi(optarg_); break;
201  case 'w': wait = true; break;
202  case 'h': usage(argv[0], NULL, ipath, ppath, first, nimages, step);
203  return false; break;
204 
205  default:
206  usage(argv[0], optarg_, ipath, ppath, first, nimages, step);
207  return false; break;
208  }
209  }
210 
211  if ((c == 1) || (c == -1)) {
212  // standalone param or error
213  usage(argv[0], NULL, ipath, ppath, first, nimages, step);
214  std::cerr << "ERROR: " << std::endl;
215  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
216  return false;
217  }
218 
219  return true;
220 }
221 
222 int
223 main(int argc, const char ** argv)
224 {
225  try {
226  std::string env_ipath;
227  std::string opt_ipath;
228  std::string ipath;
229  std::string opt_ppath;
230  std::string dirname;
231  std::string filename;
232  unsigned opt_first = 0;
233  unsigned opt_nimages = 80;
234  unsigned opt_step = 1;
235  bool opt_display = true;
236  bool opt_wait = false;
237 
238  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
239  env_ipath = vpIoTools::getViSPImagesDataPath();
240 
241  // Set the default input path
242  if (! env_ipath.empty())
243  ipath = env_ipath;
244 
245  // Read the command line options
246  if (getOptions(argc, argv, opt_ipath, opt_ppath,opt_first, opt_nimages,
247  opt_step, opt_display, opt_wait) == false) {
248  exit (-1);
249  }
250 
251  if ( ! opt_display )
252  opt_wait = false; // turn off the waiting
253 
254  // Get the option values
255  if (!opt_ipath.empty())
256  ipath = opt_ipath;
257 
258  // Compare ipath and env_ipath. If they differ, we take into account
259  // the input path comming from the command line option
260  if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
261  if (ipath != env_ipath) {
262  std::cout << std::endl
263  << "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() && opt_ppath.empty() ){
272  usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_nimages, opt_step);
273  std::cerr << std::endl
274  << "ERROR:" << std::endl;
275  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
276  << std::endl
277  << " environment variable to specify the location of the " << std::endl
278  << " image path where test images are located." << std::endl
279  << " Use -p <personal image path> option if you want to "<<std::endl
280  << " use personal images." << std::endl
281  << std::endl;
282 
283  exit(-1);
284  }
285 
286  // Declare an image, this is a gray level image (unsigned char)
287  // it size is not defined yet, it will be defined when the image will
288  // read on the disk
290 
291  unsigned iter = opt_first;
292  std::ostringstream s;
293  char cfilename[FILENAME_MAX];
294 
295  if (opt_ppath.empty()){
296 
297 
298  // Warning :
299  // the image sequence is not provided with the ViSP package
300  // therefore the program will return you an error :
301  // !! vpImageIoPnm.cpp: readPGM(#210) :couldn't read file
302  // ViSP-images/cube/image.0001.pgm
303  // !! vpDotExample.cpp: main(#95) :Error while reading the image
304  // terminate called after throwing an instance of 'vpImageException'
305  //
306  // The sequence is available on the visp www site
307  // http://www.irisa.fr/lagadic/visp/visp.html
308  // in the download section. It is named "ViSP-images.tar.gz"
309 
310  // Set the path location of the image sequence
311  dirname = vpIoTools::createFilePath(ipath, "ViSP-images/cube");
312 
313  // Build the name of the image file
314 
315  s.setf(std::ios::right, std::ios::adjustfield);
316  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
317  filename = vpIoTools::createFilePath(dirname, s.str());
318  }
319  else {
320  sprintf(cfilename,opt_ppath.c_str(), iter) ;
321  filename = cfilename;
322  }
323  // Read the PGM image named "filename" on the disk, and put the
324  // bitmap into the image structure I. I is initialized to the
325  // correct size
326  //
327  // exception readPGM may throw various exception if, for example,
328  // the file does not exist, or if the memory cannot be allocated
329  try{
330  vpImageIo::read(I, filename) ;
331  }
332  catch(...)
333  {
334  // an exception is throwned if an exception from readPGM has been catched
335  // here this will result in the end of the program
336  // Note that another error message has been printed from readPGM
337  // to give more information about the error
338  std::cerr << std::endl
339  << "ERROR:" << std::endl;
340  std::cerr << " Cannot read " << filename << std::endl;
341  std::cerr << " Check your -i " << ipath << " option, " << std::endl
342  << " or your -p " << opt_ppath << " option " <<std::endl
343  << " or VISP_INPUT_IMAGE_PATH environment variable"
344  << std::endl;
345  exit(-1);
346  }
347 
348 #if defined VISP_HAVE_GTK
349  vpDisplayGTK display;
350 #elif defined VISP_HAVE_X11
351  vpDisplayX display;
352 #elif defined VISP_HAVE_GDI
353  vpDisplayGDI display;
354 #endif
355  if (opt_display) {
356 
357  // We open a window using either X11 or GTK or GDI.
358  // Its size is automatically defined by the image (I) size
359  display.init(I, 100, 100,"Display...") ;
360 
361  // Display the image
362  // The image class has a member that specify a pointer toward
363  // the display that has been initialized in the display declaration
364  // therefore is is no longuer necessary to make a reference to the
365  // display variable.
366  vpDisplay::display(I) ;
367  vpDisplay::flush(I) ;
368  }
369 
370  // double tms_1 = vpTime::measureTimeMs() ;
371  unsigned niter=0 ;
372  // this is the loop over the image sequence
373  while (iter < opt_first + opt_nimages*opt_step) {
374  double tms = vpTime::measureTimeMs() ;
375 
376  // set the new image name
377 
378  if (opt_ppath.empty()){
379  s.str("");
380  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
381  filename = vpIoTools::createFilePath(dirname, s.str());
382  }
383  else {
384  sprintf(cfilename, opt_ppath.c_str(), iter) ;
385  filename = cfilename;
386  }
387 
388  std::cout << "read : " << filename << std::endl;
389  // read the image
390  vpImageIo::read(I, filename);
391  if (opt_display) {
392  // Display the image
393  vpDisplay::display(I) ;
394  //Flush the display
395  vpDisplay::flush(I) ;
396 
397  }
398  if (opt_wait) {
399  std::cout << "A click in the image to continue..." << std::endl;
400  // Wait for a blocking mouse click
402  }
403  else {
404  // Synchronise the loop to 40 ms
405  vpTime::wait(tms, 40) ;
406  }
407  niter++ ;
408 
409  iter += opt_step ;
410  }
411  // double tms_2 = vpTime::measureTimeMs() ;
412  // double tms_total = tms_2 - tms_1 ;
413  // std::cout << "Total Time : "<< tms_total<<std::endl;
414  return 0;
415  }
416  catch(vpException e) {
417  std::cout << "Catch an exception: " << e << std::endl;
418  return 1;
419  }
420 }
421 #else
422 int
423 main()
424 {
425  vpERROR_TRACE("You do not have X11 or GTK display functionalities...");
426 }
427 
428 #endif
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1071
#define vpERROR_TRACE
Definition: vpDebug.h:395
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:132
Define the X11 console to display images.
Definition: vpDisplayX.h:152
error that can be emited by ViSP classes.
Definition: vpException.h:76
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
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1245
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:210
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
Definition: vpDisplayGTK.h:145
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
virtual bool getClick(bool blocking=true)=0
static void read(vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:278