Visual Servoing Platform version 3.5.0
grabV4l2.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 * Acquire images using 1394 device with cfox (MAC OSX) and display it
33 * using GTK or GTK.
34 *
35 * Authors:
36 * Fabien Spindler
37 *
38 *****************************************************************************/
39
40#include <stdlib.h>
41#include <visp3/core/vpConfig.h>
42#include <visp3/core/vpDebug.h>
50#ifdef VISP_HAVE_V4L2
51
52#if (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GTK))
53
54#include <visp3/core/vpDisplay.h>
55#include <visp3/core/vpImage.h>
56#include <visp3/core/vpTime.h>
57#include <visp3/gui/vpDisplayGTK.h>
58#include <visp3/gui/vpDisplayX.h>
59#include <visp3/io/vpImageIo.h>
60#include <visp3/io/vpParseArgv.h>
61#include <visp3/sensor/vpV4l2Grabber.h>
62
63// List of allowed command line options
64#define GETOPTARGS "df:i:hn:o:p:s:t:v:x"
65
66typedef enum {
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 char *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", name);
99
100 fprintf(stdout, "\n\
101OPTIONS: Default\n\
102 -v <video device> %s\n\
103 Video device to access to the camera\n\
104\n\
105 -f <fps> %u\n\
106 Framerate in term od number of images per second.\n\
107 Possible values are 25 (for 25Hz) or 50 (for %%) Hz)\n\
108\n\
109 -i <input> %u\n\
110 Framegrabber active input. Values can be 0, 1, 2, 4\n\
111\n\
112 -p <pixel format> %d\n\
113 Camera pixel format. Values must be in [0-%d]:\n\
114 0 for gray format\n\
115 1 for RGB24 format\n\
116 2 for RGB32 format\n\
117 3 for BGR24 format\n\
118 4 for YUYV format\n\
119\n\
120 -t <image type> %d\n\
121 Kind of images that are acquired/displayed by ViSP. \n\
122 Values must be in [0-1]:\n\
123 0 for grey images in unsigned char \n\
124 1 for color images in vpRGBa\n\
125\n\
126 -s <scale> %u\n\
127 Framegrabber subsampling factor. \n\
128 If 1, full resolution image acquisition.\n\
129 If 2, half resolution image acquisition. The \n\
130 subsampling is achieved by the hardware.\n\
131\n\
132 -n <niter> %ld\n\
133 Number of images to acquire.\n\
134\n\
135 -d \n\
136 Turn off the display.\n\
137\n\
138 -x \n\
139 Activates the extra verbose mode.\n\
140\n\
141 -o [%%s] : Filename for image saving. \n\
142 Example: -o %s\n\
143 The %%d is for the image numbering. The format is set \n\
144 by the extension of the file (ex .png, .pgm, ...) \n\
145 \n\
146 -h \n\
147 Print the help.\n\n", device, fps, input, pixelformat, vpV4l2Grabber::V4L2_MAX_FORMAT - 1, image_type, scale, niter,
148 opath.c_str());
149
150 if (badparam)
151 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
152}
153
175bool getOptions(int argc, const char **argv, unsigned &fps, unsigned &input, unsigned &scale, bool &display,
176 bool &verbose, long &niter, char *device, vpV4l2Grabber::vpV4l2PixelFormatType &pixelformat,
177 vpImage_type &image_type, bool &save, std::string &opath)
178{
179 const char *optarg_;
180 int c;
181 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
182
183 switch (c) {
184 case 'd':
185 display = false;
186 break;
187 case 'f':
188 fps = (unsigned)atoi(optarg_);
189 break;
190 case 'i':
191 input = (unsigned)atoi(optarg_);
192 break;
193 case 'n':
194 niter = atol(optarg_);
195 break;
196 case 'o':
197 save = true;
198 opath = optarg_;
199 break;
200 case 'p':
201 pixelformat = (vpV4l2Grabber::vpV4l2PixelFormatType)atoi(optarg_);
202 break;
203 case 's':
204 scale = (unsigned)atoi(optarg_);
205 break;
206 case 't':
207 image_type = (vpImage_type)atoi(optarg_);
208 break;
209 case 'v':
210 sprintf(device, "%s", optarg_);
211 break;
212 case 'x':
213 verbose = true;
214 break;
215 case 'h':
216 usage(argv[0], NULL, fps, input, scale, niter, device, pixelformat, image_type, opath);
217 return false;
218 break;
219
220 default:
221 usage(argv[0], optarg_, fps, input, scale, niter, device, pixelformat, image_type, opath);
222 return false;
223 break;
224 }
225 }
226
227 if ((c == 1) || (c == -1)) {
228 // standalone param or error
229 usage(argv[0], NULL, 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 try {
250 unsigned int opt_fps = 25;
251 unsigned int opt_input = 0;
252 unsigned int opt_scale = 1;
254 long opt_iter = 100;
255 bool opt_verbose = false;
256 bool opt_display = true;
257 char opt_device[20];
258 bool opt_save = false;
259 sprintf(opt_device, "/dev/video0");
260 // Default output path for image saving
261 std::string opt_opath = "/tmp/I%04d.ppm";
262
263 vpImage_type opt_image_type = color_image;
264
265 // Read the command line options
266 if (getOptions(argc, argv, opt_fps, opt_input, opt_scale, opt_display, opt_verbose, opt_iter, opt_device,
267 opt_pixelformat, opt_image_type, opt_save, opt_opath) == false) {
268 exit(-1);
269 }
270
271 // Declare an image, this is a gray level image (unsigned char) and
272 // an other one that is a color image. There size is not defined
273 // yet. It will be defined when the image will acquired the first
274 // time.
275 vpImage<unsigned char> Ig; // grey level image
276 vpImage<vpRGBa> Ic; // color image
277
278 // Creates the grabber
280
281 // Initialize the grabber
282 g.setVerboseMode(opt_verbose);
283 g.setDevice(opt_device);
284 g.setInput(opt_input);
285 g.setScale(opt_scale);
286 g.setPixelFormat(opt_pixelformat);
287 if (opt_fps == 25)
289 else
291 if (opt_image_type == grey_image) {
292 // Open the framegrabber with the specified settings on grey images
293 g.open(Ig);
294 // Acquire an image
295 g.acquire(Ig);
296 std::cout << "Grey image size: width : " << Ig.getWidth() << " height: " << Ig.getHeight() << std::endl;
297 } else {
298 // Open the framegrabber with the specified settings on color images
299 g.open(Ic);
300 // Acquire an image
301 g.acquire(Ic);
302 std::cout << "Color image size: width : " << Ic.getWidth() << " height: " << Ic.getHeight() << std::endl;
303 }
304
305// We open a window using either X11 or GTK.
306// Its size is automatically defined by the image (I) size
307#if defined VISP_HAVE_X11
308 vpDisplayX display;
309#elif defined VISP_HAVE_GTK
310 vpDisplayGTK display;
311#endif
312
313 if (opt_display) {
314 // Display the image
315 // The image class has a member that specify a pointer toward
316 // the display that has been initialized in the display declaration
317 // therefore is is no longuer necessary to make a reference to the
318 // display variable.
319 if (opt_image_type == grey_image) {
320 display.init(Ig, 100, 100, "V4L2 grey images framegrabbing");
323 } else {
324 display.init(Ic, 100, 100, "V4L2 color images framegrabbing");
327 }
328 }
329 // Acquisition loop
330 long cpt = 1;
331 while (cpt++ < opt_iter) {
332 // Measure the initial time of an iteration
333 double t = vpTime::measureTimeMs();
334 // Acquire the image
335 if (opt_image_type == grey_image) {
336 g.acquire(Ig);
337 if (opt_display) {
338 // Display the image
340 // Flush the display
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 sprintf(buf, 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 } else {
361 vpImageIo::write(Ic, filename);
362 }
363 }
364
365 // Print the iteration duration
366 std::cout << "time: " << vpTime::measureTimeMs() - t << " (ms)" << std::endl;
367 }
368
369 g.close();
370 return EXIT_SUCCESS;
371 } catch (const vpException &e) {
372 std::cout << "Catch an exception: " << e << std::endl;
373 return EXIT_FAILURE;
374 }
375}
376#else
377int main()
378{
379 std::cout << "You do not have X11, or GTK functionalities to display images..." << std::endl;
380 std::cout << "Tip if you are on a unix-like system:" << std::endl;
381 std::cout << "- Install X11, configure again ViSP using cmake and build again this example" << std::endl;
382 std::cout << "Tip if you are on a windows-like system:" << std::endl;
383 std::cout << "- Install GTK, configure again ViSP using cmake and build again this example" << std::endl;
384 return EXIT_SUCCESS;
385}
386#endif
387#else
388int main()
389{
390 std::cout << "You do not have Video 4 Linux 2 functionality enabled" << std::endl;
391 std::cout << "Tip if you are on a unix-like system:" << std::endl;
392 std::cout << "- Install libv4l2, configure again ViSP using cmake and build again this example" << std::endl;
393 return EXIT_SUCCESS;
394}
395#endif
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 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 write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:293
unsigned int getWidth() const
Definition: vpImage.h:246
unsigned int getHeight() const
Definition: vpImage.h:188
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
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)
VISP_EXPORT double measureTimeMs()