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