ViSP
testMouseEvent.cpp
1 /****************************************************************************
2  *
3  * $Id: testMouseEvent.cpp 5230 2015-01-30 06:55:59Z 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-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
306  env_ipath = vpIoTools::getViSPImagesDataPath();
307 
308  // Set the default input path
309  if (! env_ipath.empty())
310  ipath = env_ipath;
311 
312  // Read the command line options
313  if (getOptions(argc, argv, opt_ipath, opt_ppath,opt_first, opt_nimages,
314  opt_step, opt_dtype, opt_list, opt_display, opt_click,
315  opt_click_blocking) == false) {
316  exit (-1);
317  }
318  // Print the list of video-devices available
319  if (opt_list) {
320  unsigned nbDevices = 0;
321  std::cout << "List of video-devices available: \n";
322 #if defined VISP_HAVE_GTK
323  std::cout << " GTK (use \"-t GTK\" option to use it)\n";
324  nbDevices ++;
325 #endif
326 #if defined VISP_HAVE_X11
327  std::cout << " X11 (use \"-t X11\" option to use it)\n";
328  nbDevices ++;
329 #endif
330 #if defined VISP_HAVE_GDI
331  std::cout << " GDI (use \"-t GDI\" option to use it)\n";
332  nbDevices ++;
333 #endif
334 #if defined VISP_HAVE_D3D9
335  std::cout << " D3D (use \"-t D3D\" option to use it)\n";
336  nbDevices ++;
337 #endif
338  if (!nbDevices) {
339  std::cout << " No display is available\n";
340  }
341  return (0);
342  }
343 
344  if ( ! opt_display )
345  opt_click_blocking = false; // turn off the waiting
346 
347  // Get the option values
348  if (!opt_ipath.empty())
349  ipath = opt_ipath;
350 
351  // Compare ipath and env_ipath. If they differ, we take into account
352  // the input path comming from the command line option
353  if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
354  if (ipath != env_ipath) {
355  std::cout << std::endl
356  << "WARNING: " << std::endl;
357  std::cout << " Since -i <visp image path=" << ipath << "> "
358  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
359  << " we skip the environment variable." << std::endl;
360  }
361  }
362 
363  // Test if an input path is set
364  if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty() ){
365  usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_nimages, opt_step,opt_dtype);
366  std::cerr << std::endl
367  << "ERROR:" << std::endl;
368  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
369  << std::endl
370  << " environment variable to specify the location of the " << std::endl
371  << " image path where test images are located." << std::endl
372  << " Use -p <personal image path> option if you want to "<<std::endl
373  << " use personal images." << std::endl
374  << std::endl;
375 
376  exit(-1);
377  }
378 
379  // Declare an image, this is a gray level image (unsigned char)
380  // it size is not defined yet, it will be defined when the image will
381  // read on the disk
383 
384  unsigned iter = opt_first;
385  std::ostringstream s;
386  char cfilename[FILENAME_MAX];
387 
388  if (opt_ppath.empty()){
389 
390 
391  // Warning :
392  // the image sequence is not provided with the ViSP package
393  // therefore the program will return you an error :
394  // !! vpImageIoPnm.cpp: readPGM(#210) :couldn't read file
395  // ViSP-images/cube/image.0001.pgm
396  // !! vpDotExample.cpp: main(#95) :Error while reading the image
397  // terminate called after throwing an instance of 'vpImageException'
398  //
399  // The sequence is available on the visp www site
400  // http://www.irisa.fr/lagadic/visp/visp.html
401  // in the download section. It is named "ViSP-images.tar.gz"
402 
403  // Set the path location of the image sequence
404  dirname = vpIoTools::createFilePath(ipath, "ViSP-images/cube");
405 
406  // Build the name of the image file
407 
408  s.setf(std::ios::right, std::ios::adjustfield);
409  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
410  filename = vpIoTools::createFilePath(dirname, s.str());
411  }
412  else {
413 
414  sprintf(cfilename,opt_ppath.c_str(), iter) ;
415  filename = cfilename;
416  }
417  // Read the PGM image named "filename" on the disk, and put the
418  // bitmap into the image structure I. I is initialized to the
419  // correct size
420  //
421  // exception readPGM may throw various exception if, for example,
422  // the file does not exist, or if the memory cannot be allocated
423  try{
424  vpImageIo::read(I, filename) ;
425  }
426  catch(...)
427  {
428  // an exception is throwned if an exception from readPGM has been catched
429  // here this will result in the end of the program
430  // Note that another error message has been printed from readPGM
431  // to give more information about the error
432  std::cerr << std::endl
433  << "ERROR:" << std::endl;
434  std::cerr << " Cannot read " << filename << std::endl;
435  std::cerr << " Check your -i " << ipath << " option, " << std::endl
436  << " or your -p " << opt_ppath << " option " <<std::endl
437  << " or VISP_INPUT_IMAGE_PATH environment variable"
438  << std::endl;
439  exit(-1);
440  }
441  // Create a display for the image
442  vpDisplay *display = NULL;
443 
444  switch(opt_dtype) {
445  case vpX11:
446  std::cout << "Requested X11 display functionnalities..." << std::endl;
447 #if defined VISP_HAVE_X11
448  display = new vpDisplayX;
449 #else
450  std::cout << " Sorry, X11 video device is not available.\n";
451  std::cout << "Use \"" << argv[0]
452  << " -l\" to print the list of available devices.\n";
453  return 0;
454 #endif
455  break;
456  case vpGTK:
457  std::cout << "Requested GTK display functionnalities..." << std::endl;
458 #if defined VISP_HAVE_GTK
459  display = new vpDisplayGTK;
460 #else
461  std::cout << " Sorry, GTK video device is not available.\n";
462  std::cout << "Use \"" << argv[0]
463  << " -l\" to print the list of available devices.\n";
464  return 0;
465 #endif
466  break;
467  case vpGDI:
468  std::cout << "Requested GDI display functionnalities..." << std::endl;
469 #if defined VISP_HAVE_GDI
470  display = new vpDisplayGDI;
471 #else
472  std::cout << " Sorry, GDI video device is not available.\n";
473  std::cout << "Use \"" << argv[0]
474  << " -l\" to print the list of available devices.\n";
475  return 0;
476 #endif
477  break;
478  case vpD3D:
479  std::cout << "Requested D3D display functionnalities..." << std::endl;
480 #if defined VISP_HAVE_D3D9
481  display = new vpDisplayD3D;
482 #else
483  std::cout << " Sorry, D3D video device is not available.\n";
484  std::cout << "Use \"" << argv[0]
485  << " -l\" to print the list of available devices.\n";
486  return 0;
487 #endif
488  break;
489  }
490 
491  if (opt_display) {
492  try {
493  // We open a window using either X11 or GTK or GDI.
494  // Its size is automatically defined by the image (I) size
495  display->init(I, 100, 100,"Display...") ;
496 
497  // Display the image
498  // The image class has a member that specify a pointer toward
499  // the display that has been initialized in the display declaration
500  // therefore is is no longuer necessary to make a reference to the
501  // display variable.
502  vpDisplay::display(I) ;
503  vpDisplay::flush(I) ;
504  }
505  catch(...) {
506  vpERROR_TRACE("Error while displaying the image") ;
507  delete display;
508  exit(-1);
509  }
510  }
511 
512  // double tms_1 = vpTime::measureTimeMs() ;
513  unsigned niter=0 ;
514  // this is the loop over the image sequence
515  while (iter < opt_first + opt_nimages*opt_step) {
516  try {
517  double tms = vpTime::measureTimeMs() ;
518 
519  // set the new image name
520 
521  if (opt_ppath.empty()){
522  s.str("");
523  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
524  filename = vpIoTools::createFilePath(dirname, s.str());
525  }
526  else {
527  sprintf(cfilename, opt_ppath.c_str(), iter) ;
528  filename = cfilename;
529  }
530 
531  std::cout << "read : " << filename << std::endl;
532  // read the image
533  vpImageIo::read(I, filename);
534  if (opt_display) {
535  // Display the image
536  vpDisplay::display(I) ;
537  //Flush the display
538  vpDisplay::flush(I) ;
539 
540  if (opt_click_blocking) {
541  std::cout << "A click in the image to continue..." << std::endl;
542  }
543  vpImagePoint ip;
545 
546  if (opt_click) {
547  bool pressed = vpDisplay::getClick(I, ip, button, opt_click_blocking);
548  if (pressed) {
549  switch (button) {
551  std::cout << "Left button was pressed." << std::endl;
552  break;
554  std::cout << "Middle button was pressed." << std::endl;
555  break;
557  std::cout << "Right button was pressed. Bye. " << std::endl;
558  delete display;
559  return 0; break;
560  case vpMouseButton::none: break;
561  }
562  }
563  }
564 
565  vpTime::wait(tms, 1000);
566  }
567 
568  else {
569  // Synchronise the loop to 40 ms
570  vpTime::wait(tms, 40) ;
571  }
572  niter++ ;
573  }
574  catch(...) {
575  delete display;
576  exit(-1) ;
577  }
578  iter += opt_step ;
579  }
580  delete display;
581  // double tms_2 = vpTime::measureTimeMs() ;
582  // double tms_total = tms_2 - tms_1 ;
583  // std::cout << "Total Time : "<< tms_total<<std::endl;
584 
585 }
586 #else
587 int
588 main()
589 {
590  vpERROR_TRACE("You do not have X11 or GTK display functionalities...");
591 }
592 
593 #endif
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:174
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
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
Display for windows using Direct3D.
Definition: vpDisplayD3D.h:109
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
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:93
static void read(vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:278