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