ViSP
grab1394Two.cpp
1 /****************************************************************************
2  *
3  * $Id: grab1394Two.cpp 4658 2014-02-09 09:50:14Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 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  * Firewire cameras video capture.
36  *
37  * Authors:
38  * Fabien Spindler
39  *
40  *****************************************************************************/
41 
42 
58 #include <visp/vpConfig.h>
59 #include <visp/vpDebug.h>
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <iostream>
63 #include <sstream>
64 #include <list>
65 #if defined(VISP_HAVE_DC1394_2)
66 
67 #include <visp/vp1394TwoGrabber.h>
68 #include <visp/vpImage.h>
69 #include <visp/vpImageIo.h>
70 #include <visp/vpDisplay.h>
71 #include <visp/vpDisplayX.h>
72 #include <visp/vpTime.h>
73 #include <visp/vpParseArgv.h>
74 #include <visp/vpRGBa.h>
75 
76 #define GRAB_CxOLOR
77 
78 
79 // List of allowed command line options
80 #define GETOPTARGS "b:c:df:g:hH:L:mn:io:p:rsT:v:W:"
81 #define DUAL_ACQ
82 
83 void usage(const char *name, const char *badparam, unsigned int camera,
84  const unsigned int &nframes, const std::string &opath,
85  const unsigned int &roi_left, const unsigned int &roi_top,
86  const unsigned int &roi_width, const unsigned int &roi_height,
87  const unsigned int &ringbuffersize, const unsigned int &panControl);
88 void read_options(int argc, const char **argv, bool &multi, unsigned int &camera,
89  unsigned int &nframes, bool &verbose_info,
90  bool &verbose_settings,
91  bool &videomode_is_set,
93  bool &framerate_is_set,
95  bool &colorcoding_is_set,
97  bool &ringbuffersize_is_set,
98  unsigned int &ringbuffersize,
99  bool &display, bool &save, std::string &opath,
100  unsigned int &roi_left, unsigned int &roi_top,
101  unsigned int &roi_width, unsigned int &roi_height,
102  bool &reset,
103  unsigned int &panControl, bool & panControl_is_set);
104 
120 void usage(const char *name, const char *badparam, unsigned int camera,
121  const unsigned int &nframes, const std::string &opath,
122  const unsigned int &roi_left, const unsigned int &roi_top,
123  const unsigned int &roi_width, const unsigned int &roi_height,
124  const unsigned int &ringbuffersize, const unsigned int &panControl)
125 {
126  if (badparam)
127  fprintf(stderr, "\nERROR: Bad parameter [%s]\n", badparam);
128 
129  fprintf(stderr, "\n\
130 SYNOPSIS\n\
131  %s [-v <video mode>] [-f <framerate>] \n\
132  [-g <color coding>] [-c <camera id>] [-m] [-n <frames>] \n\
133  [-i] [-s] [-d] [-o <filename>] [-L <format 7 roi left position>] \n\
134  [-T <format 7 roi top position>] [-W <format 7 roi width>] \n\
135  [-H <format 7 roi height>] [-b <ring buffer size>] \n\
136  [-p <pan control value>] [-R] [-h]\n\
137  \n\
138 DESCRIPTION\n\
139  Test for firewire camera image acquisition.\n\
140  \n\
141 EXAMPLES\n\
142  \n\
143  %s -s\n\
144  Indicates the current settings for the first camera found on the bus.\n\n\
145  %s -i\n\
146  Gives information on the first camera found on the bus.\n\n\
147  %s -s -m\n\
148  Indicates the current settings for all the cameras found on the bus.\n\n\
149  %s -i -m\n\
150  Gives information on all the cameras found on the bus.\n\
151  %s -c 1\n\
152  Grab images from camera 1.\n\n\
153  %s -m\n\
154  Grab images from all the cameras.\n\n\
155  \n\
156  If a stereo camera is connected to the bus like the PointGrey Bumblebee,\n\
157  you may set the pan control to select the camera view:\n\
158  %s -p 0\n\
159  Transmit right imge.\n\
160  %s -p 1\n\
161  Transmit left imge.\n\
162  \n\
163 OPTIONS Default\n\
164  -v [%%u] : Video mode to set for the active camera.\n\
165  Use -s option so see which are the supported \n\
166  video modes. You can select the active \n\
167  camera using -c option.\n\
168  \n\
169  -f [%%u] : Framerate to set for the active camera.\n\
170  Use -s option so see which are the supported \n\
171  framerates. You can select the active \n\
172  camera using -c option.\n\
173  \n\
174  -g [%%u] : Color coding to set for the active camera\n\
175  in format 7 video mode. Use -s option so see if \n\
176  format 7 is supported by the camera and if so, \n\
177  which are the supported color codings. You can \n\
178  select the active camera using -c option.\n\
179  See -t <top>, -l <left>, -w <width>, \n\
180  -h <height> option to set format 7 roi.\n\
181  \n\
182  -L [%%u] : Format 7 region of interest (roi) left %u\n\
183  position. This option is only used if video\n\
184  mode is format 7.\n\
185  \n\
186  -T [%%u] : Format 7 region of interest (roi) top %u\n\
187  position. This option is only used if video\n\
188  mode is format 7.\n\
189  \n\
190  -W [%%u] : Format 7 region of interest (roi) width. %u\n\
191  Is set to zero, use the maximum width. This\n\
192  option is only used if video mode is format 7.\n\
193  \n\
194  -H [%%u] : Format 7 region of interest (roi) height. %u\n\
195  Is set to zero, use the maximum height. This\n\
196  option is only used if video mode is format 7.\n\
197  \n\
198  -c [%%u] : Active camera identifier. %u\n\
199  Zero is for the first camera found on the bus.\n\
200  \n\
201  -m : Flag to active multi camera acquisition. \n\
202  You need at least two cameras connected on \n\
203  the bus.\n\
204  \n\
205  -n [%%u] : Number of frames to acquire. %u\n\
206  \n\
207  -i : Flag to print camera information.\n\
208  \n\
209  -s : Print camera settings capabilities such as \n\
210  video mode and framerates available and exit.\n\
211  \n\
212  -d : Flag to turn off image display.\n\
213  \n\
214  -b [%%u] : Ring buffer size used during capture %u\n\
215  \n\
216  -p [%%u] : Pan control value used to control single or %u\n\
217  multiple image transmission from stereo vision \n\
218  cameras by setting the PAN register 0x884.\n\
219  \n\
220  -o [%%s] : Filename for image saving. \n\
221  Example: -o %s\n\
222  The first %%d is for the camera id. The second\n\
223  %%04d is for the image numbering. The format is set \n\
224  by the extension of the file (ex .png, .pgm, ...) \n\
225  \n\
226  -r : Reset the bus attached to the first camera found.\n\
227  Bus reset may help to make firewire working if the\n\
228  program was not properly stopped by a CTRL-C.\n\
229  \n\
230  -h : Print this help.\n\
231  \n",
232  name, name, name, name, name, name, name, name, name,
233  roi_left, roi_top, roi_width, roi_height,
234  camera, nframes, ringbuffersize, panControl, opath.c_str());
235 }
236 
279 void read_options(int argc, const char **argv, bool &multi, unsigned int &camera,
280  unsigned int &nframes, bool &verbose_info,
281  bool &verbose_settings,
282  bool &videomode_is_set,
284  bool &framerate_is_set,
286  bool &colorcoding_is_set,
288  bool &ringbuffersize_is_set,
289  unsigned int &ringbuffersize,
290  bool &display, bool &save, std::string &opath,
291  unsigned int &roi_left, unsigned int &roi_top,
292  unsigned int &roi_width, unsigned int &roi_height,
293  bool &reset,
294  unsigned int &panControl, bool & panControl_is_set)
295 {
296  /*
297  * Lecture des options.
298  */
299  const char *optarg_;
300  int c;
301 
302  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
303  switch (c) {
304  case 'c':
305  camera = (unsigned int)atoi(optarg_); break;
306  case 'd':
307  display = false; break;
308  case 'f':
309  framerate_is_set = true;
310  framerate = (vp1394TwoGrabber::vp1394TwoFramerateType) atoi(optarg_);
311  break;
312  case 'g':
313  colorcoding_is_set = true;
314  colorcoding = (vp1394TwoGrabber::vp1394TwoColorCodingType) atoi(optarg_);
315  break;
316  case 'H':
317  roi_height = (unsigned int) atoi(optarg_); break;
318  case 'i':
319  verbose_info = true; break;
320  case 'L':
321  roi_left = (unsigned int) atoi(optarg_); break;
322  case 'm':
323  multi = true; break;
324  case 'n':
325  nframes = (unsigned int)atoi(optarg_); break;
326  case 'o':
327  save = true;
328  opath = optarg_; break;
329  case 'b':
330  ringbuffersize_is_set = true;
331  ringbuffersize = (unsigned int) atoi(optarg_); break;
332  case 'p':
333  panControl = (unsigned int) atoi(optarg_);
334  panControl_is_set = true;
335  break;
336  case 'r':
337  reset = true; break;
338  case 's':
339  verbose_settings = true; break;
340  case 'T':
341  roi_top = (unsigned int) atoi(optarg_); break;
342  case 'v':
343  videomode_is_set = true;
344  videomode = (vp1394TwoGrabber::vp1394TwoVideoModeType) atoi(optarg_);
345  break;
346  case 'W':
347  roi_width = (unsigned int) atoi(optarg_); break;
348  case 'h':
349  case '?':
350  usage(argv[0], NULL, camera, nframes, opath,
351  roi_left, roi_top, roi_width, roi_height, ringbuffersize,
352  panControl);
353  exit(0);
354  break;
355  }
356  }
357 
358  if ((c == 1) || (c == -1)) {
359  // standalone param or error
360  usage(argv[0], NULL, camera, nframes, opath,
361  roi_left, roi_top, roi_width, roi_height, ringbuffersize, panControl);
362  std::cerr << "ERROR: " << std::endl;
363  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
364  exit(-1);
365  }
366 }
367 
377 int
378 main(int argc, const char ** argv)
379 {
380  try {
381  unsigned int camera = 0;
382  bool multi = false;
383  bool verbose_info = false;
384  bool verbose_settings = false;
385  bool display = true;
386  unsigned int nframes = 50;
387  unsigned int offset;
388  bool videomode_is_set = false;
390  bool framerate_is_set = false;
392  bool colorcoding_is_set = false;
394  bool ringbuffersize_is_set = false;
395  unsigned int ringbuffersize = 4;
396  bool save = false;
397  bool reset = false;
398  unsigned int panControl = 0;
399  bool panControl_is_set = false;
400 
401  // Format 7 roi
402  unsigned int roi_left=0, roi_top=0, roi_width=0, roi_height=0;
403 
404  // Default output path for image saving
405  std::string opath = "/tmp/I%d-%04d.ppm";
406 
407  read_options(argc, argv, multi, camera, nframes,
408  verbose_info, verbose_settings,
409  videomode_is_set, videomode,
410  framerate_is_set, framerate,
411  colorcoding_is_set, colorcoding,
412  ringbuffersize_is_set, ringbuffersize,
413  display, save, opath,
414  roi_left, roi_top, roi_width, roi_height, reset,
415  panControl, panControl_is_set);
416 
417  // Create a grabber
418  vp1394TwoGrabber g(reset);
419 
420  if (reset) {
421  // The experience shows that for some Marlin cameras (F131B and
422  // F033C) a tempo of 1s is requested after a bus reset.
423  vpTime::wait(1000); // Wait 1000 ms
424  }
425 
426  // Number of cameras connected on the bus
427  unsigned int ncameras = 0;
428  g.getNumCameras(ncameras);
429 
430  std::cout << "Number of cameras on the bus: " << ncameras << std::endl;
431 
432  // Check the consistancy of the options
433  if (multi) {
434  // ckeck if two cameras are connected
435  if (ncameras < 2) {
436  std::cout << "You have only " << ncameras << " camera connected on the bus." << std::endl;
437  std::cout << "It is not possible to active multi-camera acquisition." << std::endl;
438  std::cout << "Disable -m command line option, or connect an other " << std::endl;
439  std::cout << "cameras on the bus." << std::endl;
440  g.close();
441  return(0);
442  }
443  }
444  if (camera >= ncameras) {
445  std::cout << "You have only " << ncameras;
446  std::cout << " camera connected on the bus." << std::endl;
447  std::cout << "It is not possible to select camera " << camera << std::endl;
448  std::cout << "Check your -c <camera> command line option." << std::endl;
449  g.close();
450  return(0);
451  }
452 
453  if (multi) {
454  camera = 0; // to over write a bad option usage
455  }
456  else {
457  ncameras = 1; // acquisition from only one camera
458  }
459  // Offset is used to set the correspondancy between and image and the
460  // camera. For example, images comming from camera (i+offset) are available
461  // in I[i]
462  offset = camera;
463 
464  // Display information for each camera
465  if (verbose_info || verbose_settings) {
466  for (unsigned int i=0; i < ncameras; i ++) {
467 
468  g.setCamera(i+offset);
469 
470  if (verbose_info)
471  g.printCameraInfo();
472 
473  if (verbose_settings) {
477  std::list<vp1394TwoGrabber::vp1394TwoVideoModeType> lmode;
478  std::list<vp1394TwoGrabber::vp1394TwoFramerateType> lfps;
479  std::list<vp1394TwoGrabber::vp1394TwoColorCodingType> lcoding;
480  std::list<vp1394TwoGrabber::vp1394TwoVideoModeType>::const_iterator it_lmode;
481  std::list<vp1394TwoGrabber::vp1394TwoFramerateType>::const_iterator it_lfps;
482  std::list<vp1394TwoGrabber::vp1394TwoColorCodingType>::const_iterator it_lcoding;
483  uint64_t guid;
484 
485  g.getVideoMode(curmode);
486  g.getFramerate(curfps);
487  g.getColorCoding(curcoding);
488  g.getVideoModeSupported(lmode);
489  g.getGuid(guid);
490 
491  std::cout << "----------------------------------------------------------"
492  << std::endl
493  << "---- Video modes and framerates supported by camera "
494  << i+offset << " ----" << std::endl
495  << "---- with guid 0x" << std::hex << guid << " ----" << std::endl
496  << "---- * is for the current settings ----"
497  << std::endl
498  << "---- between ( ) you have the corresponding option ----"
499  << std::endl
500  << "---- to use. ----"
501  << std::endl
502  << "----------------------------------------------------------"
503  << std::endl;
504 
505  for (it_lmode = lmode.begin(); it_lmode != lmode.end(); ++it_lmode) {
506  // Parse the list of supported modes
507  vp1394TwoGrabber::vp1394TwoVideoModeType supmode = *it_lmode;
508  if (curmode == supmode)
509  std::cout << " * " << vp1394TwoGrabber::videoMode2string(supmode)
510  << " (-v " << (int)supmode << ")" << std::endl;
511  else
512  std::cout << " " << vp1394TwoGrabber::videoMode2string(supmode)
513  << " (-v " << (int)supmode << ")" << std::endl;
514 
515  if (g.isVideoModeFormat7(supmode)){
516  // Format 7 video mode; no framerate setting, but color
517  // coding setting
518  g.getColorCodingSupported(supmode, lcoding);
519  for (it_lcoding = lcoding.begin(); it_lcoding != lcoding.end(); ++it_lcoding) {
521  supcoding = *it_lcoding;
522  if ( (curmode == supmode) && (supcoding == curcoding) )
523  std::cout << " * "
525  << " (-g " << (int)supcoding << ")" << std::endl;
526  else
527  std::cout << " "
529  << " (-g " << (int)supcoding << ")" << std::endl;
530  }
531  }
532  else {
533 
534  // Parse the list of supported framerates for a supported mode
535  g.getFramerateSupported(supmode, lfps);
536  for (it_lfps = lfps.begin(); it_lfps != lfps.end(); ++it_lfps) {
538  if ( (curmode == supmode) && (supfps == curfps) )
539  std::cout << " * "
541  << " (-f " << (int)supfps << ")" << std::endl;
542  else
543  std::cout << " "
545  << " (-f " << (int)supfps << ")" << std::endl;
546  }
547  }
548  }
549  std::cout << "----------------------------------------------------------"
550  << std::endl;
551 
552  }
553  }
554  return 0;
555  }
556 
557  // If requested set the PAN register 0x884 to control single or
558  // multiple image transmission from stereo vision cameras.
559  if (panControl_is_set) {
560  g.setPanControl(panControl);
561  }
562 
563  // If required modify camera settings
564  if (videomode_is_set) {
565  g.setCamera(camera);
566  g.setVideoMode(videomode);
567  }
568  else {
569  // get The actual video mode
570  g.setCamera(camera);
571  g.getVideoMode(videomode);
572  }
573  if (framerate_is_set) {
574  g.setCamera(camera);
575  g.setFramerate(framerate);
576  }
577  if (colorcoding_is_set) {
578  g.setCamera(camera);
579  g.setColorCoding(colorcoding);
580  }
581  if (ringbuffersize_is_set) {
582  g.setRingBufferSize(ringbuffersize);
583  }
584 
585  // In format 7 set roi to the hole image
586  if (g.isVideoModeFormat7(videomode))
587  g.setFormat7ROI(roi_left, roi_top, roi_width, roi_height);
588 
589  // Array to know if color images or grey level images are acquired
590  bool *grab_color = new bool [ncameras];
591 
592 #ifdef VISP_HAVE_X11
593  // allocate a display for each camera to consider
594  vpDisplayX *d = NULL;
595  if (display)
596  d = new vpDisplayX [ncameras];
597 #endif
598 
599  // allocate an Grey and color image for each camera to consider
600  vpImage<vpRGBa> *Ic = new vpImage<vpRGBa> [ncameras];
601  vpImage<unsigned char> *Ig = new vpImage<unsigned char> [ncameras];
602 
603  // Do a first acquisition to initialise the display
604  for (unsigned int i=0; i < ncameras; i ++) {
605  // Set the active camera on the bus
606  g.setCamera(i+offset);
607  // Ask each camera to know if color images or grey level images are
608  // acquired
609  grab_color[i] = g.isColor();
610  // Acquire the first image
611  if (grab_color[i]) {
612  g.acquire(Ic[i]);
613  std::cout << "Image size for camera " << i+offset << " : width: "
614  << Ic[i].getWidth() << " height: " << Ic[i].getHeight()
615  << std::endl;
616 
617 #ifdef VISP_HAVE_X11
618  if (display) {
619  // Initialise the display
620  char title[100];
621  sprintf(title, "Images captured by camera %u", i+offset);
622  d[i].init(Ic[i], (int)(100+i*50), (int)(100+i*50), title) ;
623  vpDisplay::display(Ic[i]);
624  vpDisplay::flush(Ic[i]);
625  }
626 #endif
627  }
628  else {
629  g.acquire(Ig[i]);
630  std::cout << "Image size for camera " << i+offset << " : width: "
631  << Ig[i].getWidth() << " height: " << Ig[i].getHeight()
632  << std::endl;
633 
634 #ifdef VISP_HAVE_X11
635  if (display) {
636  // Initialise the display
637  char title[100];
638  sprintf(title, "Images captured by camera %u", i+offset);
639  d[i].init(Ig[i], (int)(100+i*50), (int)(100+i*50), title) ;
640  vpDisplay::display(Ig[i]);
641  vpDisplay::flush(Ig[i]);
642  }
643 #endif
644 
645  }
646  }
647 
648  // Main loop for single or multi-camera acquisition and display
649  std::cout << "Capture in process..." << std::endl;
650 
651  double tbegin=0, tend=0, tloop=0, ttotal=0;
652 
653  ttotal = 0;
654  tbegin = vpTime::measureTimeMs();
655  for (unsigned int i = 0; i < nframes; i++) {
656  for (unsigned int c = 0; c < ncameras; c++) {
657  // Set the active camera on the bus
658  g.setCamera(c+offset);
659  // Acquire an image
660  if (grab_color[c]) {
661  g.acquire(Ic[c]);
662 #ifdef VISP_HAVE_X11
663  if (display) {
664  // Display the last image acquired
665  vpDisplay::display(Ic[c]);
666  vpDisplay::flush(Ic[c]);
667  }
668 #endif
669  }
670  else {
671  g.acquire(Ig[c]);
672 #ifdef VISP_HAVE_X11
673  if (display) {
674  // Display the last image acquired
675  vpDisplay::display(Ig[c]);
676  vpDisplay::flush(Ig[c]);
677  }
678 #endif
679 
680  }
681  if (save) {
682  char buf[FILENAME_MAX];
683  sprintf(buf, opath.c_str(), c+offset, i);
684  std::string filename(buf);
685  std::cout << "Write: " << filename << std::endl;
686  if (grab_color[c]) {
687  vpImageIo::write(Ic[c], filename);
688  }
689  else {
690  vpImageIo::write(Ig[c], filename);
691  }
692  }
693  }
694  tend = vpTime::measureTimeMs();
695  tloop = tend - tbegin;
696  tbegin = tend;
697  std::cout << "loop time: " << tloop << " ms" << std::endl;
698  ttotal += tloop;
699  }
700 
701  std::cout << "Mean loop time: " << ttotal / nframes << " ms" << std::endl;
702  std::cout << "Mean frequency: " << 1000./(ttotal / nframes) << " fps" << std::endl;
703 
704  // Release the framegrabber
705  g.close();
706 
707  // Free memory
708 
709  delete [] Ic;
710  delete [] Ig;
711  delete [] grab_color;
712 
713 #ifdef VISP_HAVE_X11
714  if (display)
715  delete [] d;
716 #endif
717  return 0;
718  }
719  catch(vpException e) {
720  std::cout << "Catch an exception: " << e << std::endl;
721  return 1;
722  }
723 }
724 #else
725 int
726 main()
727 {
728  vpTRACE("Ieee 1394 grabber capabilities are not available...\n"
729  "You should install libdc1394-2 to use this example.") ;
730 }
731 
732 #endif
static void write(const vpImage< unsigned char > &I, const char *filename)
Definition: vpImageIo.cpp:476
static std::string colorCoding2string(vp1394TwoColorCodingType colorcoding)
static std::string framerate2string(vp1394TwoFramerateType fps)
unsigned int getWidth() const
Definition: vpImage.h:161
#define vpTRACE
Definition: vpDebug.h:418
Define the X11 console to display images.
Definition: vpDisplayX.h:152
error that can be emited by ViSP classes.
Definition: vpException.h:76
static double measureTimeMs()
Definition: vpTime.cpp:86
static int wait(double t0, double t)
Definition: vpTime.cpp:149
static void flush(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:2232
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:80
static void display(const vpImage< unsigned char > &I)
Definition: vpDisplay.cpp:210
static std::string videoMode2string(vp1394TwoVideoModeType videomode)
unsigned int getHeight() const
Definition: vpImage.h:152
Class for firewire ieee1394 video devices using libdc1394-2.x api.
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const char *title=NULL)
Definition: vpDisplayX.cpp:194