Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
grabDirectShowMulti.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 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 https://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 * Acquire images using DirectShow (under Windows only) and display it
33 * using GTK or GDI.
34 *
35*****************************************************************************/
36
37#include <visp3/core/vpConfig.h>
38#include <visp3/core/vpDebug.h>
39
47#include <iostream>
48#include <sstream>
49#include <vector>
50
51#if defined(VISP_HAVE_DIRECTSHOW)
52#if (defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI))
53
54#include <visp3/core/vpImage.h>
55#include <visp3/core/vpTime.h>
56#include <visp3/gui/vpDisplayGDI.h>
57#include <visp3/gui/vpDisplayGTK.h>
58#include <visp3/io/vpImageIo.h>
59#include <visp3/io/vpParseArgv.h>
60#include <visp3/sensor/vpDirectShowGrabber.h>
61
62// List of allowed command line options
63#define GETOPTARGS "c:df:hmn:io:st:?"
64
65#define GRAB_COLOR
66
78void usage(const char *name, const char *badparam, unsigned int camera, unsigned int &nframes, std::string &opath)
79{
80 if (badparam)
81 fprintf(stderr, "\nERREUR: Bad parameter [%s]\n", badparam);
82
83 fprintf(stdout, "\n\
84Acquire images using DirectShow (under Windows only) and display\n\
85it using GTK or the windows GDI if GTK is not available.\n\
86For a given camera, mediatype (or video mode) as well as framerate\n\
87can be set.\n\
88If more than one camera is connected, this example allows also to \n\
89acquire images from all the cameras.\n\
90\n\
91SYNOPSIS\n\
92%s [-t <mediatype>] [-f <framerate>] \n\
93 [-c <camera id>] [-m] [-n <frames>] [-i] [-s] [-d] \n\
94 [-o <filename>] [-h]\n\
95 \n\
96OPTIONS Default\n\
97 -t [%%u] \n\
98 MediaType (or video mode) to set for the active \n\
99 camera. Use -s option so see which are the supported \n\
100 Mediatypes. You can select the active camera \n\
101 using -c option.\n\
102\n\
103 -f [%%d] \n\
104 Framerate to set for the active camera.\n\
105 You can select the active camera using -c option.\n",
106 name);
107
108 fprintf(stdout, "\n\
109 -c [%%u] %u\n\
110 Active camera identifier.\n\
111 Zero is for the first camera found on the bus.\n\
112\n\
113 -m \n\
114 Flag to active multi camera acquisition. \n\
115 You need at least two cameras connected on the bus.\n\
116\n\
117 -n [%%u] %u\n\
118 Number of frames to acquire.\n\
119\n\
120 -i \n\
121 Flag to print camera information.\n\
122\n\
123 -s \n\
124 Print camera settings capabilities such as MediaType \n\
125 and sizes available and exit.\n\
126\n\
127 -d \n\
128 Flag to turn off image display.\n\
129\n\
130 -o [%%s] \n\
131 Filename for image saving. \n\
132 Example: -o %s\n\
133 The first %%d is for the camera id, %%04d\n\
134 is for the image numbering.\n\
135\n\
136 -h \n\
137 Print the help.\n\
138\n",
139 camera, nframes, opath.c_str());
140
141 exit(0);
142}
143
169void read_options(int argc, const char **argv, bool &multi, unsigned int &camera, unsigned int &nframes,
170 bool &verbose_info, bool &verbose_settings, bool &mediatype_is_set, unsigned int &mediatypeID,
171 bool &framerate_is_set, double &framerate, bool &display, bool &save, std::string &opath)
172{
173 const char *optarg;
174 int c;
175 /*
176 * Lecture des options.
177 */
178
179 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
180 switch (c) {
181 case 'c':
182 camera = atoi(optarg);
183 break;
184 case 'd':
185 display = false;
186 break;
187 case 'f':
188 framerate_is_set = true;
189 framerate = atoi(optarg);
190 break;
191 case 'i':
192 verbose_info = true;
193 break;
194 case 'm':
195 multi = true;
196 break;
197 case 'n':
198 nframes = atoi(optarg);
199 break;
200 case 'o':
201 save = true;
202 opath = optarg;
203 break;
204 case 's':
205 verbose_settings = true;
206 break;
207 case 't':
208 mediatype_is_set = true;
209 mediatypeID = atoi(optarg);
210 break;
211 default:
212 usage(argv[0], NULL, camera, nframes, opath);
213 break;
214 }
215 }
216
217 if ((c == 1) || (c == -1)) {
218 // standalone param or error
219 usage(argv[0], NULL, camera, nframes, opath);
220 std::cerr << "ERROR: " << std::endl;
221 std::cerr << " Bad argument " << optarg << std::endl << std::endl;
222 }
223}
224
233int main(int argc, const char **argv)
234{
235 try {
236 unsigned int camera = 0;
237 bool multi = false;
238 bool verbose_info = false;
239 bool verbose_settings = false;
240 bool display = true;
241 unsigned int nframes = 50;
242 bool mediatype_is_set = false;
243 unsigned int mediatypeID;
244 bool framerate_is_set = false;
245 double framerate;
246 bool save = false;
247
248#ifdef GRAB_COLOR
250 std::string opath = "C:/temp/I%d-%04d.ppm";
251#else
253 std::string opath = "C:/temp/I%d-%04d.pgm";
254#endif
255#if defined(VISP_HAVE_GDI)
256
257 vpDisplayGDI *d;
258#elif defined(VISP_HAVE_GTK)
259 vpDisplayGTK *d;
260#endif
261 read_options(argc, argv, multi, camera, nframes, verbose_info, verbose_settings, mediatype_is_set, mediatypeID,
262 framerate_is_set, framerate, display, save, opath);
263
264 // Number of cameras connected on the bus
266 g = new vpDirectShowGrabber();
267 unsigned int ncameras = g->getDeviceNumber();
268 // Check the consistancy of the options
269 if (multi) {
270 // ckeck if two cameras are connected
271 if (ncameras < 2) {
272 std::cout << "You have only " << ncameras << " camera connected on the bus." << std::endl;
273 std::cout << "It is not possible to active multi-camera acquisition." << std::endl;
274 std::cout << "Disable -m command line option, or connect an other " << std::endl;
275 std::cout << "cameras on the bus." << std::endl;
276 g->close();
277 delete g;
278 return EXIT_FAILURE;
279 }
280 }
281 if (camera >= ncameras) {
282 std::cout << "You have only " << ncameras;
283 std::cout << " camera connected on the bus." << std::endl;
284 std::cout << "It is not possible to select camera " << camera << std::endl;
285 std::cout << "Check your -c <camera> command line option." << std::endl;
286 g->close();
287 delete g;
288 return EXIT_FAILURE;
289 }
290 if (multi) {
291 camera = 0; // to over write a bad option usage
292 // reinitialize the grabbers with the right number of devices (one
293 // grabber per device)
294 delete[] g;
295 g = new vpDirectShowGrabber[ncameras];
296 for (unsigned int i = 0; i < ncameras; i++) {
297 g[i].open();
298 }
299
300 } else {
301 ncameras = 1; // acquisition from only one camera
302 delete[] g;
303 g = new vpDirectShowGrabber[1];
304 g[0].open();
305 g[0].setDevice(camera);
306 }
307
308// allocate an image and display for each camera to consider
309#ifdef GRAB_COLOR
310 I = new vpImage<vpRGBa>[ncameras];
311#else
312 I = new vpImage<unsigned char>[ncameras];
313#endif
314 if (display)
315
316#ifdef VISP_HAVE_GDI
317 d = new vpDisplayGDI[ncameras];
318#else
319 d = new vpDisplayGTK[ncameras];
320#endif
321 // If required modify camera settings
322
323 if (mediatype_is_set) {
324 g[0].setMediaType(mediatypeID);
325 }
326
327 if (framerate_is_set) {
328 for (unsigned int i = 0; i < ncameras; i++) {
329 unsigned int c;
330 if (multi)
331 c = i;
332 else
333 c = camera;
334 std::cout << "camera " << c << std::endl;
335 if (!g[i].setFramerate(framerate))
336 std::cout << "Set Framerate failed !!" << std::endl << std::endl;
337 }
338 }
339
340 // Display information for each camera
341 if (verbose_info || verbose_settings) {
342
343 std::cout << "----------------------------------------------------------" << std::endl;
344 std::cout << "---- Device List : " << std::endl;
345 std::cout << "----------------------------------------------------------" << std::endl;
346 g[0].displayDevices();
347 for (unsigned i = 0; i < ncameras; i++) {
348 unsigned int c;
349 if (multi)
350 c = i;
351 else
352 c = camera;
353
354 if (verbose_info) {
355 unsigned int width, height;
356 g[i].getFormat(width, height, framerate);
357 std::cout << "----------------------------------------------------------" << std::endl
358 << "---- MediaType and framerate currently used by device " << std::endl
359 << "---- (or camera) " << c << std::endl
360 << "---- Current MediaType : " << g[i].getMediaType() << std::endl
361 << "---- Current format : " << width << " x " << height << " at " << framerate << " fps"
362 << std::endl
363 << "----------------------------------------------------------" << std::endl;
364 }
365 if (verbose_settings) {
366 std::cout << "----------------------------------------------------------" << std::endl
367 << "---- MediaTypes supported by device (or camera) " << c << std::endl
368 << "---- One of the MediaType below can be set using " << std::endl
369 << "---- option -t <mediatype>." << std::endl
370 << "----------------------------------------------------------" << std::endl;
372 }
373 }
374 delete[] g;
375 delete[] I;
376 if (display)
377 delete[] d;
378
379 return EXIT_SUCCESS;
380 }
381
382 // Do a first acquisition to initialise the display
383 for (unsigned int i = 0; i < ncameras; i++) {
384 // Acquire the first image
385 g[i].acquire(I[i]);
386 unsigned int c;
387 if (multi)
388 c = i;
389 else
390 c = camera;
391
392 std::cout << "Image size for camera " << c << " : width: " << I[i].getWidth() << " height: " << I[i].getHeight()
393 << std::endl;
394
395 if (display) {
396 // Initialise the display
397 std::stringstream title;
398 title << "Images captured by camera ";
399 title << c;
400 d[i].init(I[i], 100 + i * 50, 100 + i * 50, title.c_str());
401 }
402 }
403
404 // Main loop for single or multi-camera acquisition and display
405 std::cout << "Capture in process..." << std::endl;
406
407 double tbegin = 0, ttotal = 0;
408
409 ttotal = 0;
410 tbegin = vpTime::measureTimeMs();
411 for (unsigned i = 0; i < nframes; i++) {
412 for (unsigned c = 0; c < ncameras; c++) {
413 // Acquire an image
414 g[c].acquire(I[c]);
415 if (display) {
416 // Display the last image acquired
417 vpDisplay::display(I[c]);
418 vpDisplay::flush(I[c]);
419 }
420 if (save) {
421 char buf[FILENAME_MAX];
422 snprintf(buf, FILENAME_MAX, opath.c_str(), c, i);
423 std::string filename(buf);
424 std::cout << "Write: " << filename << std::endl;
425 vpImageIo::write(I[c], filename);
426 }
427 }
428 double tend = vpTime::measureTimeMs();
429 double tloop = tend - tbegin;
430 tbegin = tend;
431 std::cout << "loop time: " << tloop << " ms" << std::endl;
432 ttotal += tloop;
433 }
434
435 std::cout << "Mean loop time: " << ttotal / nframes << " ms" << std::endl;
436 std::cout << "Mean frequency: " << 1000. / (ttotal / nframes) << " fps" << std::endl;
437
438 // Release the framegrabber
439 delete[] g;
440
441 // Free memory
442 delete[] I;
443 if (display)
444 delete[] d;
445
446 return EXIT_SUCCESS;
447 } catch (const vpException &e) {
448 std::cout << "Catch an exception: " << e << std::endl;
449 return EXIT_FAILURE;
450 }
451}
452#else // (defined (VISP_HAVE_GTK) || defined(VISP_HAVE_GDI))
453int main()
454{
455 std::cout << "You do not have GDI (Graphical Device Interface), or GTK functionalities to display images..."
456 << std::endl;
457 std::cout << "Tip if you are on a windows-like system:" << std::endl;
458 std::cout << "- Install GDI, configure again ViSP using cmake and build again this example" << std::endl;
459 return EXIT_SUCCESS;
460}
461#endif // (defined (VISP_HAVE_GTK) || defined(VISP_HAVE_GDI))
462#else // defined (VISP_HAVE_DIRECTSHOW)
463int main()
464{
465 std::cout << "This example requires Direct Show SDK. " << std::endl;
466 std::cout << "Tip if you are on a windows-like system:" << std::endl;
467 std::cout << "- Install Direct Show, configure again ViSP using cmake and build again this example" << std::endl;
468 return EXIT_SUCCESS;
469}
470#endif // defined (VISP_HAVE_DIRECTSHOW)
class for windows direct show devices
void acquire(vpImage< unsigned char > &I)
void getFormat(unsigned int &width, unsigned int &height, double &framerate)
bool setDevice(unsigned int id)
bool setMediaType(int mediaTypeID)
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
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 emitted by ViSP classes.
Definition vpException.h:59
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:135
unsigned int getWidth() const
Definition vpImage.h:242
unsigned int getHeight() const
Definition vpImage.h:184
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()