Visual Servoing Platform version 3.5.0
grabDisk.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 *
38 *****************************************************************************/
39
40#include <stdlib.h>
41#include <visp3/core/vpConfig.h>
42#include <visp3/core/vpDebug.h>
43#if (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
44
45#include <visp3/core/vpDisplay.h>
46#include <visp3/core/vpImage.h>
47#include <visp3/core/vpIoTools.h>
48#include <visp3/core/vpTime.h>
49#include <visp3/gui/vpDisplayGDI.h>
50#include <visp3/gui/vpDisplayX.h>
51#include <visp3/io/vpDiskGrabber.h>
52#include <visp3/io/vpParseArgv.h>
53
64// List of allowed command line options
65#define GETOPTARGS "b:de:f:i:hn:s:z:"
66
67void usage(const char *name, const char *badparam, std::string ipath, std::string basename, std::string ext, int first,
68 unsigned int nimages, int step, unsigned int nzero);
69bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename, std::string &ext, int &first,
70 unsigned int &nimages, int &step, unsigned int &nzero, bool &display);
71
72/*
73
74 Print the program options.
75
76 \param name : Program name.
77 \param badparam : Bad parameter name.
78 \param ipath : Input image path.
79 \param basename : Input image base name.
80 \param ext : Input image extension.
81 \param first : First image number to read.
82 \param nimages : Number of images to read.
83 \param step : Step between two successive images to read.
84 \param nzero : Number of zero for the image number coding.
85
86 */
87void usage(const char *name, const char *badparam, std::string ipath, std::string basename, std::string ext, int first,
88 unsigned int nimages, int step, unsigned int nzero)
89{
90 fprintf(stdout, "\n\
91Read an image sequence from the disk. Display it using X11 or GTK.\n\
92The sequence is made of separate images. Each image corresponds\n\
93to a PGM file.\n\
94\n\
95SYNOPSIS\n\
96 %s [-i <input image path>] [-b <base name>] [-e <extension>] \n\
97 [-f <first frame>] [-n <number of images> [-s <step>] \n\
98 [-z <number of zero>] [-d] [-h]\n", name);
99
100 fprintf(stdout, "\n\
101OPTIONS: Default\n\
102 -i <input image path> %s\n\
103 Set image input path.\n\
104 From this path read \"cube/image.%%04d.pgm\"\n\
105 images.\n\
106 Setting the VISP_INPUT_IMAGE_PATH environment\n\
107 variable produces the same behaviour than using\n\
108 this option.\n\
109\n\
110 -b <base name> %s\n\
111 Specify the base name of the files of the sequence\n\
112 containing the images to process. \n\
113 By image sequence, we mean one file per image.\n\
114 The following image file formats PNM (PGM P5, PPM P6)\n\
115 are supported. The format is selected by analysing \n\
116 the filename extension.\n\
117\n\
118 -e <extension> %s\n\
119 Specify the extension of the files.\n\
120 Not taken into account for the moment. Will be a\n\
121 future feature...\n\
122\n\
123 -f <first frame> %d\n\
124 First frame number of the sequence\n\
125\n\
126 -n <number of images> %u\n\
127 Number of images to load from the sequence.\n\
128\n\
129 -s <step> %d\n\
130 Step between two images.\n\
131\n\
132 -z <number of zero> %u\n\
133 Number of digits to encode the image number.\n\
134\n\
135 -d \n\
136 Turn off the display.\n\
137\n\
138 -h \n\
139 Print the help.\n\n", ipath.c_str(), basename.c_str(), ext.c_str(), first, nimages, step, nzero);
140
141 if (badparam)
142 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
143}
162bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename, std::string &ext, int &first,
163 unsigned int &nimages, int &step, unsigned int &nzero, bool &display)
164{
165 const char *optarg_;
166 int c;
167 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
168
169 switch (c) {
170 case 'b':
171 basename = optarg_;
172 break;
173 case 'd':
174 display = false;
175 break;
176 case 'e':
177 ext = optarg_;
178 break;
179 case 'f':
180 first = atoi(optarg_);
181 break;
182 case 'i':
183 ipath = optarg_;
184 break;
185 case 'n':
186 nimages = (unsigned)atoi(optarg_);
187 break;
188 case 's':
189 step = atoi(optarg_);
190 break;
191 case 'z':
192 nzero = (unsigned)atoi(optarg_);
193 break;
194 case 'h':
195 usage(argv[0], NULL, ipath, basename, ext, first, nimages, step, nzero);
196 return false;
197 break;
198
199 default:
200 usage(argv[0], optarg_, ipath, basename, ext, first, nimages, step, nzero);
201 return false;
202 break;
203 }
204 }
205
206 if ((c == 1) || (c == -1)) {
207 // standalone param or error
208 usage(argv[0], NULL, ipath, basename, ext, first, nimages, step, nzero);
209 std::cerr << "ERROR: " << std::endl;
210 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
211 return false;
212 }
213
214 return true;
215}
216
226int main(int argc, const char **argv)
227{
228 try {
229 std::string env_ipath;
230 std::string opt_ipath;
231 std::string ipath;
232 std::string opt_basename = "cube/image.";
233 std::string opt_ext = "pgm";
234 bool opt_display = true;
235
236 int opt_first = 5;
237 unsigned int opt_nimages = 70;
238 int opt_step = 1;
239 unsigned int opt_nzero = 4;
240
241 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
242 // environment variable value
244
245 // Set the default input path
246 if (!env_ipath.empty())
247 ipath = env_ipath;
248
249 // Read the command line options
250 if (getOptions(argc, argv, opt_ipath, opt_basename, opt_ext, opt_first, opt_nimages, opt_step, opt_nzero,
251 opt_display) == false) {
252 exit(-1);
253 }
254
255 // Get the option values
256 if (!opt_ipath.empty())
257 ipath = opt_ipath;
258
259 // Compare ipath and env_ipath. If they differ, we take into account
260 // the input path comming from the command line option
261 if (!opt_ipath.empty() && !env_ipath.empty()) {
262 if (ipath != env_ipath) {
263 std::cout << std::endl << "WARNING: " << std::endl;
264 std::cout << " Since -i <visp image path=" << ipath << "> "
265 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
266 << " we skip the environment variable." << std::endl;
267 }
268 }
269
270 // Test if an input path is set
271 if (opt_ipath.empty() && env_ipath.empty()) {
272 usage(argv[0], NULL, ipath, opt_basename, opt_ext, opt_first, opt_nimages, opt_step, opt_nzero);
273 std::cerr << std::endl << "ERROR:" << std::endl;
274 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
275 << " environment variable to specify the location of the " << std::endl
276 << " image path where test images are located." << std::endl
277 << std::endl;
278 exit(-1);
279 }
280
281 // Declare an image, this is a gray level image (unsigned char)
282 // it size is not defined yet, it will be defined when the image will
283 // read on the disk
285
286 // Declare a framegrabber able to read a sequence of successive
287 // images from the disk
289
290 // Set the path to the directory containing the sequence
291 g.setDirectory(ipath.c_str());
292 // Set the image base name. The directory and the base name constitute
293 // the constant part of the full filename
294 g.setBaseName(opt_basename.c_str());
295 // Set the step between two images of the sequence
296 g.setStep(opt_step);
297 // Set the number of digits to build the image number
298 g.setNumberOfZero(opt_nzero);
299 // Set the first frame number of the sequence
300 g.setImageNumber(opt_first);
301 // Set the image extension
302 g.setExtension(opt_ext.c_str());
303
304 // Open the framegrabber by loading the first image of the sequence
305 g.open(I);
306
307 std::cout << "Image size: width : " << I.getWidth() << " height: " << I.getHeight() << std::endl;
308
309// We open a window using either X11 or GDI.
310// Its size is automatically defined by the image (I) size
311#if defined(VISP_HAVE_X11)
312 vpDisplayX display(I);
313#elif defined(VISP_HAVE_GDI)
314 vpDisplayGDI display(I);
315#else
316 std::cout << "No image viewer is available..." << std::endl;
317#endif
318
319 if (opt_display) {
320 display.init(I, 100, 100, "Disk Framegrabber");
321
322 // display the image
323 // The image class has a member that specify a pointer toward
324 // the display that has been initialized in the display declaration
325 // therefore is is no longuer necessary to make a reference to the
326 // display variable.
329 }
330
331 unsigned cpt = 1;
332 // this is the loop over the image sequence
333
334 while (cpt++ < opt_nimages) {
335 double tms = vpTime::measureTimeMs();
336 // read the image and then increment the image counter so that the next
337 // call to acquire(I) will get the next image
338 g.acquire(I);
339 if (opt_display) {
340 // Display the image
342 // Flush the display
344 }
345 // Synchronise the loop to 40 ms
346 vpTime::wait(tms, 40);
347 }
348 return EXIT_SUCCESS;
349 } catch (const vpException &e) {
350 std::cout << "Catch an exception: " << e << std::endl;
351 return EXIT_FAILURE;
352 }
353}
354
355#else
356int main()
357{
358 std::cout << "You do not have X11, or GDI (Graphical Device Interface) functionalities to display images..." << std::endl;
359 std::cout << "Tip if you are on a unix-like system:" << std::endl;
360 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
361 std::cout << "Tip if you are on a windows-like system:" << std::endl;
362 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
363 return EXIT_SUCCESS;
364}
365#endif
Class to grab (ie. read) images from the disk.
void setStep(long step)
void setDirectory(const std::string &dir)
void setExtension(const std::string &ext)
void open(vpImage< unsigned char > &I)
void setImageNumber(long number)
void setNumberOfZero(unsigned int noz)
void setBaseName(const std::string &name)
void acquire(vpImage< unsigned char > &I)
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
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 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
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
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()