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