Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testMouseEvent.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Read an image sequence from the disk and display it.
32  *
33  * Authors:
34  * Fabien Spindler
35  * Anthony Saunier
36  *
37  *****************************************************************************/
48 #include <visp3/core/vpDebug.h>
49 #include <visp3/core/vpConfig.h>
50 #include <visp3/io/vpParseArgv.h>
51 #include <visp3/core/vpIoTools.h>
52 
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <sstream>
56 #include <iomanip>
57 
58 #if (defined (VISP_HAVE_GTK) || defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI) || defined(VISP_HAVE_D3D9))
59 
60 #include <visp3/core/vpImage.h>
61 #include <visp3/io/vpImageIo.h>
62 
63 #include <visp3/gui/vpDisplayGTK.h>
64 #include <visp3/gui/vpDisplayX.h>
65 #include <visp3/gui/vpDisplayGDI.h>
66 #include <visp3/gui/vpDisplayD3D.h>
67 #include <visp3/core/vpMouseButton.h>
68 
69 #include <visp3/core/vpTime.h>
70 
81 // List of allowed command line options
82 #define GETOPTARGS "cdi:lp:ht:f:n:s:w"
83 typedef enum {
84  vpX11,
85  vpGTK,
86  vpGDI,
87  vpD3D,
88 } vpDisplayType;
89 
90 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath,
91  unsigned first, unsigned nimages, unsigned step, vpDisplayType &dtype);
92 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath,
93  unsigned &first, unsigned &nimages, unsigned &step,
94  vpDisplayType &dtype, bool &list, bool &display, bool &click, bool &wait);
95 
110 void usage(const char *name, const char *badparam, std::string ipath, std::string ppath,
111  unsigned first, unsigned nimages, unsigned step, vpDisplayType &dtype)
112 {
113  fprintf(stdout, "\n\
114 Read an image sequence from the disk and display it.\n\
115 The sequence is made of separate images. Each image corresponds\n\
116 to a PGM file.\n\
117 \n\
118 SYNOPSIS\n\
119  %s [-i <test image path>] [-p <personal image path>]\n\
120  [-f <first image>] [-n <number of images>] [-s <step>] \n\
121  [-t <type of video device>] [-l] [-w] [-c] [-d] [-h]\n \
122  ", name);
123 
124  std::string display;
125  switch(dtype) {
126  case vpX11: display = "X11"; break;
127  case vpGTK: display = "GTK"; break;
128  case vpGDI: display = "GDI"; break;
129  case vpD3D: display = "D3D"; break;
130  }
131 
132  fprintf(stdout, "\n\
133  OPTIONS: Default\n\
134  -i <test image path> %s\n\
135  Set image input path.\n\
136  From this path read \"ViSP-images/cube/image.%%04d.pgm\"\n\
137  images. These images come from ViSP-images-x.y.z.tar.gz\n\
138  available on the ViSP website.\n\
139  Setting the VISP_INPUT_IMAGE_PATH environment\n\
140  variable produces the same behaviour than using\n\
141  this option.\n\
142  \n\
143  -p <personal image path> %s\n\
144  Specify a personal sequence containing images \n\
145  to process.\n\
146  By image sequence, we mean one file per image.\n\
147  The following image file formats PNM (PGM P5, PPM P6)\n\
148  are supported. The format is selected by analysing \n\
149  the filename extension.\n\
150  Example : \"/Temp/ViSP-images/cube/image.%%04d.pgm\"\n\
151  %%04d is for the image numbering.\n\
152  \n\
153  -f <first image> %u\n\
154  First image number of the sequence.\n\
155  \n\
156  -n <number of images> %u\n\
157  Number of images to load from the sequence.\n\
158  \n\
159  -s <step> %u\n\
160  Step between two images.\n\
161 \n\
162  -t <type of video device> \"%s\"\n\
163  String specifying the video device to use.\n\
164  Possible values:\n\
165  \"X11\": only on UNIX platforms,\n\
166  \"GTK\": on all plaforms,\n\
167  \"GDI\": only on Windows platform (Graphics Device Interface),\n\
168  \"D3D\": only on Windows platform (Direct3D).\n\
169 \n\
170  -l\n\
171  Print the list of video-devices available and exit.\n\
172 \n\
173  -c\n\
174  Disable mouse click.\n\
175 \n\
176  -d\n\
177  Disable the image display. This can be useful \n\
178  for automatic tests using crontab under Unix or \n\
179  using the task manager under Windows.\n\
180 \n\
181  -w\n\
182  Wait for a mouse click between two images.\n\
183  If the image display is disabled (using -d)\n\
184  this option is without effect.\n\
185 \n\
186  -h\n\
187  Print the help.\n\n",
188  ipath.c_str(),ppath.c_str(), first, nimages, step, display.c_str());
189 
190  if (badparam)
191  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
192 }
217 bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath,
218  unsigned &first, unsigned &nimages, unsigned &step,
219  vpDisplayType &dtype, bool &list, bool &display, bool &click, bool &wait)
220 {
221  const char *optarg_;
222  int c;
223  std::string sDisplayType;
224  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
225 
226  switch (c) {
227  case 'c': click = false; break;
228  case 'd': display = false; break;
229  case 't': sDisplayType = optarg_;
230  // Parse the display type option
231  if (sDisplayType.compare("X11") == 0) {
232  dtype = vpX11;
233  }
234  else if (sDisplayType.compare("GTK") == 0) {
235  dtype = vpGTK;
236  }
237  else if (sDisplayType.compare("GDI") == 0) {
238  dtype = vpGDI;
239  }
240  else if (sDisplayType.compare("D3D") == 0) {
241  dtype = vpD3D;
242  }
243 
244  break;
245  case 'i': ipath = optarg_; break;
246  case 'l': list = true; break;
247  case 'p': ppath = optarg_; break;
248  case 'f': first = (unsigned) atoi(optarg_); break;
249  case 'n': nimages = (unsigned) atoi(optarg_); break;
250  case 's': step = (unsigned) atoi(optarg_); break;
251  case 'w': wait = true; break;
252  case 'h': usage(argv[0], NULL, ipath, ppath, first, nimages, step, dtype);
253  return false; break;
254 
255  default:
256  usage(argv[0], optarg_, ipath, ppath, first, nimages, step, dtype);
257  return false; break;
258  }
259  }
260 
261  if ((c == 1) || (c == -1)) {
262  // standalone param or error
263  usage(argv[0], NULL, ipath, ppath, first, nimages, step, dtype);
264  std::cerr << "ERROR: " << std::endl;
265  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
266  return false;
267  }
268 
269  return true;
270 }
271 
272 int
273 main(int argc, const char ** argv)
274 {
275  std::string env_ipath;
276  std::string opt_ipath;
277  std::string ipath;
278  std::string opt_ppath;
279  std::string dirname;
280  std::string filename;
281  unsigned opt_first = 30;
282  unsigned opt_nimages = 10;
283  unsigned opt_step = 1;
284  vpDisplayType opt_dtype; // Type of display to use
285  bool opt_list = false; // To print the list of video devices
286  bool opt_display = true;
287  bool opt_click = true;
288  bool opt_click_blocking = false;
289 
290  // Default display is one available
291 #if defined VISP_HAVE_GTK
292  opt_dtype = vpGTK;
293 #elif defined VISP_HAVE_X11
294  opt_dtype = vpX11;
295 #elif defined VISP_HAVE_GDI
296  opt_dtype = vpGDI;
297 #elif defined VISP_HAVE_D3D9
298  opt_dtype = vpD3D;
299 #endif
300 
301  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
302  env_ipath = vpIoTools::getViSPImagesDataPath();
303 
304  // Set the default input path
305  if (! env_ipath.empty())
306  ipath = env_ipath;
307 
308  // Read the command line options
309  if (getOptions(argc, argv, opt_ipath, opt_ppath,opt_first, opt_nimages,
310  opt_step, opt_dtype, opt_list, opt_display, opt_click,
311  opt_click_blocking) == false) {
312  exit (-1);
313  }
314  // Print the list of video-devices available
315  if (opt_list) {
316  unsigned nbDevices = 0;
317  std::cout << "List of video-devices available: \n";
318 #if defined VISP_HAVE_GTK
319  std::cout << " GTK (use \"-t GTK\" option to use it)\n";
320  nbDevices ++;
321 #endif
322 #if defined VISP_HAVE_X11
323  std::cout << " X11 (use \"-t X11\" option to use it)\n";
324  nbDevices ++;
325 #endif
326 #if defined VISP_HAVE_GDI
327  std::cout << " GDI (use \"-t GDI\" option to use it)\n";
328  nbDevices ++;
329 #endif
330 #if defined VISP_HAVE_D3D9
331  std::cout << " D3D (use \"-t D3D\" option to use it)\n";
332  nbDevices ++;
333 #endif
334  if (!nbDevices) {
335  std::cout << " No display is available\n";
336  }
337  return (0);
338  }
339 
340  if ( ! opt_display )
341  opt_click_blocking = false; // turn off the waiting
342 
343  // Get the option values
344  if (!opt_ipath.empty())
345  ipath = opt_ipath;
346 
347  // Compare ipath and env_ipath. If they differ, we take into account
348  // the input path comming from the command line option
349  if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
350  if (ipath != env_ipath) {
351  std::cout << std::endl
352  << "WARNING: " << std::endl;
353  std::cout << " Since -i <visp image path=" << ipath << "> "
354  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
355  << " we skip the environment variable." << std::endl;
356  }
357  }
358 
359  // Test if an input path is set
360  if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty() ){
361  usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_nimages, opt_step,opt_dtype);
362  std::cerr << std::endl
363  << "ERROR:" << std::endl;
364  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
365  << std::endl
366  << " environment variable to specify the location of the " << std::endl
367  << " image path where test images are located." << std::endl
368  << " Use -p <personal image path> option if you want to "<<std::endl
369  << " use personal images." << std::endl
370  << std::endl;
371 
372  exit(-1);
373  }
374 
375  // Declare an image, this is a gray level image (unsigned char)
376  // it size is not defined yet, it will be defined when the image will
377  // read on the disk
379 
380  unsigned iter = opt_first;
381  std::ostringstream s;
382  char cfilename[FILENAME_MAX];
383 
384  if (opt_ppath.empty()){
385 
386 
387  // Warning :
388  // the image sequence is not provided with the ViSP package
389  // therefore the program will return you an error :
390  // !! vpImageIoPnm.cpp: readPGM(#210) :couldn't read file
391  // ViSP-images/cube/image.0001.pgm
392  // !! vpDotExample.cpp: main(#95) :Error while reading the image
393  // terminate called after throwing an instance of 'vpImageException'
394  //
395  // The sequence is available on the visp www site
396  // http://www.irisa.fr/lagadic/visp/visp.html
397  // in the download section. It is named "ViSP-images.tar.gz"
398 
399  // Set the path location of the image sequence
400  dirname = vpIoTools::createFilePath(ipath, "ViSP-images/cube");
401 
402  // Build the name of the image file
403 
404  s.setf(std::ios::right, std::ios::adjustfield);
405  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
406  filename = vpIoTools::createFilePath(dirname, s.str());
407  }
408  else {
409 
410  sprintf(cfilename,opt_ppath.c_str(), iter) ;
411  filename = cfilename;
412  }
413  // Read the PGM image named "filename" on the disk, and put the
414  // bitmap into the image structure I. I is initialized to the
415  // correct size
416  //
417  // exception readPGM may throw various exception if, for example,
418  // the file does not exist, or if the memory cannot be allocated
419  try{
420  vpImageIo::read(I, filename) ;
421  }
422  catch(...)
423  {
424  // an exception is throwned if an exception from readPGM has been catched
425  // here this will result in the end of the program
426  // Note that another error message has been printed from readPGM
427  // to give more information about the error
428  std::cerr << std::endl
429  << "ERROR:" << std::endl;
430  std::cerr << " Cannot read " << filename << std::endl;
431  std::cerr << " Check your -i " << ipath << " option, " << std::endl
432  << " or your -p " << opt_ppath << " option " <<std::endl
433  << " or VISP_INPUT_IMAGE_PATH environment variable"
434  << std::endl;
435  exit(-1);
436  }
437  // Create a display for the image
438  vpDisplay *display = NULL;
439 
440  switch(opt_dtype) {
441  case vpX11:
442  std::cout << "Requested X11 display functionnalities..." << std::endl;
443 #if defined VISP_HAVE_X11
444  display = new vpDisplayX;
445 #else
446  std::cout << " Sorry, X11 video device is not available.\n";
447  std::cout << "Use \"" << argv[0]
448  << " -l\" to print the list of available devices.\n";
449  return 0;
450 #endif
451  break;
452  case vpGTK:
453  std::cout << "Requested GTK display functionnalities..." << std::endl;
454 #if defined VISP_HAVE_GTK
455  display = new vpDisplayGTK;
456 #else
457  std::cout << " Sorry, GTK video device is not available.\n";
458  std::cout << "Use \"" << argv[0]
459  << " -l\" to print the list of available devices.\n";
460  return 0;
461 #endif
462  break;
463  case vpGDI:
464  std::cout << "Requested GDI display functionnalities..." << std::endl;
465 #if defined VISP_HAVE_GDI
466  display = new vpDisplayGDI;
467 #else
468  std::cout << " Sorry, GDI video device is not available.\n";
469  std::cout << "Use \"" << argv[0]
470  << " -l\" to print the list of available devices.\n";
471  return 0;
472 #endif
473  break;
474  case vpD3D:
475  std::cout << "Requested D3D display functionnalities..." << std::endl;
476 #if defined VISP_HAVE_D3D9
477  display = new vpDisplayD3D;
478 #else
479  std::cout << " Sorry, D3D video device is not available.\n";
480  std::cout << "Use \"" << argv[0]
481  << " -l\" to print the list of available devices.\n";
482  return 0;
483 #endif
484  break;
485  }
486 
487  if (opt_display) {
488  try {
489  // We open a window using either X11 or GTK or GDI.
490  // Its size is automatically defined by the image (I) size
491  display->init(I, 100, 100,"Display...") ;
492 
493  // Display the image
494  // The image class has a member that specify a pointer toward
495  // the display that has been initialized in the display declaration
496  // therefore is is no longuer necessary to make a reference to the
497  // display variable.
498  vpDisplay::display(I) ;
499  vpDisplay::flush(I) ;
500  }
501  catch(...) {
502  vpERROR_TRACE("Error while displaying the image") ;
503  delete display;
504  exit(-1);
505  }
506  }
507 
508  // double tms_1 = vpTime::measureTimeMs() ;
509  unsigned niter=0 ;
510  // this is the loop over the image sequence
511  while (iter < opt_first + opt_nimages*opt_step) {
512  try {
513  double tms = vpTime::measureTimeMs() ;
514 
515  // set the new image name
516 
517  if (opt_ppath.empty()){
518  s.str("");
519  s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
520  filename = vpIoTools::createFilePath(dirname, s.str());
521  }
522  else {
523  sprintf(cfilename, opt_ppath.c_str(), iter) ;
524  filename = cfilename;
525  }
526 
527  std::cout << "read : " << filename << std::endl;
528  // read the image
529  vpImageIo::read(I, filename);
530  if (opt_display) {
531  // Display the image
532  vpDisplay::display(I) ;
533  //Flush the display
534  vpDisplay::flush(I) ;
535 
536  if (opt_click_blocking) {
537  std::cout << "A click in the image to continue..." << std::endl;
538  }
539  vpImagePoint ip;
541 
542  if (opt_click) {
543  bool pressed = vpDisplay::getClick(I, ip, button, opt_click_blocking);
544  if (pressed) {
545  switch (button) {
547  std::cout << "Left button was pressed." << std::endl;
548  break;
550  std::cout << "Middle button was pressed." << std::endl;
551  break;
553  std::cout << "Right button was pressed. Bye. " << std::endl;
554  delete display;
555  return 0; break;
556  case vpMouseButton::none: 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
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:157
Class that defines generic functionnalities for display.
Definition: vpDisplay.h:169
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
#define vpERROR_TRACE
Definition: vpDebug.h:391
vpDisplayGDI()
Basic constructor.
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:153
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
Definition: vpDisplayD3D.h:107
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1366
static void display(const vpImage< unsigned char > &I)
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:205
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88