Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
grabDiskFloat.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
44
45#include <stdlib.h>
46#include <iostream>
47#include <visp3/core/vpConfig.h>
48#if defined(VISP_HAVE_DISPLAY)
49
50#include <visp3/core/vpImage.h>
51#include <visp3/core/vpIoTools.h>
52#include <visp3/core/vpTime.h>
53#include <visp3/gui/vpDisplayFactory.h>
54#include <visp3/io/vpDiskGrabber.h>
55#include <visp3/io/vpParseArgv.h>
56
57// List of allowed command line options
58#define GETOPTARGS "df:g:hi:l:s:z:"
59
60#ifdef ENABLE_VISP_NAMESPACE
61using namespace VISP_NAMESPACE_NAME;
62#endif
63
77void usage(const char *name, const char *badparam, std::string ipath, std::string genericname, long int first,
78 long int last, long int step, unsigned int nzero)
79{
80 fprintf(stdout, "\n\
81Read a sequence of depth maps from the disk. Display it using X11, GDI,\n\
82GTK-2 or OpenCV. The sequence is made of separate depth maps.\n\
83\n\
84SYNOPSIS\n\
85 %s [-i <input image path>] \n\
86 [-f <first frame>] [-g <generic name>] [-l <last image> [-s <step>] \n\
87 [-z <number of zero>] [-d] [-h]\n", name);
88
89 fprintf(stdout, "\n\
90OPTIONS: Default\n\
91 -i <input image path> %s\n\
92 Set image input path. The sequence will be looked for in this folder.\n\
93\n\
94 -g <generic name> %s\n\
95 Specify the generic name of the files.\n\
96 A generic name of file is for example myfile_%%04d.npy\n\
97 Supported formats ar: pfm, exr, npy or tiff.\n\
98 - pfm, exr and npy formats are supported natively\n\
99 - tiff format is only supported if ViSP is build with\n\
100 OpenCV support.\n\
101 \n\
102 -f <first frame> %ld\n\
103 First frame number of the sequence.\n\
104 \n\
105 -l <last image> %ld\n\
106 Last frame number of the sequence.\n\
107 \n\
108 -s <step> %ld\n\
109 Step between two images.\n\
110 \n\
111 -z <number of zero> %u\n\
112 Number of digits to encode the image number.\n\
113 \n\
114 -d \n\
115 Turn off the display.\n\
116 \n\
117 -h \n\
118 Print the help.\n\n", ipath.c_str(), genericname.c_str(), first, last, step, nzero);
119
120 if (badparam)
121 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
122}
123
139bool getOptions(int argc, const char **argv, std::string &ipath, std::string &genericname, long &first,
140 long &last, long &step, unsigned int &nzero, bool &display)
141{
142 const char *optarg_;
143 int c;
144 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
145
146 switch (c) {
147 case 'd':
148 display = false;
149 break;
150 case 'f':
151 first = atol(optarg_);
152 break;
153 case 'g':
154 genericname = optarg_;
155 break;
156 case 'i':
157 ipath = optarg_;
158 break;
159 case 'l':
160 last = std::atol(optarg_);
161 break;
162 case 's':
163 step = atol(optarg_);
164 break;
165 case 'z':
166 nzero = static_cast<unsigned int>(atoi(optarg_));
167 break;
168 case 'h':
169 usage(argv[0], nullptr, ipath, genericname, first, last, step, nzero);
170 return false;
171
172 default:
173 usage(argv[0], optarg_, ipath, genericname, first, last, step, nzero);
174 return false;
175 }
176 }
177
178 if ((c == 1) || (c == -1)) {
179 // standalone param or error
180 usage(argv[0], nullptr, ipath, genericname, first, last, step, nzero);
181 std::cerr << "ERROR: " << std::endl;
182 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
183 return false;
184 }
185
186 return true;
187}
188
195void convertDepthImageToDisplayImage(const vpImage<float> &Idepth, vpImage<unsigned char> &Idisp)
196{
197 float max, min;
198 Idepth.getMinMaxValue(min, max);
199 Idisp.resize(Idepth.getHeight(), Idepth.getWidth());
200 float a = 255.f / (min - max);
201 float b = 255.f - a * min;
202 int size = Idepth.getSize();
203#ifdef VISP_HAVE_OPENMP
204#pragma omp parallel for
205#endif
206 for (int i = 0; i < size; ++i) {
207 Idisp.bitmap[i] = static_cast<unsigned char>(a * Idepth.bitmap[i] + b);
208 }
209}
210
223int main(int argc, const char **argv)
224{
225#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
226 vpDisplay *display = nullptr;
227#endif
228 try {
229 std::string env_ipath;
230 std::string opt_ipath;
231 std::string ipath;
232 std::string opt_genericname = "mbt-depth/castel/castel/depth_image_%04d.pfm";
233
234 bool opt_display = true;
235
236 long int opt_first = 0;
237 long int opt_last = 29;
238 long 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_genericname, opt_first, opt_last, opt_step, opt_nzero,
251 opt_display) == false) {
252 return EXIT_FAILURE;
253 }
254
255 // Get the option values
256 if (!opt_ipath.empty()) {
257 ipath = opt_ipath;
258 }
259 else {
260#if defined(VISP_HAVE_DATASET)
261#if VISP_HAVE_DATASET_VERSION < 0x030701
262 std::cout << "This example requires visp-images 3.7.1 or a more recent version..." << std::endl;
263 return EXIT_SUCCESS;
264#endif
265#endif
266 }
267
268 // Compare ipath and env_ipath. If they differ, we take into account
269 // the input path coming from the command line option
270 if (!opt_ipath.empty() && !env_ipath.empty()) {
271 if (ipath != env_ipath) {
272 std::cout << std::endl << "WARNING: " << std::endl;
273 std::cout << " Since -i <visp image path=" << ipath << "> "
274 << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
275 << " we skip the environment variable." << std::endl;
276 }
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
284
285 // Declare a framegrabber able to read a sequence of successive
286 // images from the disk
288
289 if (opt_genericname.empty()) {
290 throw(vpException(vpException::notInitialized, "A generic name was given to the program"));
291 }
292 else {
293 if (!ipath.empty()) {
294 // Set the path to the directory containing the sequence
295 opt_genericname = vpIoTools::createFilePath(ipath, opt_genericname);
296 }
297 std::cout << "Sequence that will be read:= " << opt_genericname << std::endl;
298 g.setGenericName(opt_genericname);
299 }
300 // Set the step between two images of the sequence
301 g.setStep(opt_step);
302 // Set the number of digits to build the image number
303 g.setNumberOfZero(opt_nzero);
304 // Set the first frame number of the sequence
305 g.setImageNumber(opt_first);
306
307 // Open the framegrabber by loading the first image of the sequence
308 g.open(I);
309 Idisp.init(I.getHeight(), I.getWidth());
310 convertDepthImageToDisplayImage(I, Idisp);
311 std::cout << "Image size: width : " << I.getWidth() << " height: " << I.getHeight() << std::endl;
312
313 // We open a window using either of the display library.
314 // Its size is automatically defined by the image (I) size
315#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
316 std::shared_ptr<vpDisplay> display = vpDisplayFactory::createDisplay();
317#else
319#endif
320
321 if (opt_display) {
322 display->init(Idisp, 100, 100, "Disk Framegrabber");
323
324 // display the image
325 // The image class has a member that specify a pointer toward
326 // the display that has been initialized in the display declaration
327 // therefore is is no longer necessary to make a reference to the
328 // display variable.
329 vpDisplay::display(Idisp);
330 vpDisplay::flush(Idisp);
331 }
332
333 // this is the loop over the image sequence
334 while (g.getImageNumber() < opt_last) {
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 convertDepthImageToDisplayImage(I, Idisp);
341 // Display the image
342 vpDisplay::display(Idisp);
343 // Flush the display
344 vpDisplay::flush(Idisp);
345 }
346 // Synchronise the loop to 40 ms
347 vpTime::wait(tms, 40);
348 }
349#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
350 if (display != nullptr) {
351 delete display;
352 }
353#endif
354 return EXIT_SUCCESS;
355 }
356 catch (const vpException &e) {
357 std::cout << "Catch an exception: " << e << std::endl;
358#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
359 if (display != nullptr) {
360 delete display;
361 }
362#endif
363 return EXIT_FAILURE;
364 }
365}
366
367#else
368
369int main()
370{
371 std::cout << "You do not have X11, or GDI (Graphical Device Interface) functionalities to display images..."
372 << std::endl;
373 std::cout << "Tip if you are on a unix-like system:" << std::endl;
374 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
375 std::cout << "Tip if you are on a windows-like system:" << std::endl;
376 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
377 return EXIT_SUCCESS;
378}
379#endif
Class to grab (ie. read) images from the disk.
void setStep(long step)
void open(vpImage< unsigned char > &I) VP_OVERRIDE
void acquire(vpImage< unsigned char > &I) VP_OVERRIDE
void setGenericName(const std::string &genericName)
void setImageNumber(long number)
void setNumberOfZero(unsigned int noz)
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
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition vpException.h:74
Definition of the vpImage class member functions.
Definition vpImage.h:131
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getSize() const
Definition vpImage.h:221
Type * bitmap
points toward the bitmap
Definition vpImage.h:135
unsigned int getHeight() const
Definition vpImage.h:181
void getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal=true) const
Look for the minimum and the maximum value within the bitmap.
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
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)