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