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