ViSP  2.8.0
grabV4l2.cpp
1 /****************************************************************************
2  *
3  * $Id: grabV4l2.cpp 4056 2013-01-05 13:04:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Acquire images using 1394 device with cfox (MAC OSX) and display it
36  * using GTK or GTK.
37  *
38  * Authors:
39  * Fabien Spindler
40  *
41  *****************************************************************************/
42 
43 
44 #include <visp/vpConfig.h>
45 #include <visp/vpDebug.h>
46 #include <stdlib.h>
54 #ifdef VISP_HAVE_V4L2
55 
56 #if (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK))
57 
58 #include <visp/vpDisplay.h>
59 #include <visp/vpDisplayX.h>
60 #include <visp/vpDisplayGTK.h>
61 #include <visp/vpImage.h>
62 #include <visp/vpImageIo.h>
63 #include <visp/vpTime.h>
64 #include <visp/vpParseArgv.h>
65 #include <visp/vpV4l2Grabber.h>
66 
67 // List of allowed command line options
68 #define GETOPTARGS "df:i:hn:o:p:s:t:v:x"
69 
70 typedef enum {
71  grey_image = 0, // for ViSP unsigned char grey images
72  color_image // for ViSP vpRGBa color images
73 } vpImage_type;
74 
91 void usage(const char *name, const char *badparam, unsigned fps,
92  unsigned input, unsigned scale, long niter, char *device,
94  const vpImage_type &image_type, const std::string &opath)
95 {
96  fprintf(stdout, "\n\
97 Grab grey level images using the Video For Linux Two framegrabber. \n\
98 Display these images using X11 or GTK.\n\
99 \n\
100 SYNOPSIS\n\
101  %s [-v <video device>] [-f <fps=25|50>] \n\
102  [-i <input=0|1|2|3> [-s <scale=1|2|4>] [-p <pixel format>]\n\
103  [-n <niter>] [-t <image type>] [-o <filename>] [-x] [-d] [-h]\n", name);
104 
105  fprintf(stdout, "\n\
106 OPTIONS: Default\n\
107  -v <video device> %s\n\
108  Video device to access to the camera\n\
109 \n\
110  -f <fps> %u\n\
111  Framerate in term od number of images per second.\n\
112  Possible values are 25 (for 25Hz) or 50 (for %%) Hz)\n\
113 \n\
114  -i <input> %u\n\
115  Framegrabber active input. Values can be 0, 1, 2, 4\n\
116 \n\
117  -p <pixel format> %d\n\
118  Camera pixel format. Values must be in [0-%d]:\n\
119  0 for gray format\n\
120  1 for RGB24 format\n\
121  2 for RGB32 format\n\
122  3 for BGR24 format\n\
123  4 for YUYV format\n\
124 \n\
125  -t <image type> %d\n\
126  Kind of images that are acquired/displayed by ViSP. \n\
127  Values must be in [0-1]:\n\
128  0 for grey images in unsigned char \n\
129  1 for color images in vpRGBa\n\
130 \n\
131  -s <scale> %u\n\
132  Framegrabber subsampling factor. \n\
133  If 1, full resolution image acquisition.\n\
134  If 2, half resolution image acquisition. The \n\
135  subsampling is achieved by the hardware.\n\
136 \n\
137  -n <niter> %ld\n\
138  Number of images to acquire.\n\
139 \n\
140  -d \n\
141  Turn off the display.\n\
142 \n\
143  -x \n\
144  Activates the extra verbose mode.\n\
145 \n\
146  -o [%%s] : Filename for image saving. \n\
147  Example: -o %s\n\
148  The %%d is for the image numbering. The format is set \n\
149  by the extension of the file (ex .png, .pgm, ...) \n\
150  \n\
151  -h \n\
152  Print the help.\n\n",
153  device, fps, input, pixelformat,
154  vpV4l2Grabber::V4L2_MAX_FORMAT-1, image_type, scale, niter, opath.c_str());
155 
156  if (badparam)
157  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
158 }
159 
181 bool getOptions(int argc, const char **argv, unsigned &fps, unsigned &input,
182  unsigned &scale, bool &display, bool &verbose,
183  long &niter, char *device,
185  vpImage_type &image_type, bool &save, std::string &opath)
186 {
187  const char *optarg;
188  int c;
189  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
190 
191  switch (c) {
192  case 'd': display = false; break;
193  case 'f': fps = (unsigned) atoi(optarg); break;
194  case 'i': input = (unsigned) atoi(optarg); break;
195  case 'n': niter = atol(optarg); break;
196  case 'o':
197  save = true;
198  opath = optarg; break;
199  case 'p': pixelformat = (vpV4l2Grabber::vpV4l2PixelFormatType) atoi(optarg); break;
200  case 's': scale = (unsigned) atoi(optarg); break;
201  case 't': image_type = (vpImage_type) atoi(optarg); break;
202  case 'v': sprintf(device, "%s", optarg); break;
203  case 'x': verbose = true; break;
204  case 'h': usage(argv[0], NULL, fps, input, scale, niter,
205  device, pixelformat, image_type, opath);
206  return false; break;
207 
208  default:
209  usage(argv[0], optarg, fps, input, scale, niter,
210  device, pixelformat, image_type, opath); return false; break;
211  }
212  }
213 
214  if ((c == 1) || (c == -1)) {
215  // standalone param or error
216  usage(argv[0], NULL, fps, input, scale, niter,
217  device, pixelformat, image_type, opath);
218  std::cerr << "ERROR: " << std::endl;
219  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
220  return false;
221  }
222 
223  return true;
224 }
225 
235 int
236 main(int argc, const char ** argv)
237 {
238  unsigned int opt_fps = 25;
239  unsigned int opt_input = 0;
240  unsigned int opt_scale = 1;
242  long opt_iter = 100;
243  bool opt_verbose = false;
244  bool opt_display = true;
245  char opt_device[20];
246  bool opt_save = false;
247  sprintf(opt_device, "/dev/video0");
248  // Default output path for image saving
249  std::string opt_opath = "/tmp/I%04d.ppm";
250 
251  vpImage_type opt_image_type = color_image;
252 
253  // Read the command line options
254  if (getOptions(argc, argv, opt_fps, opt_input, opt_scale, opt_display,
255  opt_verbose, opt_iter, opt_device,
256  opt_pixelformat, opt_image_type, opt_save, opt_opath) == false) {
257  exit (-1);
258  }
259 
260  // Declare an image, this is a gray level image (unsigned char) and
261  // an other one that is a color image. There size is not defined
262  // yet. It will be defined when the image will acquired the first
263  // time.
264  vpImage<unsigned char> Ig ; // grey level image
265  vpImage<vpRGBa> Ic ; // color image
266 
267  // Creates the grabber
268  vpV4l2Grabber g;
269 
270  try{
271  // Initialize the grabber
272  g.setVerboseMode(opt_verbose);
273  g.setDevice(opt_device);
274  g.setInput(opt_input);
275  g.setScale(opt_scale);
276  g.setPixelFormat(opt_pixelformat);
277  if (opt_fps == 25)
279  else
281  if (opt_image_type == grey_image) {
282  // Open the framegrabber with the specified settings on grey images
283  g.open(Ig) ;
284  // Acquire an image
285  g.acquire(Ig) ;
286  std::cout << "Grey image size: width : " << Ig.getWidth() << " height: "
287  << Ig.getHeight() << std::endl;
288  }
289  else {
290  // Open the framegrabber with the specified settings on color images
291  g.open(Ic) ;
292  // Acquire an image
293  g.acquire(Ic) ;
294  std::cout << "Color image size: width : " << Ic.getWidth() << " height: "
295  << Ic.getHeight() << std::endl;
296  }
297  }
298  catch (vpException e) {
299  std::cout << "Catched exception: " << e.getMessage() << std::endl;
300  return 0;
301  }
302  catch(...)
303  {
304  vpERROR_TRACE("Cannot acquire an image...") ;
305  return 0;
306  }
307 
308 
309  // We open a window using either X11 or GTK.
310  // Its size is automatically defined by the image (I) size
311 #if defined VISP_HAVE_X11
312  vpDisplayX display;
313 #elif defined VISP_HAVE_GTK
314  vpDisplayGTK display;
315 #endif
316 
317  if (opt_display) {
318  try{
319  // Display the image
320  // The image class has a member that specify a pointer toward
321  // the display that has been initialized in the display declaration
322  // therefore is is no longuer necessary to make a reference to the
323  // display variable.
324  if (opt_image_type == grey_image) {
325  display.init(Ig, 100, 100, "V4L2 grey images framegrabbing") ;
326  vpDisplay::display(Ig) ;
327  vpDisplay::flush(Ig) ;
328  }
329  else {
330  display.init(Ic, 100, 100, "V4L2 color images framegrabbing") ;
331  vpDisplay::display(Ic) ;
332  vpDisplay::flush(Ic) ;
333  }
334 
335  }
336  catch (vpException e) {
337  std::cout << "Exception: " << e.getMessage() << std::endl;
338  }
339  catch(...)
340  {
341  vpERROR_TRACE("Error while displaying the image") ;
342  exit(-1);
343  }
344  }
345  try {
346  // Acquisition loop
347  long cpt = 1;
348  while(cpt ++ < opt_iter)
349  {
350  // Measure the initial time of an iteration
351  double t = vpTime::measureTimeMs();
352  // Acquire the image
353  if (opt_image_type == grey_image) {
354  g.acquire(Ig) ;
355  if (opt_display) {
356  // Display the image
357  vpDisplay::display(Ig) ;
358  // Flush the display
359  vpDisplay::flush(Ig) ;
360  }
361  }
362  else {
363  g.acquire(Ic) ;
364  if (opt_display) {
365  // Display the image
366  vpDisplay::display(Ic) ;
367  // Flush the display
368  vpDisplay::flush(Ic) ;
369  }
370  }
371 
372  if (opt_save) {
373  char buf[FILENAME_MAX];
374  sprintf(buf, opt_opath.c_str(), cpt);
375  std::string filename(buf);
376  std::cout << "Write: " << filename << std::endl;
377  if (opt_image_type == grey_image) {
378  vpImageIo::write(Ig, filename);
379  }
380  else {
381  vpImageIo::write(Ic, filename);
382  }
383  }
384 
385  // Print the iteration duration
386  std::cout << "time: " << vpTime::measureTimeMs() - t << " (ms)" << std::endl;
387  }
388 
389  g.close();
390  }
391  catch (vpException e) {
392  std::cout << "Exception: " << e.getMessage() << std::endl;
393  g.close();
394  }
395 
396 }
397 #else
398 int
399 main()
400 {
401  vpTRACE("X11 or GTK display are not available") ;
402 }
403 #endif
404 #else
405 int
406 main()
407 {
408  vpTRACE("Video 4 Linux 2 frame grabber drivers are not available") ;
409 }
410 #endif
411 
const char * getMessage(void)
static void write(const vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:442
void acquire(vpImage< unsigned char > &I)
50 frames per second
void open(vpImage< unsigned char > &I)
unsigned int getWidth() const
Definition: vpImage.h:159
#define vpERROR_TRACE
Definition: vpDebug.h:379
#define vpTRACE
Definition: vpDebug.h:401
Define the X11 console to display images.
Definition: vpDisplayX.h:152
void setDevice(const char *devname)
error that can be emited by ViSP classes.
Definition: vpException.h:75
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
void setVerboseMode(bool verbose)
static double measureTimeMs()
Definition: vpTime.cpp:86
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:1991
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:79
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:203
The vpDisplayGTK allows to display image using the GTK+ library version 1.2.
Definition: vpDisplayGTK.h:145
void setScale(unsigned scale=vpV4l2Grabber::DEFAULT_SCALE)
void setInput(unsigned input=vpV4l2Grabber::DEFAULT_INPUT)
Class for the Video4Linux2 video device.
25 frames per second
unsigned int getHeight() const
Definition: vpImage.h:150
void setPixelFormat(vpV4l2PixelFormatType pixelformat)
void setFramerate(vpV4l2FramerateType framerate)