ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Modules Pages
testMouseEvent.cpp
1 /****************************************************************************
2  *
3  * $Id: testMouseEvent.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  * Fabien Spindler
39  * Anthony Saunier
40  *
41  *****************************************************************************/
52 #include <visp/vpDebug.h>
53 #include <visp/vpConfig.h>
54 #include <visp/vpParseArgv.h>
55 #include <visp/vpIoTools.h>
56 
57 #include <stdlib.h>
58 #include <stdio.h>
59 #include <sstream>
60 #include <iomanip>
61 
62 #if (defined (VISP_HAVE_GTK) || defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9))
63 
64 #include <visp/vpImage.h>
65 #include <visp/vpImageIo.h>
66 
67 #include <visp/vpDisplayGTK.h>
68 #include <visp/vpDisplayX.h>
69 #include <visp/vpDisplayGDI.h>
70 #include <visp/vpDisplayD3D.h>
71 #include <visp/vpMouseButton.h>
72 
73 #include <visp/vpTime.h>
74 
85 // List of allowed command line options
86 #define GETOPTARGS "cdi:lp:ht:f:n:s:w"
87 typedef enum {
88  vpX11,
89  vpGTK,
90  vpGDI,
91  vpD3D,
92 } vpDisplayType;
93 
94 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath,
95  unsigned first, unsigned nimages, unsigned step, vpDisplayType &dtype);
96 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath,
97  unsigned &first, unsigned &nimages, unsigned &step,
98  vpDisplayType &dtype, bool &list, bool &display, bool &click, bool &wait);
99 
114 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath,
115  unsigned first, unsigned nimages, unsigned step, vpDisplayType &dtype)
116 {
117  fprintf(stdout, "\n\
118 Read an image sequence from the disk and display it.\n\
119 The sequence is made of separate images. Each image corresponds\n\
120 to a PGM file.\n\
121 \n\
122 SYNOPSIS\n\
123  %s [-i <test image path>] [-p <personal image path>]\n\
124  [-f <first image>] [-n <number of images>] [-s <step>] \n\
125  [-t <type of video device>] [-l] [-w] [-c] [-d] [-h]\n \
126  ", name);
127 
128  std::string display;
129  switch(dtype) {
130  case vpX11: display = "X11"; break;
131  case vpGTK: display = "GTK"; break;
132  case vpGDI: display = "GDI"; break;
133  case vpD3D: display = "D3D"; break;
134  }
135 
136  fprintf(stdout, "\n\
137  OPTIONS: Default\n\
138  -i <test image path> %s\n\
139  Set image input path.\n\
140  From this path read \"ViSP-images/cube/image.%%04d.pgm\"\n\
141  images. These images come from ViSP-images-x.y.z.tar.gz\n\
142  available on the ViSP website.\n\
143  Setting the VISP_INPUT_IMAGE_PATH environment\n\
144  variable produces the same behaviour than using\n\
145  this option.\n\
146  \n\
147  -p <personal image path> %s\n\
148  Specify a personal sequence containing images \n\
149  to process.\n\
150  By image sequence, we mean one file per image.\n\
151  The following image file formats PNM (PGM P5, PPM P6)\n\
152  are supported. The format is selected by analysing \n\
153  the filename extension.\n\
154  Example : \"/Temp/ViSP-images/cube/image.%%04d.pgm\"\n\
155  %%04d is for the image numbering.\n\
156  \n\
157  -f <first image> %u\n\
158  First image number of the sequence.\n\
159  \n\
160  -n <number of images> %u\n\
161  Number of images to load from the sequence.\n\
162  \n\
163  -s <step> %u\n\
164  Step between two images.\n\
165 \n\
166  -t <type of video device> \"%s\"\n\
167  String specifying the video device to use.\n\
168  Possible values:\n\
169  \"X11\": only on UNIX platforms,\n\
170  \"GTK\": on all plaforms,\n\
171  \"GDI\": only on Windows platform (Graphics Device Interface),\n\
172  \"D3D\": only on Windows platform (Direct3D).\n\
173 \n\
174  -l\n\
175  Print the list of video-devices available and exit.\n\
176 \n\
177  -c\n\
178  Disable mouse click.\n\
179 \n\
180  -d\n\
181  Disable the image display. This can be useful \n\
182  for automatic tests using crontab under Unix or \n\
183  using the task manager under Windows.\n\
184 \n\
185  -w\n\
186  Wait for a mouse click between two images.\n\
187  If the image display is disabled (using -d)\n\
188  this option is without effect.\n\
189 \n\
190  -h\n\
191  Print the help.\n\n",
192  ipath.c_str(),ppath.c_str(), first, nimages, step, display.c_str());
193 
194  if (badparam)
195  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
196 }
221 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath,
222  unsigned &first, unsigned &nimages, unsigned &step,
223  vpDisplayType &dtype, bool &list, bool &display, bool &click, bool &wait)
224 {
225  const char *optarg_;
226  int c;
227  std::string sDisplayType;
228  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
229 
230  switch (c) {
231  case 'c': click = false; break;
232  case 'd': display = false; break;
233  case 't': sDisplayType = optarg_;
234  // Parse the display type option
235  if (sDisplayType.compare("X11") == 0) {
236  dtype = vpX11;
237  }
238  else if (sDisplayType.compare("GTK") == 0) {
239  dtype = vpGTK;
240  }
241  else if (sDisplayType.compare("GDI") == 0) {
242  dtype = vpGDI;
243  }
244  else if (sDisplayType.compare("D3D") == 0) {
245  dtype = vpD3D;
246  }
247 
248  break;
249  case 'i': ipath = optarg_; break;
250  case 'l': list = true; break;
251  case 'p': ppath = optarg_; break;
252  case 'f': first = (unsigned) atoi(optarg_); break;
253  case 'n': nimages = (unsigned) atoi(optarg_); break;
254  case 's': step = (unsigned) atoi(optarg_); break;
255  case 'w': wait = true; break;
256  case 'h': usage(argv[0], NULL, ipath, ppath, first, nimages, step, dtype);
257  return false; break;
258 
259  default:
260  usage(argv[0], optarg_, ipath, ppath, first, nimages, step, dtype);
261  return false; break;
262  }
263  }
264 
265  if ((c == 1) || (c == -1)) {
266  // standalone param or error
267  usage(argv[0], NULL, ipath, ppath, first, nimages, step, dtype);
268  std::cerr << "ERROR: " << std::endl;
269  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
270  return false;
271  }
272 
273  return true;
274 }
275 
276 int
277 main(int argc, const char ** argv)
278 {
279  std::string env_ipath;
280  std::string opt_ipath;
281  std::string ipath;
282  std::string opt_ppath;
283  std::string dirname;
284  std::string filename;
285  unsigned opt_first = 30;
286  unsigned opt_nimages = 10;
287  unsigned opt_step = 1;
288  vpDisplayType opt_dtype; // Type of display to use
289  bool opt_list = false; // To print the list of video devices
290  bool opt_display = true;
291  bool opt_click = true;
292  bool opt_click_blocking = false;
293 
294  // Default display is one available
295 #if defined VISP_HAVE_GTK
296  opt_dtype = vpGTK;
297 #elif defined VISP_HAVE_X11
298  opt_dtype = vpX11;
299 #elif defined VISP_HAVE_GDI
300  opt_dtype = vpGDI;
301 #elif defined VISP_HAVE_D3D9
302  opt_dtype = vpD3D;
303 #endif
304 
305  // Get the VISP_IMAGE_PATH environment variable value
306  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
307  if (ptenv != NULL)
308  env_ipath = ptenv;
309 
310  // Set the default input path
311  if (! env_ipath.empty())
312  ipath = env_ipath;
313 
314  // Read the command line options
315  if (getOptions(argc, argv, opt_ipath, opt_ppath,opt_first, opt_nimages,
316  opt_step, opt_dtype, opt_list, opt_display, opt_click,
317  opt_click_blocking) == false) {
318  exit (-1);
319  }
320  // Print the list of video-devices available
321  if (opt_list) {
322  unsigned nbDevices = 0;
323  std::cout << "List of video-devices available: \n";
324 #if defined VISP_HAVE_GTK
325  std::cout << " GTK (use \"-t GTK\" option to use it)\n";
326  nbDevices ++;
327 #endif
328 #if defined VISP_HAVE_X11
329  std::cout << " X11 (use \"-t X11\" option to use it)\n";
330  nbDevices ++;
331 #endif
332 #if defined VISP_HAVE_GDI
333  std::cout << " GDI (use \"-t GDI\" option to use it)\n";
334  nbDevices ++;
335 #endif
336 #if defined VISP_HAVE_D3D9
337  std::cout << " D3D (use \"-t D3D\" option to use it)\n";
338  nbDevices ++;
339 #endif
340  if (!nbDevices) {
341  std::cout << " No display is available\n";
342  }
343  return (0);
344  }
345 
346  if ( ! opt_display )
347  opt_click_blocking = false; // turn off the waiting
348 
349  // Get the option values
350  if (!opt_ipath.empty())
351  ipath = opt_ipath;
352 
353  // Compare ipath and env_ipath. If they differ, we take into account
354  // the input path comming from the command line option
355  if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
356  if (ipath != env_ipath) {
357  std::cout << std::endl
358  << "WARNING: " << std::endl;
359  std::cout << " Since -i <visp image path=" << ipath << "> "
360  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
361  << " we skip the environment variable." << std::endl;
362  }
363  }
364 
365  // Test if an input path is set
366  if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty() ){
367  usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_nimages, opt_step,opt_dtype);
368  std::cerr << std::endl
369  << "ERROR:" << std::endl;
370  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
371  << std::endl
372  << " environment variable to specify the location of the " << std::endl
373  << " image path where test images are located." << std::endl
374  << " Use -p <personal image path> option if you want to "<<std::endl
375  << " use personal images." << std::endl
376  << std::endl;
377 
378  exit(-1);
379  }
380 
381  // Declare an image, this is a gray level image (unsigned char)
382  // it size is not defined yet, it will be defined when the image will
383  // read on the disk
385 
386  unsigned iter = opt_first;
387  std::ostringstream s;
388  char cfilename[FILENAME_MAX];
389 
390  if (opt_ppath.empty()){
391 
392 
393  // Warning :
394  // the image sequence is not provided with the ViSP package
395  // therefore the program will return you an error :
396  // !! vpImageIoPnm.cpp: readPGM(#210) :couldn't read file
397  // ViSP-images/cube/image.0001.pgm
398  // !! vpDotExample.cpp: main(#95) :Error while reading the image
399  // terminate called after throwing an instance of 'vpImageException'
400  //
401  // The sequence is available on the visp www site
402  // http://www.irisa.fr/lagadic/visp/visp.html
403  // in the download section. It is named "ViSP-images.tar.gz"
404 
405  // Set the path location of the image sequence
406  dirname = ipath + vpIoTools::path("/ViSP-images/cube/");
407 
408  // Build the name of the image file
409 
410  s.setf(std::ios::right, std::ios::adjustfield);
411  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
412  filename = dirname + s.str();
413  }
414  else {
415 
416  sprintf(cfilename,opt_ppath.c_str(), iter) ;
417  filename = cfilename;
418  }
419  // Read the PGM image named "filename" on the disk, and put the
420  // bitmap into the image structure I. I is initialized to the
421  // correct size
422  //
423  // exception readPGM may throw various exception if, for example,
424  // the file does not exist, or if the memory cannot be allocated
425  try{
426  vpImageIo::read(I, filename) ;
427  }
428  catch(...)
429  {
430  // an exception is throwned if an exception from readPGM has been catched
431  // here this will result in the end of the program
432  // Note that another error message has been printed from readPGM
433  // to give more information about the error
434  std::cerr << std::endl
435  << "ERROR:" << std::endl;
436  std::cerr << " Cannot read " << filename << std::endl;
437  std::cerr << " Check your -i " << ipath << " option, " << std::endl
438  << " or your -p " << opt_ppath << " option " <<std::endl
439  << " or VISP_INPUT_IMAGE_PATH environment variable"
440  << std::endl;
441  exit(-1);
442  }
443  // Create a display for the image
444  vpDisplay *display = NULL;
445 
446  switch(opt_dtype) {
447  case vpX11:
448  std::cout << "Requested X11 display functionnalities..." << std::endl;
449 #if defined VISP_HAVE_X11
450  display = new vpDisplayX;
451 #else
452  std::cout << " Sorry, X11 video device is not available.\n";
453  std::cout << "Use \"" << argv[0]
454  << " -l\" to print the list of available devices.\n";
455  return 0;
456 #endif
457  break;
458  case vpGTK:
459  std::cout << "Requested GTK display functionnalities..." << std::endl;
460 #if defined VISP_HAVE_GTK
461  display = new vpDisplayGTK;
462 #else
463  std::cout << " Sorry, GTK video device is not available.\n";
464  std::cout << "Use \"" << argv[0]
465  << " -l\" to print the list of available devices.\n";
466  return 0;
467 #endif
468  break;
469  case vpGDI:
470  std::cout << "Requested GDI display functionnalities..." << std::endl;
471 #if defined VISP_HAVE_GDI
472  display = new vpDisplayGDI;
473 #else
474  std::cout << " Sorry, GDI video device is not available.\n";
475  std::cout << "Use \"" << argv[0]
476  << " -l\" to print the list of available devices.\n";
477  return 0;
478 #endif
479  break;
480  case vpD3D:
481  std::cout << "Requested D3D display functionnalities..." << std::endl;
482 #if defined VISP_HAVE_D3D9
483  display = new vpDisplayD3D;
484 #else
485  std::cout << " Sorry, D3D video device is not available.\n";
486  std::cout << "Use \"" << argv[0]
487  << " -l\" to print the list of available devices.\n";
488  return 0;
489 #endif
490  break;
491  }
492 
493  if (opt_display) {
494  try {
495  // We open a window using either X11 or GTK or GDI.
496  // Its size is automatically defined by the image (I) size
497  display->init(I, 100, 100,"Display...") ;
498 
499  // Display the image
500  // The image class has a member that specify a pointer toward
501  // the display that has been initialized in the display declaration
502  // therefore is is no longuer necessary to make a reference to the
503  // display variable.
504  vpDisplay::display(I) ;
505  vpDisplay::flush(I) ;
506  }
507  catch(...) {
508  vpERROR_TRACE("Error while displaying the image") ;
509  delete display;
510  exit(-1);
511  }
512  }
513 
514 // double tms_1 = vpTime::measureTimeMs() ;
515  unsigned niter=0 ;
516  // this is the loop over the image sequence
517  while (iter < opt_first + opt_nimages*opt_step) {
518  try {
519  double tms = vpTime::measureTimeMs() ;
520 
521  // set the new image name
522 
523  if (opt_ppath.empty()){
524  s.str("");
525  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
526  filename = dirname + s.str();
527  }
528  else {
529  sprintf(cfilename, opt_ppath.c_str(), iter) ;
530  filename = cfilename;
531  }
532 
533  std::cout << "read : " << filename << std::endl;
534  // read the image
535  vpImageIo::read(I, filename);
536  if (opt_display) {
537  // Display the image
538  vpDisplay::display(I) ;
539  //Flush the display
540  vpDisplay::flush(I) ;
541 
542  if (opt_click_blocking) {
543  std::cout << "A click in the image to continue..." << std::endl;
544  }
545  vpImagePoint ip;
547 
548  if (opt_click) {
549  bool pressed = vpDisplay::getClick(I, ip, button, opt_click_blocking);
550  if (pressed) {
551  switch (button) {
553  std::cout << "Left button was pressed." << std::endl;
554  break;
556  std::cout << "Middle button was pressed." << std::endl;
557  break;
559  std::cout << "Right button was pressed. Bye. " << std::endl;
560  delete display;
561  return 0; break;
562  }
563  }
564  }
565 
566  vpTime::wait(tms, 1000);
567  }
568 
569  else {
570  // Synchronise the loop to 40 ms
571  vpTime::wait(tms, 40) ;
572  }
573  niter++ ;
574  }
575  catch(...) {
576  delete display;
577  exit(-1) ;
578  }
579  iter += opt_step ;
580  }
581  delete display;
582 // double tms_2 = vpTime::measureTimeMs() ;
583 // double tms_total = tms_2 - tms_1 ;
584 // std::cout << "Total Time : "<< tms_total<<std::endl;
585 
586 }
587 #else
588 int
589 main()
590 {
591  vpERROR_TRACE("You do not have X11 or GTK display functionalities...");
592 }
593 
594 #endif
595 
596 /*
597  * Local variables:
598  * c-basic-offset: 2
599  * End:
600  */
virtual void init(vpImage< unsigned char > &I, int x=-1, int y=-1, const char *title=NULL)=0
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:176
#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
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
Display for windows using Direct3D.
Definition: vpDisplayD3D.h:109
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
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
static void read(vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:278