Visual Servoing Platform version 3.5.0
displaySequence.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 * Eric Marchand
36 * Fabien Spindler
37 * Anthony Saunier
38 *
39 *****************************************************************************/
50#include <iomanip>
51#include <sstream>
52#include <stdio.h>
53#include <stdlib.h>
54#include <visp3/core/vpConfig.h>
55#include <visp3/core/vpDebug.h>
56#include <visp3/core/vpIoTools.h>
57#include <visp3/io/vpParseArgv.h>
58#if (defined(VISP_HAVE_GTK) || defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
59
60#include <visp3/core/vpImage.h>
61#include <visp3/io/vpImageIo.h>
62
63#include <visp3/gui/vpDisplayGDI.h>
64#include <visp3/gui/vpDisplayGTK.h>
65#include <visp3/gui/vpDisplayX.h>
66
67#include <visp3/core/vpTime.h>
68
79// List of allowed command line options
80#define GETOPTARGS "di:p:hf:n:s:w"
81
82void usage(const char *name, const char *badparam, std::string ipath, std::string ppath, unsigned first,
83 unsigned nimages, unsigned step);
84bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath, unsigned &first, unsigned &nimages,
85 unsigned &step, bool &display, bool &wait);
86
100void usage(const char *name, const char *badparam, std::string ipath, std::string ppath, unsigned first,
101 unsigned nimages, unsigned step)
102{
103 fprintf(stdout, "\n\
104Read an image sequence from the disk and display it.\n\
105The sequence is made of separate images. Each image corresponds\n\
106to a PGM file.\n\
107\n\
108SYNOPSIS\n\
109 %s [-i <test image path>] [-p <personal image path>]\n\
110 [-f <first image>] [-n <number of images>] [-s <step>] \n\
111 [-w] [-d] [-h]\n \
112 ", name);
113
114 fprintf(stdout, "\n\
115 OPTIONS: Default\n\
116 -i <test image path> %s\n\
117 Set image input path.\n\
118 From this path read \"cube/image.%%04d.pgm\"\n\
119 images. These images come from ViSP-images-x.y.z.tar.gz\n\
120 available on the ViSP website.\n\
121 Setting the VISP_INPUT_IMAGE_PATH environment\n\
122 variable produces the same behaviour than using\n\
123 this option.\n\
124 \n\
125 -p <personal image path> %s\n\
126 Specify a personal sequence containing images \n\
127 to process.\n\
128 By image sequence, we mean one file per image.\n\
129 The following image file formats PNM (PGM P5, PPM P6)\n\
130 are supported. The format is selected by analysing \n\
131 the filename extension.\n\
132 Example : \"/Temp/ViSP-images/cube/image.%%04d.pgm\"\n\
133 %%04d is for the image numbering.\n\
134 \n\
135 -f <first image> %u\n\
136 First image number of the sequence.\n\
137 \n\
138 -n <number of images> %u\n\
139 Number of images to load from the sequence.\n\
140 \n\
141 -s <step> %u\n\
142 Step between two images.\n\
143\n\
144 -d \n\
145 Disable the image display. This can be useful \n\
146 for automatic tests using crontab under Unix or \n\
147 using the task manager under Windows.\n\
148\n\
149 -w\n\
150 Wait for a mouse click between two images.\n\
151 If the image display is disabled (using -d)\n\
152 this option is without effect.\n\
153\n\
154 -h\n\
155 Print the help.\n\n", ipath.c_str(), ppath.c_str(), first, nimages, step);
156
157 if (badparam)
158 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
159}
181bool getOptions(int argc, const char **argv, std::string &ipath, std::string &ppath, unsigned &first, unsigned &nimages,
182 unsigned &step, bool &display, bool &wait)
183{
184 const char *optarg_;
185 int c;
186 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
187
188 switch (c) {
189 case 'd':
190 display = false;
191 break;
192 case 'i':
193 ipath = optarg_;
194 break;
195 case 'p':
196 ppath = optarg_;
197 break;
198 case 'f':
199 first = (unsigned)atoi(optarg_);
200 break;
201 case 'n':
202 nimages = (unsigned)atoi(optarg_);
203 break;
204 case 's':
205 step = (unsigned)atoi(optarg_);
206 break;
207 case 'w':
208 wait = true;
209 break;
210 case 'h':
211 usage(argv[0], NULL, ipath, ppath, first, nimages, step);
212 return false;
213 break;
214
215 default:
216 usage(argv[0], optarg_, ipath, ppath, first, nimages, step);
217 return false;
218 break;
219 }
220 }
221
222 if ((c == 1) || (c == -1)) {
223 // standalone param or error
224 usage(argv[0], NULL, ipath, ppath, first, nimages, step);
225 std::cerr << "ERROR: " << std::endl;
226 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
227 return false;
228 }
229
230 return true;
231}
232
233int main(int argc, const char **argv)
234{
235 try {
236 std::string env_ipath;
237 std::string opt_ipath;
238 std::string ipath;
239 std::string opt_ppath;
240 std::string dirname;
241 std::string filename;
242 unsigned opt_first = 0;
243 unsigned opt_nimages = 80;
244 unsigned opt_step = 1;
245 bool opt_display = true;
246 bool opt_wait = false;
247
248 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
249 // environment variable value
251
252 // Set the default input path
253 if (!env_ipath.empty())
254 ipath = env_ipath;
255
256 // Read the command line options
257 if (getOptions(argc, argv, opt_ipath, opt_ppath, opt_first, opt_nimages, opt_step, opt_display, opt_wait) ==
258 false) {
259 exit(-1);
260 }
261
262 if (!opt_display)
263 opt_wait = false; // turn off the waiting
264
265 // Get the option values
266 if (!opt_ipath.empty())
267 ipath = opt_ipath;
268
269 // Compare ipath and env_ipath. If they differ, we take into account
270 // the input path comming from the command line option
271 if (!opt_ipath.empty() && !env_ipath.empty() && opt_ppath.empty()) {
272 if (ipath != env_ipath) {
273 std::cout << std::endl << "WARNING: " << std::endl;
274 std::cout << " Since -i <visp image path=" << ipath << "> "
275 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
276 << " we skip the environment variable." << std::endl;
277 }
278 }
279
280 // Test if an input path is set
281 if (opt_ipath.empty() && env_ipath.empty() && opt_ppath.empty()) {
282 usage(argv[0], NULL, ipath, opt_ppath, opt_first, opt_nimages, opt_step);
283 std::cerr << std::endl << "ERROR:" << std::endl;
284 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
285 << " environment variable to specify the location of the " << std::endl
286 << " image path where test images are located." << std::endl
287 << " Use -p <personal image path> option if you want to " << std::endl
288 << " use personal images." << std::endl
289 << std::endl;
290
291 exit(-1);
292 }
293
294 // Declare an image, this is a gray level image (unsigned char)
295 // it size is not defined yet, it will be defined when the image will
296 // read on the disk
298
299 unsigned iter = opt_first;
300 std::ostringstream s;
301 char cfilename[FILENAME_MAX];
302
303 if (opt_ppath.empty()) {
304
305 // Warning :
306 // the image sequence is not provided with the ViSP package
307 // therefore the program will return you an error :
308 // !! vpImageIoPnm.cpp: readPGM(#210) :couldn't read file
309 // ViSP-images/cube/image.0001.pgm
310 // !! vpDotExample.cpp: main(#95) :Error while reading the image
311 // terminate called after throwing an instance of 'vpImageException'
312 //
313 // The sequence is available on the visp www site
314 // https://visp.inria.fr/download/
315 // in the download section. It is named "ViSP-images.tar.gz"
316
317 // Set the path location of the image sequence
318 dirname = vpIoTools::createFilePath(ipath, "cube");
319
320 // Build the name of the image file
321
322 s.setf(std::ios::right, std::ios::adjustfield);
323 s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
324 filename = vpIoTools::createFilePath(dirname, s.str());
325 } else {
326 sprintf(cfilename, opt_ppath.c_str(), iter);
327 filename = cfilename;
328 }
329 // Read the PGM image named "filename" on the disk, and put the
330 // bitmap into the image structure I. I is initialized to the
331 // correct size
332 //
333 // exception readPGM may throw various exception if, for example,
334 // the file does not exist, or if the memory cannot be allocated
335 try {
336 vpImageIo::read(I, filename);
337 } catch (...) {
338 // an exception is throwned if an exception from readPGM has been
339 // catched here this will result in the end of the program Note that
340 // another error message has been printed from readPGM to give more
341 // information about the error
342 std::cerr << std::endl << "ERROR:" << std::endl;
343 std::cerr << " Cannot read " << filename << std::endl;
344 std::cerr << " Check your -i " << ipath << " option, " << std::endl
345 << " or your -p " << opt_ppath << " option " << std::endl
346 << " or VISP_INPUT_IMAGE_PATH environment variable" << std::endl;
347 exit(-1);
348 }
349
350#if defined VISP_HAVE_GTK
351 vpDisplayGTK display;
352#elif defined VISP_HAVE_X11
353 vpDisplayX display;
354#elif defined VISP_HAVE_GDI
355 vpDisplayGDI display;
356#endif
357 if (opt_display) {
358
359 // We open a window using either X11 or GTK or GDI.
360 // Its size is automatically defined by the image (I) size
361 display.init(I, 100, 100, "Display...");
362
363 // Display the image
364 // The image class has a member that specify a pointer toward
365 // the display that has been initialized in the display declaration
366 // therefore is is no longuer necessary to make a reference to the
367 // display variable.
370 }
371
372 // double tms_1 = vpTime::measureTimeMs() ;
373 unsigned niter = 0;
374 // this is the loop over the image sequence
375 while (iter < opt_first + opt_nimages * opt_step) {
376 double tms = vpTime::measureTimeMs();
377
378 // set the new image name
379
380 if (opt_ppath.empty()) {
381 s.str("");
382 s << "image." << std::setw(4) << std::setfill('0') << iter << ".pgm";
383 filename = vpIoTools::createFilePath(dirname, s.str());
384 } else {
385 sprintf(cfilename, opt_ppath.c_str(), iter);
386 filename = cfilename;
387 }
388
389 std::cout << "read : " << filename << std::endl;
390 // read the image
391 vpImageIo::read(I, filename);
392 if (opt_display) {
393 // Display the image
395 // Flush the display
397 }
398 if (opt_wait) {
399 std::cout << "A click in the image to continue..." << std::endl;
400 // Wait for a blocking mouse click
402 } else {
403 // Synchronise the loop to 40 ms
404 vpTime::wait(tms, 40);
405 }
406 niter++;
407
408 iter += opt_step;
409 }
410 // double tms_2 = vpTime::measureTimeMs() ;
411 // double tms_total = tms_2 - tms_1 ;
412 // std::cout << "Total Time : "<< tms_total<<std::endl;
413 return EXIT_SUCCESS;
414 } catch (const vpException &e) {
415 std::cout << "Catch an exception: " << e << std::endl;
416 return EXIT_FAILURE;
417 }
418}
419#else
420int main() {
421 std::cout << "You do not have X11, or GDI (Graphical Device Interface), or GTK functionalities to display images..." << std::endl;
422 std::cout << "Tip if you are on a unix-like system:" << std::endl;
423 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
424 std::cout << "Tip if you are on a windows-like system:" << std::endl;
425 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
426 return EXIT_SUCCESS;
427}
428#endif
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
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)
error that can be emited by ViSP classes.
Definition: vpException.h:72
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:149
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
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMs()