Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
grabDisk.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 by Inria. All rights reserved.
4 *
5 * This software is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
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 https://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
41
42#include <stdlib.h>
43#include <iostream>
44#include <visp3/core/vpConfig.h>
45
46#if defined(VISP_HAVE_DISPLAY)
47
48#include <visp3/core/vpImage.h>
49#include <visp3/core/vpIoTools.h>
50#include <visp3/core/vpTime.h>
51#include <visp3/gui/vpDisplayFactory.h>
52#include <visp3/io/vpDiskGrabber.h>
53#include <visp3/io/vpParseArgv.h>
54
55// List of allowed command line options
56#define GETOPTARGS "b:de:f:hi:l:s:z:"
57
58#ifdef ENABLE_VISP_NAMESPACE
59using namespace VISP_NAMESPACE_NAME;
60#endif
61
75void usage(const char *name, const char *badparam, const std::string &ipath, const std::string &basename,
76 const std::string &ext, long first, long last, long step, unsigned int nzero)
77{
78 fprintf(stdout, "\n\
79Read an image sequence from the disk. Display it using X11 or GTK.\n\
80The sequence is made of separate images. Each image corresponds\n\
81to a PGM file.\n\
82\n\
83SYNOPSIS\n\
84 %s [-i <input image path>] [-b <base name>] [-e <extension>] \n\
85 [-f <first frame>] [-l <last image> [-s <step>] \n\
86 [-z <number of zero>] [-d] [-h]\n", name);
87
88 fprintf(stdout, "\n\
89OPTIONS: Default\n\
90 -i <input image path> %s\n\
91 Set image input path.\n\
92 From this path read \"cube/image.%%04d.%s\"\n\
93 images.\n\
94 Setting the VISP_INPUT_IMAGE_PATH environment\n\
95 variable produces the same behaviour than using\n\
96 this option.\n\
97\n\
98 -b <base name> %s\n\
99 Specify the base name of the files of the sequence\n\
100 containing the images to process. \n\
101 By image sequence, we mean one file per image.\n\
102 The format is selected by analyzing the filename extension.\n\
103\n\
104 -e <extension> %s\n\
105 Specify the extension of the files.\n\
106 Not taken into account for the moment. Will be a\n\
107 future feature...\n\
108\n\
109 -f <first frame> %ld\n\
110 First frame number of the sequence.\n\
111\n\
112 -l <last image> %ld\n\
113 Last frame number of the sequence.\n\
114\n\
115 -s <step> %ld\n\
116 Step between two images.\n\
117\n\
118 -z <number of zero> %u\n\
119 Number of digits to encode the image number.\n\
120\n\
121 -d \n\
122 Turn off the display.\n\
123\n\
124 -h \n\
125 Print the help.\n\n",
126 ipath.c_str(), ext.c_str(), basename.c_str(), ext.c_str(), first, last, step, nzero);
127
128 if (badparam)
129 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
130}
149bool getOptions(int argc, const char **argv, std::string &ipath, std::string &basename, std::string &ext, long &first,
150 long &last, long &step, unsigned int &nzero, bool &display)
151{
152 const char *optarg_;
153 int c;
154 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
155
156 switch (c) {
157 case 'b':
158 basename = optarg_;
159 break;
160 case 'd':
161 display = false;
162 break;
163 case 'e':
164 ext = optarg_;
165 break;
166 case 'f':
167 first = atol(optarg_);
168 break;
169 case 'i':
170 ipath = optarg_;
171 break;
172 case 'l':
173 last = std::atol(optarg_);
174 break;
175 case 's':
176 step = atol(optarg_);
177 break;
178 case 'z':
179 nzero = static_cast<unsigned int>(atoi(optarg_));
180 break;
181 case 'h':
182 usage(argv[0], nullptr, ipath, basename, ext, first, last, step, nzero);
183 return false;
184
185 default:
186 usage(argv[0], optarg_, ipath, basename, ext, first, last, step, nzero);
187 return false;
188 }
189 }
190
191 if ((c == 1) || (c == -1)) {
192 // standalone param or error
193 usage(argv[0], nullptr, ipath, basename, ext, first, last, step, nzero);
194 std::cerr << "ERROR: " << std::endl;
195 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
196 return false;
197 }
198
199 return true;
200}
201
211int main(int argc, const char **argv)
212{
213#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
214 vpDisplay *display = nullptr;
215#endif
216 try {
217 std::string env_ipath;
218 std::string opt_ipath;
219 std::string ipath;
220 std::string opt_basename = "cube/image.";
221#if defined(VISP_HAVE_DATASET)
222#if VISP_HAVE_DATASET_VERSION >= 0x030600
223 std::string opt_ext("png");
224#else
225 std::string opt_ext("pgm");
226#endif
227#else
228 // We suppose that the user will download a recent dataset
229 std::string opt_ext("png");
230#endif
231
232 bool opt_display = true;
233
234 long opt_first = 5;
235 long opt_last = 70;
236 long opt_step = 1;
237 unsigned int opt_nzero = 4;
238
239 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
240 // environment variable value
242
243 // Set the default input path
244 if (!env_ipath.empty())
245 ipath = env_ipath;
246
247 // Read the command line options
248 if (getOptions(argc, argv, opt_ipath, opt_basename, opt_ext, opt_first, opt_last, opt_step, opt_nzero,
249 opt_display) == false) {
250 return EXIT_FAILURE;
251 }
252
253 // Get the option values
254 if (!opt_ipath.empty())
255 ipath = opt_ipath;
256
257 // Compare ipath and env_ipath. If they differ, we take into account
258 // the input path coming from the command line option
259 if (!opt_ipath.empty() && !env_ipath.empty()) {
260 if (ipath != env_ipath) {
261 std::cout << std::endl << "WARNING: " << std::endl;
262 std::cout << " Since -i <visp image path=" << ipath << "> "
263 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
264 << " we skip the environment variable." << std::endl;
265 }
266 }
267
268 // Test if an input path is set
269 if (opt_ipath.empty() && env_ipath.empty()) {
270 usage(argv[0], nullptr, ipath, opt_basename, opt_ext, opt_first, opt_last, opt_step, opt_nzero);
271 std::cerr << std::endl << "ERROR:" << std::endl;
272 std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
273 << " environment variable to specify the location of the " << std::endl
274 << " image path where test images are located." << std::endl
275 << std::endl;
276 return EXIT_FAILURE;
277 }
278
279 // Declare an image, this is a gray level image (unsigned char)
280 // it size is not defined yet, it will be defined when the image will
281 // read on the disk
283
284 // Declare a framegrabber able to read a sequence of successive
285 // images from the disk
287
288 // Set the path to the directory containing the sequence
289 g.setDirectory(ipath.c_str());
290 // Set the image base name. The directory and the base name constitute
291 // the constant part of the full filename
292 g.setBaseName(opt_basename.c_str());
293 // Set the step between two images of the sequence
294 g.setStep(opt_step);
295 // Set the number of digits to build the image number
296 g.setNumberOfZero(opt_nzero);
297 // Set the first frame number of the sequence
298 g.setImageNumber(opt_first);
299 // Set the image extension
300 g.setExtension(opt_ext.c_str());
301
302 // Open the framegrabber by loading the first image of the sequence
303 g.open(I);
304
305 std::cout << "Image size: width : " << I.getWidth() << " height: " << I.getHeight() << std::endl;
306
307 // We open a window using either of the display library.
308 // Its size is automatically defined by the image (I) size
309#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
310 std::shared_ptr<vpDisplay> display = vpDisplayFactory::createDisplay(I);
311#else
313#endif
314
315 if (opt_display) {
316 display->init(I, 100, 100, "Disk Framegrabber");
317
318 // display the image
319 // The image class has a member that specify a pointer toward
320 // the display that has been initialized in the display declaration
321 // therefore is is no longer necessary to make a reference to the
322 // display variable.
325 }
326
327 // this is the loop over the image sequence
328 while (g.getImageNumber() < opt_last) {
329 double tms = vpTime::measureTimeMs();
330 // read the image and then increment the image counter so that the next
331 // call to acquire(I) will get the next image
332 g.acquire(I);
333 if (opt_display) {
334 // Display the image
336 // Flush the display
338 }
339 // Synchronise the loop to 40 ms
340 vpTime::wait(tms, 40);
341 }
342#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
343 if (display != nullptr) {
344 delete display;
345 }
346#endif
347 return EXIT_SUCCESS;
348}
349 catch (const vpException &e) {
350 std::cout << "Catch an exception: " << e << std::endl;
351#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
352 if (display != nullptr) {
353 delete display;
354 }
355#endif
356 return EXIT_FAILURE;
357 }
358}
359
360#else
361int main()
362{
363 std::cout << "You do not have X11, or GDI (Graphical Device Interface) functionalities to display images..."
364 << std::endl;
365 std::cout << "Tip if you are on a unix-like system:" << std::endl;
366 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
367 std::cout << "Tip if you are on a windows-like system:" << std::endl;
368 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
369 return EXIT_SUCCESS;
370}
371#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) VP_OVERRIDE
void acquire(vpImage< unsigned char > &I) VP_OVERRIDE
void setImageNumber(long number)
void setNumberOfZero(unsigned int noz)
void setBaseName(const std::string &name)
long getImageNumber() const
Class that defines generic functionalities for display.
Definition vpDisplay.h:171
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Definition vpException.h:60
Definition of the vpImage class member functions.
Definition vpImage.h:131
static std::string getViSPImagesDataPath()
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
std::shared_ptr< vpDisplay > createDisplay()
Return a smart pointer vpDisplay specialization if a GUI library is available or nullptr otherwise.
vpDisplay * allocateDisplay()
Return a newly allocated vpDisplay specialization if a GUI library is available or nullptr otherwise.
VISP_EXPORT double measureTimeMs()
VISP_EXPORT int wait(double t0, double t)