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