ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Modules Pages
displaySequence.cpp
1 /****************************************************************************
2  *
3  * $Id: displaySequence.cpp 4658 2014-02-09 09:50:14Z 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_IMAGE_PATH environment variable value
239  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
240  if (ptenv != NULL)
241  env_ipath = ptenv;
242 
243  // Set the default input path
244  if (! env_ipath.empty())
245  ipath = env_ipath;
246 
247  // Read the command line options
248  if (getOptions(argc, argv, opt_ipath, opt_ppath,opt_first, opt_nimages,
249  opt_step, opt_display, opt_wait) == false) {
250  exit (-1);
251  }
252 
253  if ( ! opt_display )
254  opt_wait = false; // turn off the waiting
255 
256  // Get the option values
257  if (!opt_ipath.empty())
258  ipath = opt_ipath;
259 
260  // Compare ipath and env_ipath. If they differ, we take into account
261  // the input path comming from the command line option
262  if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
263  if (ipath != env_ipath) {
264  std::cout << std::endl
265  << "WARNING: " << std::endl;
266  std::cout << " Since -i <visp image path=" << ipath << "> "
267  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
268  << " we skip the environment variable." << std::endl;
269  }
270  }
271 
272  // Test if an input path is set
273  if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty() ){
274  usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_nimages, opt_step);
275  std::cerr << std::endl
276  << "ERROR:" << std::endl;
277  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
278  << std::endl
279  << " environment variable to specify the location of the " << std::endl
280  << " image path where test images are located." << std::endl
281  << " Use -p <personal image path> option if you want to "<<std::endl
282  << " use personal images." << std::endl
283  << std::endl;
284 
285  exit(-1);
286  }
287 
288  // Declare an image, this is a gray level image (unsigned char)
289  // it size is not defined yet, it will be defined when the image will
290  // read on the disk
292 
293  unsigned iter = opt_first;
294  std::ostringstream s;
295  char cfilename[FILENAME_MAX];
296 
297  if (opt_ppath.empty()){
298 
299 
300  // Warning :
301  // the image sequence is not provided with the ViSP package
302  // therefore the program will return you an error :
303  // !! vpImageIoPnm.cpp: readPGM(#210) :couldn't read file
304  // ViSP-images/cube/image.0001.pgm
305  // !! vpDotExample.cpp: main(#95) :Error while reading the image
306  // terminate called after throwing an instance of 'vpImageException'
307  //
308  // The sequence is available on the visp www site
309  // http://www.irisa.fr/lagadic/visp/visp.html
310  // in the download section. It is named "ViSP-images.tar.gz"
311 
312  // Set the path location of the image sequence
313  dirname = ipath + vpIoTools::path("/ViSP-images/cube/");
314 
315  // Build the name of the image file
316 
317  s.setf(std::ios::right, std::ios::adjustfield);
318  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
319  filename = dirname + s.str();
320  }
321  else {
322 
323  sprintf(cfilename,opt_ppath.c_str(), iter) ;
324  filename = cfilename;
325  }
326  // Read the PGM image named "filename" on the disk, and put the
327  // bitmap into the image structure I. I is initialized to the
328  // correct size
329  //
330  // exception readPGM may throw various exception if, for example,
331  // the file does not exist, or if the memory cannot be allocated
332  try{
333  vpImageIo::read(I, filename) ;
334  }
335  catch(...)
336  {
337  // an exception is throwned if an exception from readPGM has been catched
338  // here this will result in the end of the program
339  // Note that another error message has been printed from readPGM
340  // to give more information about the error
341  std::cerr << std::endl
342  << "ERROR:" << std::endl;
343  std::cerr << " Cannot read " << filename << std::endl;
344  std::cerr << " Check your -i " << ipath << " option, " << std::endl
345  << " or your -p " << opt_ppath << " option " <<std::endl
346  << " or VISP_INPUT_IMAGE_PATH environment variable"
347  << std::endl;
348  exit(-1);
349  }
350 
351 #if defined VISP_HAVE_GTK
352  vpDisplayGTK display;
353 #elif defined VISP_HAVE_X11
354  vpDisplayX display;
355 #elif defined VISP_HAVE_GDI
356  vpDisplayGDI display;
357 #endif
358  if (opt_display) {
359 
360  // We open a window using either X11 or GTK or GDI.
361  // Its size is automatically defined by the image (I) size
362  display.init(I, 100, 100,"Display...") ;
363 
364  // Display the image
365  // The image class has a member that specify a pointer toward
366  // the display that has been initialized in the display declaration
367  // therefore is is no longuer necessary to make a reference to the
368  // display variable.
369  vpDisplay::display(I) ;
370  vpDisplay::flush(I) ;
371  }
372 
373  // double tms_1 = vpTime::measureTimeMs() ;
374  unsigned niter=0 ;
375  // this is the loop over the image sequence
376  while (iter < opt_first + opt_nimages*opt_step) {
377  double tms = vpTime::measureTimeMs() ;
378 
379  // set the new image name
380 
381  if (opt_ppath.empty()){
382  s.str("");
383  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
384  filename = dirname + s.str();
385  }
386  else {
387  sprintf(cfilename, opt_ppath.c_str(), iter) ;
388  filename = cfilename;
389  }
390 
391  std::cout << "read : " << filename << std::endl;
392  // read the image
393  vpImageIo::read(I, filename);
394  if (opt_display) {
395  // Display the image
396  vpDisplay::display(I) ;
397  //Flush the display
398  vpDisplay::flush(I) ;
399 
400  }
401  if (opt_wait) {
402  std::cout << "A click in the image to continue..." << std::endl;
403  // Wait for a blocking mouse click
405  }
406  else {
407  // Synchronise the loop to 40 ms
408  vpTime::wait(tms, 40) ;
409  }
410  niter++ ;
411 
412  iter += opt_step ;
413  }
414  // double tms_2 = vpTime::measureTimeMs() ;
415  // double tms_total = tms_2 - tms_1 ;
416  // std::cout << "Total Time : "<< tms_total<<std::endl;
417  return 0;
418  }
419  catch(vpException e) {
420  std::cout << "Catch an exception: " << e << std::endl;
421  return 1;
422  }
423 }
424 #else
425 int
426 main()
427 {
428  vpERROR_TRACE("You do not have X11 or GTK display functionalities...");
429 }
430 
431 #endif
#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 std::string path(const char *pathname)
Definition: vpIoTools.cpp:715
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:1994
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:79
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:206
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