Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
grabV4l2.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 * Acquire images using 1394 device with cfox (MAC OSX) and display it
32 * using GTK or GTK.
33 */
34
41
42#include <stdlib.h>
43#include <visp3/core/vpConfig.h>
44#include <visp3/core/vpDebug.h>
45
46#ifdef VISP_HAVE_V4L2
47
48#if defined(VISP_HAVE_DISPLAY)
49
50#include <visp3/core/vpDisplay.h>
51#include <visp3/core/vpImage.h>
52#include <visp3/core/vpTime.h>
53#include <visp3/gui/vpDisplayFactory.h>
54#include <visp3/io/vpImageIo.h>
55#include <visp3/io/vpParseArgv.h>
56#include <visp3/sensor/vpV4l2Grabber.h>
57
58// List of allowed command line options
59#define GETOPTARGS "df:i:hn:o:p:s:t:v:x"
60
61#ifdef ENABLE_VISP_NAMESPACE
62using namespace VISP_NAMESPACE_NAME;
63#endif
64
65typedef enum
66{
67 grey_image = 0, // for ViSP unsigned char grey images
68 color_image // for ViSP vpRGBa color images
69} vpImage_type;
70
87void usage(const char *name, const char *badparam, unsigned fps, unsigned input, unsigned scale, long niter,
88 const std::string &device, vpV4l2Grabber::vpV4l2PixelFormatType pixelformat, const vpImage_type &image_type,
89 const std::string &opath)
90{
91 fprintf(stdout, "\n\
92Grab grey level images using the Video For Linux Two framegrabber. \n\
93Display these images using X11 or GTK.\n\
94\n\
95SYNOPSIS\n\
96 %s [-v <video device>] [-f <fps=25|50>] \n\
97 [-i <input=0|1|2|3> [-s <scale=1|2|4>] [-p <pixel format>]\n\
98 [-n <niter>] [-t <image type>] [-o <filename>] [-x] [-d] [-h]\n",
99 name);
100
101 fprintf(stdout, "\n\
102OPTIONS: Default\n\
103 -v <video device> %s\n\
104 Video device to access to the camera\n\
105\n\
106 -f <fps> %u\n\
107 Framerate in term od number of images per second.\n\
108 Possible values are 25 (for 25Hz) or 50 (for %%) Hz)\n\
109\n\
110 -i <input> %u\n\
111 Framegrabber active input. Values can be 0, 1, 2, 4\n\
112\n\
113 -p <pixel format> %d\n\
114 Camera pixel format. Values must be in [0-%d]:\n\
115 0 for gray format\n\
116 1 for RGB24 format\n\
117 2 for RGB32 format\n\
118 3 for BGR24 format\n\
119 4 for YUYV format\n\
120\n\
121 -t <image type> %d\n\
122 Kind of images that are acquired/displayed by ViSP. \n\
123 Values must be in [0-1]:\n\
124 0 for grey images in unsigned char \n\
125 1 for color images in vpRGBa\n\
126\n\
127 -s <scale> %u\n\
128 Framegrabber subsampling factor. \n\
129 If 1, full resolution image acquisition.\n\
130 If 2, half resolution image acquisition. The \n\
131 subsampling is achieved by the hardware.\n\
132\n\
133 -n <niter> %ld\n\
134 Number of images to acquire.\n\
135\n\
136 -d \n\
137 Turn off the display.\n\
138\n\
139 -x \n\
140 Activates the extra verbose mode.\n\
141\n\
142 -o [%%s] : Filename for image saving. \n\
143 Example: -o %s\n\
144 The %%d is for the image numbering. The format is set \n\
145 by the extension of the file (ex .png, .pgm, ...) \n\
146 \n\
147 -h \n\
148 Print the help.\n\n",
149 device.c_str(), fps, input, pixelformat, vpV4l2Grabber::V4L2_MAX_FORMAT - 1, image_type, scale, niter,
150 opath.c_str());
151
152 if (badparam)
153 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
154}
155
177bool getOptions(int argc, const char **argv, unsigned &fps, unsigned &input, unsigned &scale, bool &display,
178 bool &verbose, long &niter, std::string &device, vpV4l2Grabber::vpV4l2PixelFormatType &pixelformat,
179 vpImage_type &image_type, bool &save, std::string &opath)
180{
181 const char *optarg_;
182 int c;
183 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
184
185 switch (c) {
186 case 'd':
187 display = false;
188 break;
189 case 'f':
190 fps = static_cast<unsigned int>(atoi(optarg_));
191 break;
192 case 'i':
193 input = static_cast<unsigned int>(atoi(optarg_));
194 break;
195 case 'n':
196 niter = atol(optarg_);
197 break;
198 case 'o':
199 save = true;
200 opath = optarg_;
201 break;
202 case 'p':
203 pixelformat = (vpV4l2Grabber::vpV4l2PixelFormatType)atoi(optarg_);
204 break;
205 case 's':
206 scale = static_cast<unsigned int>(atoi(optarg_));
207 break;
208 case 't':
209 image_type = (vpImage_type)atoi(optarg_);
210 break;
211 case 'v':
212 device = std::string(optarg_);
213 break;
214 case 'x':
215 verbose = true;
216 break;
217 case 'h':
218 usage(argv[0], nullptr, fps, input, scale, niter, device, pixelformat, image_type, opath);
219 return false;
220
221 default:
222 usage(argv[0], optarg_, fps, input, scale, niter, device, pixelformat, image_type, opath);
223 return false;
224 }
225 }
226
227 if ((c == 1) || (c == -1)) {
228 // standalone param or error
229 usage(argv[0], nullptr, fps, input, scale, niter, device, pixelformat, image_type, opath);
230 std::cerr << "ERROR: " << std::endl;
231 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
232 return false;
233 }
234
235 return true;
236}
237
247int main(int argc, const char **argv)
248{
249 // We create a display if a display library is available
250#if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
251 std::shared_ptr<vpDisplay> display = vpDisplayFactory::createDisplay();
252#else
254#endif
255 try {
256 unsigned int opt_fps = 25;
257 unsigned int opt_input = 0;
258 unsigned int opt_scale = 1;
260 long opt_iter = 100;
261 bool opt_verbose = false;
262 bool opt_display = true;
263 std::string opt_device = "/dev/video0";
264 bool opt_save = false;
265 // Default output path for image saving
266 std::string opt_opath = "/tmp/I%04d.ppm";
267
268 vpImage_type opt_image_type = color_image;
269
270 // Read the command line options
271 if (getOptions(argc, argv, opt_fps, opt_input, opt_scale, opt_display, opt_verbose, opt_iter, opt_device,
272 opt_pixelformat, opt_image_type, opt_save, opt_opath) == false) {
273 return EXIT_FAILURE;
274 }
275
276 // Declare an image, this is a gray level image (unsigned char) and
277 // an other one that is a color image. There size is not defined
278 // yet. It will be defined when the image will acquired the first
279 // time.
280 vpImage<unsigned char> Ig; // grey level image
281 vpImage<vpRGBa> Ic; // color image
282
283 // Creates the grabber
285
286 // Initialize the grabber
287 g.setVerboseMode(opt_verbose);
288 g.setDevice(opt_device);
289 g.setInput(opt_input);
290 g.setScale(opt_scale);
291 g.setPixelFormat(opt_pixelformat);
292 if (opt_fps == 25)
294 else
296 if (opt_image_type == grey_image) {
297 // Open the framegrabber with the specified settings on grey images
298 g.open(Ig);
299 // Acquire an image
300 g.acquire(Ig);
301 std::cout << "Grey image size: width : " << Ig.getWidth() << " height: " << Ig.getHeight() << std::endl;
302 }
303 else {
304 // Open the framegrabber with the specified settings on color images
305 g.open(Ic);
306 // Acquire an image
307 g.acquire(Ic);
308 std::cout << "Color image size: width : " << Ic.getWidth() << " height: " << Ic.getHeight() << std::endl;
309 }
310
311 if (opt_display) {
312 // Display the image
313 // The image class has a member that specify a pointer toward
314 // the display that has been initialized in the display declaration
315 // therefore is is no longer necessary to make a reference to the
316 // display variable.
317 if (opt_image_type == grey_image) {
318 display->init(Ig, 100, 100, "V4L2 grey images framegrabbing");
321 }
322 else {
323 display->init(Ic, 100, 100, "V4L2 color images framegrabbing");
326 }
327 }
328 // Acquisition loop
329 long cpt = 1;
330 while (cpt++ < opt_iter) {
331 // Measure the initial time of an iteration
332 double t = vpTime::measureTimeMs();
333 // Acquire the image
334 if (opt_image_type == grey_image) {
335 g.acquire(Ig);
336 if (opt_display) {
337 // Display the image
339 // Flush the display
341 }
342 }
343 else {
344 g.acquire(Ic);
345 if (opt_display) {
346 // Display the image
348 // Flush the display
350 }
351 }
352
353 if (opt_save) {
354 char buf[FILENAME_MAX];
355 snprintf(buf, FILENAME_MAX, opt_opath.c_str(), cpt);
356 std::string filename(buf);
357 std::cout << "Write: " << filename << std::endl;
358 if (opt_image_type == grey_image) {
359 vpImageIo::write(Ig, filename);
360 }
361 else {
362 vpImageIo::write(Ic, filename);
363 }
364 }
365
366 // Print the iteration duration
367 std::cout << "time: " << vpTime::measureTimeMs() - t << " (ms)" << std::endl;
368 }
369
370 g.close();
371#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
372 if (display != nullptr) {
373 delete display;
374 }
375#endif
376 return EXIT_SUCCESS;
377 }
378 catch (const vpException &e) {
379 std::cout << "Catch an exception: " << e << std::endl;
380#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
381 if (display != nullptr) {
382 delete display;
383 }
384#endif
385 return EXIT_FAILURE;
386 }
387}
388#else
389int main()
390{
391 std::cout << "You do not have X11, or GTK functionalities to display images..." << std::endl;
392 std::cout << "Tip if you are on a unix-like system:" << std::endl;
393 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
394 std::cout << "Tip if you are on a windows-like system:" << std::endl;
395 std::cout << "- Install GTK, configure again ViSP using cmake and build again this example" << std::endl;
396 return EXIT_SUCCESS;
397}
398#endif
399#else
400int main()
401{
402 std::cout << "You do not have Video 4 Linux 2 functionality enabled" << std::endl;
403 std::cout << "Tip if you are on a unix-like system:" << std::endl;
404 std::cout << "- Install libv4l2, configure again ViSP using cmake and build again this example" << std::endl;
405 return EXIT_SUCCESS;
406}
407#endif
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
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:131
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:181
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Class that is a wrapper over the Video4Linux2 (V4L2) driver.
@ framerate_50fps
50 frames per second
@ framerate_25fps
25 frames per second
void setFramerate(vpV4l2FramerateType framerate)
void setVerboseMode(bool verbose)
void setInput(unsigned input=vpV4l2Grabber::DEFAULT_INPUT)
void open(vpImage< unsigned char > &I)
void setScale(unsigned scale=vpV4l2Grabber::DEFAULT_SCALE)
void setPixelFormat(vpV4l2PixelFormatType pixelformat)
void setDevice(const std::string &devname)
void acquire(vpImage< unsigned char > &I)
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()