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  * IDS uEye interface.
33  *
34  *****************************************************************************/
35 
36 #include <visp3/core/vpConfig.h>
37 
38 #if defined(VISP_HAVE_UEYE)
39 
40 #include <string.h>
41 
42 #include <visp3/core/vpImageConvert.h>
43 #include <visp3/core/vpIoTools.h>
44 #include <visp3/sensor/vpUeyeGrabber.h>
45 
46 #include <ueye.h>
47 
48 #include "vpUeyeGrabber_impl.h"
49 
50 #ifndef DOXYGEN_SHOULD_SKIP_THIS
51 /*!
52  * \brief Number of image buffer to alloc
53  */
54 #define IMAGE_COUNT     5
55 
56 #define CAMINFO    BOARDINFO
57 #define EVENTTHREAD_WAIT_TIMEOUT    1000
58 
59 #define CAP(val, min, max) \
60 { \
61   if (val < min) { \
62     val = min; \
63   } else if (val > max) { \
64     val = max; \
65   } \
66 }
67 
68 /*! \brief image buffer properties structure */
69 struct sBufferProps
70 {
71   int width;
72   int height;
73   int bitspp;
74 };
75 
76 /*! \brief camera feature properties structure */
77 struct sCameraProps
78 {
79   bool bUsesImageFormats;
80   int nImgFmtNormal;
81   int nImgFmtDefaultNormal;
82   int nImgFmtTrigger;
83   int nImgFmtDefaultTrigger;
84 };
85 
86 /*!
87  * \brief uEye Image parameter structure
88  */
89 typedef struct _UEYE_IMAGE
90 {
91   char *pBuf;
92   INT nImageID;
93   INT nImageSeqNum;
94   INT nBufferSize;
95 } UEYE_IMAGE, *PUEYE_IMAGE;
96 
97 class vpUeyeGrabber::vpUeyeGrabberImpl
98 {
99 public:
vpUeyeGrabberImpl()100   vpUeyeGrabberImpl()
101     : m_hCamera((HIDS)0), m_nMemoryId(0), m_nColorMode(0), m_nBitsPerPixel(0), m_activeCameraSelected(-1),
102       m_pLastBuffer(NULL), m_cameraList(NULL), m_bLive(true), m_bLiveStarted(false), m_verbose(false)
103   {
104     ZeroMemory (&m_SensorInfo, sizeof(SENSORINFO));
105     ZeroMemory (&m_CamInfo, sizeof(CAMINFO));
106     ZeroMemory (&m_CamListInfo, sizeof(UEYE_CAMERA_INFO));
107     ZeroMemory (m_Images, sizeof(m_Images));
108 
109     m_BufferProps.width = 0;
110     m_BufferProps.height = 0;
111     m_BufferProps.bitspp = 8;
112 
113     m_event = 0;
114 #ifndef __linux__
115     m_hEvent = 0;
116 #endif
117 
118     // Active camera is the first one that is found
119     m_activeCameraSelected = setActiveCamera(0);
120   }
121 
~vpUeyeGrabberImpl()122   ~vpUeyeGrabberImpl()
123   {
124     close();
125   }
126 
acquire(vpImage<unsigned char> & I,double * timestamp_camera,std::string * timestamp_system)127   void acquire(vpImage<unsigned char> &I, double *timestamp_camera, std::string *timestamp_system)
128   {
129     INT ret = IS_SUCCESS;
130 
131     if (! m_hCamera) {
132       open(I);
133     }
134 
135     if (m_hCamera) {
136       if (! m_bLive) {
137         ret = is_FreezeVideo(m_hCamera, IS_WAIT);
138       }
139       else {
140         if (! m_bLiveStarted) {
141           ret = is_CaptureVideo(m_hCamera, IS_DONT_WAIT);
142           m_bLiveStarted = true;
143         }
144       }
145 
146       ret = waitEvent();
147 
148       if (ret == IS_SUCCESS) {
149         INT dummy = 0;
150         char *pLast = NULL, *pMem = NULL;
151 
152         is_GetActSeqBuf (m_hCamera, &dummy, &pMem, &pLast);
153         m_pLastBuffer = pLast;
154 
155         if (!m_pLastBuffer || m_BufferProps.width < 1 || m_BufferProps.height < 1)
156           return;
157 
158         int nNum = getImageNum (m_pLastBuffer);
159         if (timestamp_camera != NULL || timestamp_system != NULL) {
160           int nImageID = getImageID(m_pLastBuffer);
161           UEYEIMAGEINFO ImageInfo;
162           if (is_GetImageInfo(m_hCamera, nImageID, &ImageInfo, sizeof (ImageInfo)) == IS_SUCCESS) {
163             if (timestamp_camera != NULL) {
164               *timestamp_camera = static_cast<double>(ImageInfo.u64TimestampDevice) / 10000.;
165             }
166             if (timestamp_system != NULL) {
167               std::stringstream ss;
168               ss << ImageInfo.TimestampSystem.wYear << ":"
169                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wMonth << ":"
170                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wDay << ":"
171                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wHour << ":"
172                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wMinute << ":"
173                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wSecond << ":"
174                  << std::setfill('0') << std::setw(3) << ImageInfo.TimestampSystem.wMilliseconds;
175               *timestamp_system = ss.str();
176             }
177           }
178         }
179 
180         helper::LockUnlockSeqBuffer lock(m_hCamera, nNum, m_pLastBuffer);
181 
182         if (lock.OwnsLock()) {
183           // get current colormode
184           int colormode = is_SetColorMode(m_hCamera, IS_GET_COLOR_MODE);
185 
186           switch (colormode) {
187           default:
188           case IS_CM_MONO8:
189           case IS_CM_SENSOR_RAW8:
190             memcpy(reinterpret_cast<unsigned char*>(I.bitmap), reinterpret_cast<unsigned char*>(m_pLastBuffer), m_BufferProps.width * m_BufferProps.height * m_BufferProps.bitspp / 8);
191             break;
192           case IS_CM_BGR565_PACKED:
193             throw(vpException(vpException::fatalError, "vpUeyeGrabber doesn't support BGR565 format"));
194 
195           case IS_CM_RGB8_PACKED:
196             vpImageConvert::RGBToGrey(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
197                                       m_BufferProps.width, m_BufferProps.height);
198             break;
199           case IS_CM_BGR8_PACKED:
200             vpImageConvert::BGRToGrey(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
201                                       m_BufferProps.width, m_BufferProps.height);
202             break;
203           case IS_CM_RGBA8_PACKED:
204             vpImageConvert::RGBaToGrey(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
205                                        m_BufferProps.width, m_BufferProps.height);
206             break;
207           case IS_CM_BGRA8_PACKED:
208             vpImageConvert::BGRaToGrey(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
209                                        m_BufferProps.width, m_BufferProps.height);
210             break;
211           }
212         }
213       }
214     }
215   }
216 
acquire(vpImage<vpRGBa> & I,double * timestamp_camera,std::string * timestamp_system)217   void acquire(vpImage<vpRGBa>  &I, double *timestamp_camera, std::string *timestamp_system)
218   {
219     INT ret = IS_SUCCESS;
220 
221     if (! m_hCamera) {
222       open(I);
223     }
224 
225     if (m_hCamera) {
226       if (! m_bLive) {
227         ret = is_FreezeVideo(m_hCamera, IS_WAIT);
228       }
229       else {
230         if (! m_bLiveStarted) {
231           //          ret = is_CaptureVideo(m_hCamera, IS_DONT_WAIT);
232           ret = is_CaptureVideo(m_hCamera, IS_WAIT);
233           m_bLiveStarted = true;
234         }
235       }
236 
237       ret = waitEvent();
238 
239       if (ret == IS_SUCCESS) {
240         INT dummy = 0;
241         char *pLast = NULL, *pMem = NULL;
242 
243         is_GetActSeqBuf (m_hCamera, &dummy, &pMem, &pLast);
244         m_pLastBuffer = pLast;
245 
246         if (!m_pLastBuffer || m_BufferProps.width < 1 || m_BufferProps.height < 1)
247           return;
248 
249         int nNum = getImageNum (m_pLastBuffer);
250         if (timestamp_camera != NULL || timestamp_system != NULL) {
251           int nImageID = getImageID(m_pLastBuffer);
252           UEYEIMAGEINFO ImageInfo;
253           if (is_GetImageInfo(m_hCamera, nImageID, &ImageInfo, sizeof (ImageInfo)) == IS_SUCCESS) {
254             if (timestamp_camera != NULL) {
255               *timestamp_camera = static_cast<double>(ImageInfo.u64TimestampDevice) / 10000.;
256             }
257             if (timestamp_system != NULL) {
258               std::stringstream ss;
259               ss << ImageInfo.TimestampSystem.wYear << ":"
260                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wMonth << ":"
261                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wDay << ":"
262                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wHour << ":"
263                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wMinute << ":"
264                  << std::setfill('0') << std::setw(2) << ImageInfo.TimestampSystem.wSecond << ":"
265                  << std::setfill('0') << std::setw(3) << ImageInfo.TimestampSystem.wMilliseconds;
266               *timestamp_system = ss.str();
267             }
268           }
269         }
270 
271         helper::LockUnlockSeqBuffer lock(m_hCamera, nNum, m_pLastBuffer);
272 
273         if (lock.OwnsLock()) {
274           // get current colormode
275           int colormode = is_SetColorMode(m_hCamera, IS_GET_COLOR_MODE);
276 
277           switch (colormode) {
278           default:
279           case IS_CM_MONO8:
280           case IS_CM_SENSOR_RAW8:
281             vpImageConvert::GreyToRGBa(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
282                                        m_BufferProps.width, m_BufferProps.height);
283             break;
284           case IS_CM_BGR565_PACKED:
285             throw(vpException(vpException::fatalError, "vpUeyeGrabber doesn't support BGR565 format"));
286 
287           case IS_CM_RGB8_PACKED:
288             vpImageConvert::RGBToRGBa(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
289                                       m_BufferProps.width, m_BufferProps.height);
290             break;
291           case IS_CM_BGR8_PACKED:
292             vpImageConvert::BGRToRGBa(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
293                                       m_BufferProps.width, m_BufferProps.height);
294             break;
295           case IS_CM_RGBA8_PACKED:
296             memcpy(reinterpret_cast<unsigned char*>(I.bitmap), reinterpret_cast<unsigned char*>(m_pLastBuffer), m_BufferProps.width * m_BufferProps.height * m_BufferProps.bitspp / 8);
297             break;
298           case IS_CM_BGRA8_PACKED:
299             vpImageConvert::BGRaToRGBa(reinterpret_cast<unsigned char*>(m_pLastBuffer), reinterpret_cast<unsigned char*>(I.bitmap),
300                                        m_BufferProps.width, m_BufferProps.height);
301             break;
302           }
303         }
304       }
305     }
306   }
307 
allocImages()308   bool allocImages()
309   {
310     m_pLastBuffer = NULL;
311     int nWidth = 0;
312     int nHeight = 0;
313 
314     UINT nAbsPosX;
315     UINT nAbsPosY;
316 
317     is_AOI(m_hCamera, IS_AOI_IMAGE_GET_POS_X_ABS, (void*)&nAbsPosX , sizeof(nAbsPosX));
318     is_AOI(m_hCamera, IS_AOI_IMAGE_GET_POS_Y_ABS, (void*)&nAbsPosY , sizeof(nAbsPosY));
319 
320     is_ClearSequence(m_hCamera);
321     freeImages();
322 
323     for (unsigned int i = 0; i < sizeof(m_Images) / sizeof(m_Images[0]); i++) {
324       nWidth = m_BufferProps.width;
325       nHeight = m_BufferProps.height;
326 
327       if (nAbsPosX) {
328         m_BufferProps.width = nWidth = m_SensorInfo.nMaxWidth;
329       }
330       if (nAbsPosY) {
331         m_BufferProps.height = nHeight = m_SensorInfo.nMaxHeight;
332       }
333 
334       if (is_AllocImageMem (m_hCamera, nWidth, nHeight, m_BufferProps.bitspp, &m_Images[i].pBuf,
335                             &m_Images[i].nImageID) != IS_SUCCESS)
336         return false;
337       if (is_AddToSequence (m_hCamera, m_Images[i].pBuf, m_Images[i].nImageID) != IS_SUCCESS)
338         return false;
339 
340       m_Images[i].nImageSeqNum = i + 1;
341       m_Images[i].nBufferSize = nWidth * nHeight * m_BufferProps.bitspp / 8;
342     }
343 
344     return true;
345   }
346 
cameraInitialized()347   int cameraInitialized()
348   {
349     int ret = 0;
350     unsigned int uInitialParameterSet = IS_CONFIG_INITIAL_PARAMETERSET_NONE;
351 
352     if ((ret=is_GetCameraInfo (m_hCamera, &m_CamInfo)) != IS_SUCCESS) {
353       throw(vpException(vpException::fatalError, "uEye error: GetCameraInfo failed"));
354     }
355     else if ((ret=is_GetSensorInfo (m_hCamera, &m_SensorInfo)) != IS_SUCCESS)  {
356       throw(vpException(vpException::fatalError, "uEye error: GetSensorInfo failed"));
357     }
358     else if ((ret = is_Configuration(IS_CONFIG_INITIAL_PARAMETERSET_CMD_GET, &uInitialParameterSet, sizeof(unsigned int))) != IS_SUCCESS) {
359       throw(vpException(vpException::fatalError, "uEye error: querying 'initial parameter set' failed"));
360     }
361     else
362     {
363       //m_nWidth = m_SensorInfo.nMaxWidth;
364       //m_nHeight = m_SensorInfo.nMaxHeight;
365 
366       // restore all defaults
367       // do this only if there is no 'initial parameter set' installed.
368       // if an 'initial parameter set' is installed we must not overwrite this setup!
369       if (uInitialParameterSet == IS_CONFIG_INITIAL_PARAMETERSET_NONE)
370       {
371         ret = is_ResetToDefault (m_hCamera);
372       }
373 
374       int colormode = 0;
375       if (m_SensorInfo.nColorMode >= IS_COLORMODE_BAYER) {
376         colormode = IS_CM_BGRA8_PACKED;
377       }
378       else {
379         colormode = IS_CM_MONO8;
380       }
381 
382       if (is_SetColorMode (m_hCamera, colormode) != IS_SUCCESS) {
383         throw(vpException(vpException::fatalError, "uEye error: SetColorMode failed"));
384       }
385 
386       /* get some special camera properties */
387       ZeroMemory (&m_CameraProps, sizeof(m_CameraProps));
388 
389       // If the camera does not support a continuous AOI -> it uses special image formats
390       m_CameraProps.bUsesImageFormats = false;
391       INT nAOISupported = 0;
392       if (is_ImageFormat(m_hCamera, IMGFRMT_CMD_GET_ARBITRARY_AOI_SUPPORTED, (void*)&nAOISupported,
393                          sizeof(nAOISupported)) == IS_SUCCESS) {
394         m_CameraProps.bUsesImageFormats = (nAOISupported == 0);
395       }
396 
397       /* set the default image format, if used */
398       if (m_CameraProps.bUsesImageFormats) {
399         // search the default formats
400         m_CameraProps.nImgFmtNormal = searchDefImageFormats(CAPTMODE_FREERUN | CAPTMODE_SINGLE);
401         m_CameraProps.nImgFmtDefaultNormal = m_CameraProps.nImgFmtNormal;
402         m_CameraProps.nImgFmtTrigger = searchDefImageFormats(CAPTMODE_TRIGGER_SOFT_SINGLE);
403         m_CameraProps.nImgFmtDefaultTrigger = m_CameraProps.nImgFmtTrigger;
404         // set the default formats
405         if ((ret=is_ImageFormat(m_hCamera, IMGFRMT_CMD_SET_FORMAT, (void*)&m_CameraProps.nImgFmtNormal,
406                                 sizeof(m_CameraProps.nImgFmtNormal))) == IS_SUCCESS) {
407           //m_nImageFormat = nFormat;
408           //bRet = TRUE;
409         }
410       }
411 
412       /* setup the capture parameter */
413       setupCapture();
414 
415       enableEvent(IS_SET_EVENT_FRAME);
416     }
417 
418     m_pLastBuffer = NULL;
419 
420     return ret;
421   }
422 
close()423   void close()
424   {
425     if (m_hCamera == IS_INVALID_HIDS)
426       return;
427 
428     if (m_hCamera) {
429       if (m_bLive && m_bLiveStarted) {
430         INT nRet = 1;
431         double t = vpTime::measureTimeSecond();
432         while (nRet != IS_SUCCESS && (vpTime::measureTimeSecond() - t) <= 2. ) {
433           nRet = is_StopLiveVideo(m_hCamera, IS_WAIT);
434         }
435         m_bLiveStarted = false;
436       }
437 
438       is_ClearSequence(m_hCamera);
439       freeImages();
440 
441       if (is_ExitCamera(m_hCamera) != IS_SUCCESS) {
442         throw(vpException(vpException::fatalError, "Cannot logoff camera"));
443       }
444 
445       disableEvent();
446 
447       m_hCamera = (HIDS)0;
448     }
449   }
450 
disableEvent()451   void disableEvent()
452   {
453     is_DisableEvent (m_hCamera, m_event);
454 #ifndef __linux__
455     is_ExitEvent(m_hCamera, m_event);
456     CloseHandle(m_hEvent);
457 #endif
458   }
459 
460 
enableEvent(int event)461   int enableEvent(int event)
462   {
463     int ret = 0;
464     m_event = event;
465 #ifndef __linux__
466     m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
467     if (m_hEvent == NULL) {
468       return -1;
469     }
470     ret = is_InitEvent(m_hCamera, m_hEvent, m_event);
471 #endif
472     ret = is_EnableEvent (m_hCamera, m_event);
473 
474     return ret;
475   }
476 
waitEvent()477   int waitEvent()
478   {
479 #ifdef __linux__
480     if (is_WaitEvent (m_hCamera, m_event, EVENTTHREAD_WAIT_TIMEOUT) == IS_SUCCESS) {
481 #else
482     if (WaitForSingleObject(m_hEvent, EVENTTHREAD_WAIT_TIMEOUT) == WAIT_OBJECT_0) {
483 #endif
484       return IS_SUCCESS;
485     }
486     else {
487       return IS_TIMED_OUT;
488     }
489   }
490 
491   void freeImages()
492   {
493     m_pLastBuffer = NULL;
494     //printf ("freeing image buffers\n");
495     for (unsigned int i = 0; i < sizeof(m_Images) / sizeof(m_Images[0]); i++) {
496       if (NULL != m_Images[i].pBuf) {
497         is_FreeImageMem (m_hCamera, m_Images[i].pBuf, m_Images[i].nImageID);
498       }
499 
500       m_Images[i].pBuf = NULL;
501       m_Images[i].nImageID = 0;
502       m_Images[i].nImageSeqNum = 0;
503     }
504   }
505 
506   std::string getActiveCameraModel() const
507   {
508     return m_CamListInfo.Model;
509   }
510 
511   std::string getActiveCameraSerialNumber() const
512   {
513     return m_CamListInfo.SerNo;
514   }
515 
516   int getBitsPerPixel(int colormode)
517   {
518     switch (colormode)
519     {
520     default:
521     case IS_CM_MONO8:
522     case IS_CM_SENSOR_RAW8:
523       return 8;   // occupies 8 Bit
524     case IS_CM_MONO12:
525     case IS_CM_MONO16:
526     case IS_CM_SENSOR_RAW12:
527     case IS_CM_SENSOR_RAW16:
528     case IS_CM_BGR5_PACKED:
529     case IS_CM_BGR565_PACKED:
530     case IS_CM_UYVY_PACKED:
531     case IS_CM_CBYCRY_PACKED:
532       return 16;  // occupies 16 Bit
533     case IS_CM_RGB8_PACKED:
534     case IS_CM_BGR8_PACKED:
535       return 24;
536     case IS_CM_RGBA8_PACKED:
537     case IS_CM_BGRA8_PACKED:
538     case IS_CM_RGBY8_PACKED:
539     case IS_CM_BGRY8_PACKED:
540     case IS_CM_RGB10_PACKED:
541     case IS_CM_BGR10_PACKED:
542       return 32;
543     }
544   }
545 
546   std::vector<unsigned int> getCameraIDList() const
547   {
548     CameraList camera_list;
549     return camera_list.getCameraIDList();
550   }
551 
552   std::vector<std::string> getCameraModelList() const
553   {
554     CameraList camera_list;
555     return camera_list.getCameraModelList();
556   }
557 
558   std::vector<std::string> getCameraSerialNumberList() const
559   {
560     CameraList camera_list;
561     return camera_list.getCameraSerialNumberList();
562   }
563 
564   unsigned int getFrameHeight() const
565   {
566     if (!isConnected()) {
567       throw(vpException(vpException::fatalError, "Unable to get frame height. Camera connexion is not opened"));
568     }
569     return static_cast<unsigned int>(m_BufferProps.height);
570   }
571 
572   unsigned int getFrameWidth() const
573   {
574     if (!isConnected()) {
575       throw(vpException(vpException::fatalError, "Unable to get frame width. Camera connexion is not opened"));
576     }
577     return static_cast<unsigned int>(m_BufferProps.width);
578   }
579 
580   double getFramerate() const
581   {
582     if (! m_hCamera) {
583       return 0;
584     }
585     double fps;
586 
587     // Get framerate
588     if (is_GetFramesPerSecond (m_hCamera, &fps) != IS_SUCCESS) {
589       if (m_verbose) {
590         std::cout << "Unable to get acquisition frame rate" << std::endl;
591       }
592     }
593     return fps;
594   }
595 
596   INT getImageID (char* pbuf)
597   {
598     if (!pbuf)
599       return 0;
600 
601     for (unsigned int i = 0; i < sizeof(m_Images) / sizeof(m_Images[0]); i++)
602       if (m_Images[i].pBuf == pbuf)
603         return m_Images[i].nImageID;
604 
605     return 0;
606   }
607 
608   INT getImageNum(char* pbuf)
609   {
610     if (!pbuf)
611       return 0;
612 
613     for (unsigned int i = 0; i < sizeof(m_Images) / sizeof(m_Images[0]); i++)
614       if (m_Images[i].pBuf == pbuf)
615         return m_Images[i].nImageSeqNum;
616 
617     return 0;
618   }
619 
620   bool isConnected() const
621   {
622     return (m_hCamera != (HIDS) 0);
623   }
624 
625   void loadParameters(const std::string &filename)
626   {
627     if (! vpIoTools::checkFilename(filename)) {
628       throw(vpException(vpException::fatalError, "Camera parameters file doesn't exist: %s", filename.c_str()));
629     }
630 
631     const std::wstring filename_(filename.begin(), filename.end());
632     int ret = is_ParameterSet(m_hCamera, IS_PARAMETERSET_CMD_LOAD_FILE, (void*) filename_.c_str(), 0);
633 
634     if (ret == IS_INVALID_CAMERA_TYPE) {
635       throw(vpException(vpException::fatalError, "The camera parameters file %s belong to a different camera", filename.c_str()));
636     }
637     else if (ret == IS_INCOMPATIBLE_SETTING) {
638       throw(vpException(vpException::fatalError, "Because of incompatible settings, cannot load parameters from file %s", filename.c_str()));
639     }
640     else if (ret != IS_SUCCESS) {
641       throw(vpException(vpException::fatalError, "Cannot load parameters from file %s", filename.c_str()));
642     }
643     else {
644       std::cout << "Parameters loaded sucessfully" << std::endl;
645     }
646 
647     setupCapture();
648   }
649 
650   void open()
651   {
652     if (m_hCamera) {
653       if (is_ExitCamera(m_hCamera) != IS_SUCCESS) {
654         throw(vpException(vpException::fatalError, "Cannot logoff camera"));
655       }
656     }
657 
658     // open the selected camera
659     m_hCamera = (HIDS) (m_CamListInfo.dwDeviceID | IS_USE_DEVICE_ID); // open camera
660 
661     if (is_InitCamera(&m_hCamera, 0) != IS_SUCCESS) { // init camera - no window handle required
662       throw(vpException(vpException::fatalError, "Cannot open connexion with IDS uEye camera"));
663     }
664 
665     int ret = cameraInitialized();
666     if (ret != IS_SUCCESS) {
667       throw(vpException(vpException::fatalError, "Unable to initialize uEye camera"));
668     }
669   }
670 
671   template <class Type>
672   void open(vpImage<Type> &I)
673   {
674     open();
675     I.resize(m_SensorInfo.nMaxHeight, m_SensorInfo.nMaxWidth);
676   }
677 
678   /*! \brief search the right default image format of a camera
679    *
680    * \param suppportMask
681    * \return found imageformat
682    */
683   int searchDefImageFormats(int suppportMask)
684   {
685     int ret = IS_SUCCESS;
686     int nNumber;
687     int format = 0;
688     IMAGE_FORMAT_LIST *pFormatList;
689     IS_RECT rectAOI;
690 
691     if ((ret=is_ImageFormat(m_hCamera, IMGFRMT_CMD_GET_NUM_ENTRIES, (void*)&nNumber, sizeof(nNumber))) == IS_SUCCESS &&
692         (ret=is_AOI(m_hCamera, IS_AOI_IMAGE_GET_AOI, (void*)&rectAOI, sizeof(rectAOI))) == IS_SUCCESS) {
693       int i = 0;
694       int nSize = sizeof(IMAGE_FORMAT_LIST) + (nNumber - 1) * sizeof(IMAGE_FORMAT_LIST);
695       pFormatList = (IMAGE_FORMAT_LIST*)(new char[nSize]);
696       pFormatList->nNumListElements = nNumber;
697       pFormatList->nSizeOfListEntry = sizeof(IMAGE_FORMAT_INFO);
698 
699       if((ret=is_ImageFormat(m_hCamera, IMGFRMT_CMD_GET_LIST, (void*)pFormatList, nSize)) == IS_SUCCESS) {
700         for(i=0; i<nNumber; i++) {
701           if ((pFormatList->FormatInfo[i].nSupportedCaptureModes & suppportMask) &&
702               pFormatList->FormatInfo[i].nHeight == (UINT)rectAOI.s32Height &&
703               pFormatList->FormatInfo[i].nWidth  == (UINT)rectAOI.s32Width) {
704             format = pFormatList->FormatInfo[i].nFormatID;
705             break;
706           }
707         }
708       }
709       else  {
710         throw(vpException(vpException::fatalError, "uEye error: is_ImageFormat returned %d", ret));
711       }
712 
713       delete (pFormatList);
714     }
715     else
716     {
717       throw(vpException(vpException::fatalError, "uEye error: is_ImageFormat returned %d", ret));
718     }
719     return format;
720   }
721 
722   int setActiveCamera(unsigned int cam_index)
723   {
724     m_cameraList = new CameraList;
725     m_activeCameraSelected = m_cameraList->setActiveCamera(cam_index);
726     if (! m_activeCameraSelected) {
727       m_CamListInfo = m_cameraList->getCameraInfo();
728     }
729     delete m_cameraList;
730     return m_activeCameraSelected;
731   }
732 
733   std::string toUpper(const std::basic_string<char>& s)
734   {
735     std::string s_upper = s;
736     for (std::basic_string<char>::iterator p = s_upper.begin(); p != s_upper.end(); ++p) {
737       *p = toupper(*p);
738     }
739     return s_upper;
740   }
741 
742   int setColorMode(const std::string &color_mode)
743   {
744     if (! isConnected()) {
745       throw(vpException(vpException::fatalError, "Cannot set color mode. Connection to active uEye camera is not opened"));
746     }
747 
748     std::string color_mode_upper = toUpper(color_mode);
749     int cm = IS_CM_MONO8;
750     if (color_mode_upper == "MONO8") {
751       cm = IS_CM_MONO8;
752     }
753     else if (color_mode_upper == "RGB24") {
754       cm = IS_CM_BGR8_PACKED;
755     }
756     else if (color_mode_upper == "RGB32") {
757       cm = IS_CM_RGBA8_PACKED;
758     }
759     else {
760       throw(vpException(vpException::fatalError, "Unsupported color mode %s", color_mode.c_str()));
761     }
762 
763     INT ret = IS_SUCCESS;
764     if ((ret = is_SetColorMode(m_hCamera, cm)) != IS_SUCCESS) {
765       std::cout << "Could not set color mode of " << m_CamListInfo.Model << " to " << color_mode << std::endl;
766     }
767     else {
768       setupCapture();
769     }
770     return ret;
771   }
772 
773   int setFrameRate(bool auto_frame_rate, double frame_rate_hz)
774   {
775     if (! isConnected()) {
776       throw(vpException(vpException::fatalError, "Cannot set frame rate. Connection to active uEye camera is not opened"));
777     }
778 
779     INT ret = IS_SUCCESS;
780 
781     // Auto
782     if (auto_frame_rate) {
783       double pval1 = 0, pval2 = 0;
784 
785       // Make sure that auto shutter is enabled before enabling auto frame rate
786       bool autoShutterOn = false;
787       is_SetAutoParameter(m_hCamera, IS_GET_ENABLE_AUTO_SENSOR_SHUTTER, &pval1, &pval2);
788       autoShutterOn |= (pval1 != 0);
789       is_SetAutoParameter(m_hCamera, IS_GET_ENABLE_AUTO_SHUTTER, &pval1, &pval2);
790       autoShutterOn |= (pval1 != 0);
791       if (!autoShutterOn) {
792         if (m_verbose) {
793           std::cout << "Auto shutter mode is not supported for " << m_CamListInfo.Model << std::endl;
794         }
795         return IS_NO_SUCCESS;
796       }
797 
798       // Set frame rate / auto
799       pval1 = auto_frame_rate;
800       if ((ret = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_SENSOR_FRAMERATE,
801                                      &pval1, &pval2)) != IS_SUCCESS) {
802         if ((ret = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_FRAMERATE,
803                                        &pval1, &pval2)) != IS_SUCCESS) {
804           if (m_verbose) {
805             std::cout << "Auto frame rate mode is not supported for " << m_CamListInfo.Model << std::endl;
806           }
807           return IS_NO_SUCCESS;
808         }
809       }
810     }
811     else { // Manual
812       double minFrameTime, maxFrameTime, intervalFrameTime, newFrameRate;
813       // Make sure that user-requested frame rate is achievable
814       if ((ret = is_GetFrameTimeRange(m_hCamera, &minFrameTime,
815                                       &maxFrameTime, &intervalFrameTime)) != IS_SUCCESS) {
816         if (m_verbose) {
817           std::cout << "Failed to query valid frame rate range from " << m_CamListInfo.Model << std::endl;
818         }
819         return ret;
820       }
821       CAP(frame_rate_hz, 1.0/maxFrameTime, 1.0/minFrameTime);
822 
823       // Update frame rate
824       if ((ret = is_SetFrameRate(m_hCamera, frame_rate_hz, &newFrameRate)) != IS_SUCCESS) {
825         if (m_verbose) {
826           std::cout << "Failed to set frame rate to " << frame_rate_hz <<
827                        " MHz for " << m_CamListInfo.Model << std::endl;
828         }
829         return ret;
830       } else if (frame_rate_hz != newFrameRate) {
831         frame_rate_hz = newFrameRate;
832       }
833     }
834 
835     if (m_verbose) {
836       std::cout << "Updated frame rate for " << m_CamListInfo.Model << ": " <<
837                    ((auto_frame_rate) ? "auto" : std::to_string(frame_rate_hz)) << " Hz" << std::endl;
838     }
839 
840     return ret;
841   }
842 
843   int setExposure(bool auto_exposure, double exposure_ms)
844   {
845     if (! isConnected()) {
846       throw(vpException(vpException::fatalError, "Cannot set exposure. Connection to active uEye camera is not opened"));
847     }
848 
849     INT err = IS_SUCCESS;
850 
851     double minExposure, maxExposure;
852 
853     // Set auto exposure
854     if (auto_exposure) {
855       double pval1 = auto_exposure, pval2 = 0;
856       if ((err = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_SENSOR_SHUTTER,
857                                      &pval1, &pval2)) != IS_SUCCESS) {
858         if ((err = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_SHUTTER,
859                                        &pval1, &pval2)) != IS_SUCCESS) {
860           std::cout << "Auto exposure mode is not supported for " << m_CamListInfo.Model << std::endl;
861           return IS_NO_SUCCESS;
862         }
863       }
864     }
865 
866     else { // Set manual exposure timing
867       // Make sure that user-requested exposure rate is achievable
868       if (((err = is_Exposure(m_hCamera, IS_EXPOSURE_CMD_GET_EXPOSURE_RANGE_MIN,
869                               (void*) &minExposure, sizeof(minExposure))) != IS_SUCCESS) ||
870           ((err = is_Exposure(m_hCamera, IS_EXPOSURE_CMD_GET_EXPOSURE_RANGE_MAX,
871                               (void*) &maxExposure, sizeof(maxExposure))) != IS_SUCCESS)) {
872         std::cout << "Failed to query valid exposure range from " << m_CamListInfo.Model << std::endl;
873         return err;
874       }
875       CAP(exposure_ms, minExposure, maxExposure);
876 
877       // Update exposure
878       if ((err = is_Exposure(m_hCamera, IS_EXPOSURE_CMD_SET_EXPOSURE,
879                              (void*) &(exposure_ms), sizeof(exposure_ms))) != IS_SUCCESS) {
880         std::cout << "Failed to set exposure to " << exposure_ms <<
881                      " ms for " << m_CamListInfo.Model << std::endl;
882         return err;
883       }
884     }
885 
886     if (m_verbose) {
887       std::cout << "Updated exposure: " << ((auto_exposure) ? "auto" : std::to_string(exposure_ms) + " ms") <<
888                    " for " << m_CamListInfo.Model << std::endl;
889     }
890 
891     return err;
892   }
893 
894   int setGain(bool auto_gain, int master_gain, bool gain_boost)
895   {
896     if (! isConnected()) {
897       throw(vpException(vpException::fatalError, "Cannot set gain. Connection to active uEye camera is not opened"));
898     }
899 
900     INT err = IS_SUCCESS;
901 
902     // Validate arguments
903     CAP(master_gain, 0, 100);
904 
905     double pval1 = 0, pval2 = 0;
906 
907     if (auto_gain) {
908       // Set auto gain
909       pval1 = 1;
910       if ((err = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_SENSOR_GAIN,
911                                      &pval1, &pval2)) != IS_SUCCESS) {
912         if ((err = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_GAIN,
913                                        &pval1, &pval2)) != IS_SUCCESS) {
914           if (m_verbose) {
915             std::cout << m_CamListInfo.Model << " does not support auto gain mode" << std::endl;
916           }
917           return IS_NO_SUCCESS;
918         }
919       }
920     } else {
921       // Disable auto gain
922       if ((err = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_SENSOR_GAIN,
923                                      &pval1, &pval2)) != IS_SUCCESS) {
924         if ((err = is_SetAutoParameter(m_hCamera, IS_SET_ENABLE_AUTO_GAIN,
925                                        &pval1, &pval2)) != IS_SUCCESS) {
926           std::cout << m_CamListInfo.Model << " does not support auto gain mode" << std::endl;
927         }
928       }
929 
930       // Set gain boost
931       if (is_SetGainBoost(m_hCamera, IS_GET_SUPPORTED_GAINBOOST) != IS_SET_GAINBOOST_ON) {
932         gain_boost = false;
933       } else {
934         if ((err = is_SetGainBoost(m_hCamera,
935                                    (gain_boost) ? IS_SET_GAINBOOST_ON : IS_SET_GAINBOOST_OFF))
936             != IS_SUCCESS) {
937           std::cout << "Failed to " << ((gain_boost) ? "enable" : "disable") <<
938                        " gain boost for " << m_CamListInfo.Model << std::endl;
939         }
940       }
941 
942       // Set manual gain parameters
943       if ((err = is_SetHardwareGain(m_hCamera, master_gain,
944                                     IS_IGNORE_PARAMETER, IS_IGNORE_PARAMETER, IS_IGNORE_PARAMETER)) != IS_SUCCESS) {
945         std::cout << "Failed to set manual master gain: " << master_gain << " for " << m_CamListInfo.Model << std::endl;
946         return IS_NO_SUCCESS;
947       }
948     }
949 
950     if (m_verbose) {
951       if (auto_gain) {
952         std::cout << "Updated gain for " << m_CamListInfo.Model << ": auto" << std::endl;
953       } else {
954         std::cout << "Updated gain for " << m_CamListInfo.Model << ": manual master gain " << master_gain << std::endl;
955 
956       }
957       std::cout << "\n  gain boost: " << (gain_boost ? "enabled" : "disabled") << std::endl;;
958     }
959 
960     return err;
961   }
962 
963   void applySubsamplingSettings(int subsamplingMode, int nMode)
964   {
965     INT ret = IS_SUCCESS;
966     int currentSubsampling = is_SetSubSampling(m_hCamera, IS_GET_SUBSAMPLING);
967     if ((ret = is_SetSubSampling (m_hCamera, subsamplingMode | nMode)) != IS_SUCCESS) {
968       throw(vpException(vpException::fatalError, "Unable to apply subsampling factor"));
969     }
970 
971     int newSubsampling = is_SetSubSampling(m_hCamera, IS_GET_SUBSAMPLING);
972     if((nMode == IS_SUBSAMPLING_DISABLE) && (currentSubsampling == newSubsampling)) {
973       // the subsampling nMode IS_SUBSAMPLING_DISABLE was expected, but the device
974       // did not changed the format, disable subsampling.
975       if ((ret = is_SetSubSampling (m_hCamera, IS_SUBSAMPLING_DISABLE)) != IS_SUCCESS) {
976         throw(vpException(vpException::fatalError, "Unable to apply subsampling factor"));
977       }
978     }
979   }
980 
981   void setSubsampling(int factor)
982   {
983     if (! isConnected()) {
984       throw(vpException(vpException::fatalError, "Cannot set sub sampling factor. Connection to active uEye camera is not opened"));
985     }
986 
987     INT hMode = IS_SUBSAMPLING_DISABLE, vMode = IS_SUBSAMPLING_DISABLE;
988 
989     switch(factor) {
990     case 2:
991       hMode = IS_SUBSAMPLING_2X_HORIZONTAL;
992       vMode = IS_SUBSAMPLING_2X_VERTICAL;
993       break;
994     case 3:
995       hMode = IS_SUBSAMPLING_3X_HORIZONTAL;
996       vMode = IS_SUBSAMPLING_3X_VERTICAL;
997       break;
998     case 4:
999       hMode = IS_SUBSAMPLING_4X_HORIZONTAL;
1000       vMode = IS_SUBSAMPLING_4X_VERTICAL;
1001       break;
1002     case 5:
1003       hMode = IS_SUBSAMPLING_5X_HORIZONTAL;
1004       vMode = IS_SUBSAMPLING_5X_VERTICAL;
1005       break;
1006     case 6:
1007       hMode = IS_SUBSAMPLING_6X_HORIZONTAL;
1008       vMode = IS_SUBSAMPLING_6X_VERTICAL;
1009       break;
1010     case 8:
1011       hMode = IS_SUBSAMPLING_8X_HORIZONTAL;
1012       vMode = IS_SUBSAMPLING_8X_VERTICAL;
1013       break;
1014     case 16:
1015       hMode = IS_SUBSAMPLING_16X_HORIZONTAL;
1016       vMode = IS_SUBSAMPLING_16X_VERTICAL;
1017       break;
1018     default:
1019       hMode = IS_SUBSAMPLING_DISABLE;
1020       vMode = IS_SUBSAMPLING_DISABLE;
1021     }
1022 
1023     if (m_bLive && m_bLiveStarted) {
1024       is_StopLiveVideo (m_hCamera, IS_WAIT);
1025     }
1026 
1027     INT subsamplingModeH = is_SetSubSampling (m_hCamera, IS_GET_SUBSAMPLING) & IS_SUBSAMPLING_MASK_VERTICAL;
1028     applySubsamplingSettings(subsamplingModeH, hMode);
1029 
1030     INT subsamplingModeV = is_SetSubSampling (m_hCamera, IS_GET_SUBSAMPLING) & IS_SUBSAMPLING_MASK_HORIZONTAL;
1031     applySubsamplingSettings(subsamplingModeV, vMode);
1032 
1033     setupCapture();
1034   }
1035 
1036   void setWhiteBalance(bool auto_wb)
1037   {
1038     if (! isConnected()) {
1039       throw(vpException(vpException::fatalError, "Cannot set white balance. Connection to active uEye camera is not opened"));
1040     }
1041 
1042     double dblAutoWb = 0.0;
1043 
1044     if (auto_wb) {
1045       dblAutoWb = 0.0;
1046       is_SetAutoParameter (m_hCamera, IS_SET_AUTO_WB_ONCE, &dblAutoWb, NULL);
1047 
1048       dblAutoWb = 1.0;
1049       is_SetAutoParameter (m_hCamera, IS_SET_ENABLE_AUTO_WHITEBALANCE, &dblAutoWb, NULL);
1050     }
1051     else {
1052       dblAutoWb = 0.0;
1053       is_SetAutoParameter (m_hCamera, IS_SET_AUTO_WB_ONCE, &dblAutoWb, NULL);
1054       is_SetAutoParameter (m_hCamera, IS_SET_ENABLE_AUTO_WHITEBALANCE, &dblAutoWb, NULL);
1055     }
1056   }
1057 
1058   int setupCapture()
1059   {
1060     int width, height;
1061     // init the memorybuffer properties
1062     ZeroMemory(&m_BufferProps, sizeof(m_BufferProps));
1063 
1064     IS_RECT rectAOI;
1065     INT nRet = is_AOI(m_hCamera, IS_AOI_IMAGE_GET_AOI, (void*)&rectAOI, sizeof(rectAOI));
1066 
1067     if (nRet == IS_SUCCESS) {
1068       width  = rectAOI.s32Width;
1069       height = rectAOI.s32Height;
1070 
1071       // get current colormode
1072       int colormode = is_SetColorMode(m_hCamera, IS_GET_COLOR_MODE);
1073 
1074       if(colormode == IS_CM_BGR5_PACKED) {
1075         is_SetColorMode(m_hCamera, IS_CM_BGR565_PACKED);
1076         colormode = IS_CM_BGR565_PACKED;
1077         std::cout << "uEye color format 'IS_CM_BGR5_PACKED' actually not supported by vpUeyeGrabber, patched to 'IS_CM_BGR565_PACKED'" << std::endl;
1078       }
1079 
1080       // fill memorybuffer properties
1081       ZeroMemory (&m_BufferProps, sizeof(m_BufferProps));
1082       m_BufferProps.width  = width;
1083       m_BufferProps.height = height;
1084       m_BufferProps.bitspp = getBitsPerPixel(colormode);
1085 
1086       // Reallocate image buffers
1087       allocImages();
1088 
1089       if (m_verbose) {
1090         std::cout << "Capture ready set up." << std::endl;
1091       }
1092     }
1093     return 0;
1094   }
1095 
1096   void setVerbose(bool verbose)
1097   {
1098     m_verbose = verbose;
1099   }
1100 
1101 private:
1102   HIDS m_hCamera;			     // handle to camera
1103   INT m_nMemoryId;	       // grabber memory - buffer ID
1104   INT	m_nColorMode;	       // Y8/RGB16/RGB24/REG32
1105   INT	m_nBitsPerPixel;     // number of bits needed store one pixel
1106   int m_activeCameraSelected;
1107   SENSORINFO m_SensorInfo; // sensor information struct
1108   CAMINFO m_CamInfo;       // Camera (Board)info
1109   UEYE_CAMERA_INFO m_CamListInfo;
1110   char *m_pLastBuffer;
1111   CameraList *m_cameraList;
1112   struct sBufferProps m_BufferProps;
1113   struct sCameraProps m_CameraProps;
1114   UEYE_IMAGE m_Images[IMAGE_COUNT]; // uEye frame buffer array
1115   bool m_bLive;            // live or snapshot indicator
1116   bool m_bLiveStarted;     // live mode is started
1117   bool m_verbose;
1118   /* event waiting for */
1119   int m_event;
1120 #ifndef __linux__
1121   /* on windows we need an Event handle member */
1122   HANDLE m_hEvent;
1123 #endif
1124 };
1125 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
1126 
1127 /*
1128  **********************************************************************************************
1129  */
1130 
1131 /*!
1132  * Default constructor.
1133  * By default, the active camera is the first one that is found.
1134  * To select a specific camera use setActiveCamera().
1135  */
vpUeyeGrabber()1136 vpUeyeGrabber::vpUeyeGrabber()
1137   : m_impl(new vpUeyeGrabberImpl())
1138 {
1139 
1140 }
1141 
1142 /*!
1143  * Destructor.
1144  */
~vpUeyeGrabber()1145 vpUeyeGrabber::~vpUeyeGrabber()
1146 {
1147   delete m_impl;
1148 }
1149 
1150 /*!
1151  * Capture a new grayscale image.
1152  *
1153  * \param[out] I : Captured image.
1154  * \param[out] timestamp_camera : Time of image capture in milli-seconds with a resolution of 0.1 μs, or NULL if not wanted.
1155  * The time of image capture is defined as:
1156  * - The time when a (hardware or software) trigger event is received by the camera in trigger mode.
1157  *   The delay between the receipt of the trigger signal and the start of exposure depends on the sensor.
1158  * - The time when the sensor starts to output image data in freerun mode. A rolling shutter sensors
1159  *   starts to output image data after exposure of the first row. With a global shutter sensor, image data
1160  *   is output after exposure of all rows.
1161  * \param[out] timestamp_system : Time with a resolution of 1 ms synchronized with the PC's system time,
1162  * and resynchronized every 60 seconds. This may cause minor time shifts (average time about 3 ms).
1163  * The format of the string is the following: `YYYY:MM:DD:HH:MM:SS:mmm` for
1164  * year, month, day, hour, minute, second, millisecond.
1165  *
1166  * To determine the exact interval between two image captures, it is therefore recommended to read out the camera
1167  * timestamp provided in `timestamp_camera`.
1168  *
1169  * \sa setColorMode()
1170  */
acquire(vpImage<unsigned char> & I,double * timestamp_camera,std::string * timestamp_system)1171 void vpUeyeGrabber::acquire(vpImage<unsigned char> &I, double *timestamp_camera, std::string *timestamp_system)
1172 {
1173   m_impl->acquire(I, timestamp_camera, timestamp_system);
1174 }
1175 
1176 /*!
1177  * Capture a new color image.
1178  * \param[out] I : Captured image.
1179  * \param[out] timestamp_camera : Time of image capture in milli-seconds with a resolution of 0.1 μs, or NULL if not wanted.
1180  * The time of image capture is defined as:
1181  * - The time when a (hardware or software) trigger event is received by the camera in trigger mode.
1182  *   The delay between the receipt of the trigger signal and the start of exposure depends on the sensor.
1183  * - The time when the sensor starts to output image data in freerun mode. A rolling shutter sensors
1184  *   starts to output image data after exposure of the first row. With a global shutter sensor, image data
1185  *   is output after exposure of all rows.
1186  * \param[out] timestamp_system : Time with a resolution of 1 ms synchronized with the PC's system time,
1187  * and resynchronized every 60 seconds. This may cause minor time shifts (average time about 3 ms).
1188  * The format of the string is the following: `YYYY:MM:DD:HH:MM:SS:mmm` for
1189  * year, month, day, hour, minute, second, millisecond.
1190  *
1191  * To determine the exact interval between two image captures, it is therefore recommended to read out the camera
1192  * timestamp provided in `timestamp_camera`.
1193  *
1194  * \sa setColorMode()
1195  */
acquire(vpImage<vpRGBa> & I,double * timestamp_camera,std::string * timestamp_system)1196 void vpUeyeGrabber::acquire(vpImage<vpRGBa> &I, double *timestamp_camera, std::string *timestamp_system)
1197 {
1198   m_impl->acquire(I, timestamp_camera, timestamp_system);
1199 }
1200 
1201 /*!
1202  * Get active camera model.
1203  *
1204  * \sa setActiveCamera(), getActiveCameraSerialNumber()
1205  */
getActiveCameraModel() const1206 std::string vpUeyeGrabber::getActiveCameraModel() const
1207 {
1208   return m_impl->getActiveCameraModel();
1209 }
1210 
1211 /*!
1212  * Get active camera serial number.
1213  *
1214  * \sa setActiveCamera(), getActiveCameraModel()
1215  */
getActiveCameraSerialNumber() const1216 std::string vpUeyeGrabber::getActiveCameraSerialNumber() const
1217 {
1218   return m_impl->getActiveCameraSerialNumber();
1219 }
1220 
1221 /*!
1222  * Get camera ID list.
1223  * \return Vector of camera ID corresponding to each camera index. The size of this vector gives correponds
1224  * also to the number of connected cameras.
1225  *
1226  * \sa getCameraModelList(), getCameraSerialNumberList()
1227  */
getCameraIDList() const1228 std::vector<unsigned int> vpUeyeGrabber::getCameraIDList() const
1229 {
1230   return m_impl->getCameraIDList();
1231 }
1232 
1233 /*!
1234  * Get camera model list.
1235  * \return Vector of camera models corresponding to each camera index. The size of this vector gives correponds
1236  * also to the number of connected cameras.
1237  *
1238  * \sa getCameraIDList(), getCameraSerialNumberList()
1239  */
getCameraModelList() const1240 std::vector<std::string> vpUeyeGrabber::getCameraModelList() const
1241 {
1242   return m_impl->getCameraModelList();
1243 }
1244 
1245 /*!
1246  * Get camera serial number list.
1247  * \return Vector of camera serial numbers corresponding to each camera index. The size of this vector gives correponds
1248  * also to the number of connected cameras.
1249  *
1250  * \sa getCameraIDList(), getCameraModelList()
1251  */
getCameraSerialNumberList() const1252 std::vector<std::string> vpUeyeGrabber::getCameraSerialNumberList() const
1253 {
1254   return m_impl->getCameraSerialNumberList();
1255 }
1256 
1257 /*!
1258  * Returns the current number of frames actually captured per second.
1259  * This function needs to be called after acquire().
1260  *
1261  * \sa acquire()
1262  */
getFramerate() const1263 double vpUeyeGrabber::getFramerate() const
1264 {
1265   return m_impl->getFramerate();
1266 }
1267 
1268 /*!
1269  * Return image width captured by the active camera.
1270  * \warning Image width could differ from the one returned by open()
1271  * depending on the subsampling settings loaded by loadParameters()
1272  *
1273  * \sa open(), getFrameWidth()
1274  */
getFrameHeight() const1275 unsigned int vpUeyeGrabber::getFrameHeight() const
1276 {
1277   return m_impl->getFrameHeight();
1278 }
1279 
1280 /*!
1281  * Return image height captured by the active camera.
1282  * \warning Image width could differ from the one returned by open()
1283  * depending on the subsampling settings loaded by loadParameters()
1284  *
1285  * \sa open(), getFrameHeight()
1286  */
getFrameWidth() const1287 unsigned int vpUeyeGrabber::getFrameWidth() const
1288 {
1289   return m_impl->getFrameWidth();
1290 }
1291 
1292 
1293 /*!
1294  * Return true if a camera is connected, false otherwise.
1295  */
isConnected() const1296 bool vpUeyeGrabber::isConnected() const
1297 {
1298   return m_impl->isConnected();
1299 }
1300 
1301 /*!
1302  * Load camera parameters from an `.ini` file.
1303  * \param[in] filename : Camera parameters file that contains camera settings. Such a file could be produced using `ueyedemo` binary
1304  * provided with IDS uEye Software Suite
1305  */
loadParameters(const std::string & filename)1306 void vpUeyeGrabber::loadParameters(const std::string &filename)
1307 {
1308   m_impl->loadParameters(filename);
1309 }
1310 
1311 /*!
1312  * Starts the driver and establishes the connection to the camera.
1313  * \param[out] I : Grayscale image that is resized to match the capture settings.
1314  */
open(vpImage<unsigned char> & I)1315 void vpUeyeGrabber::open(vpImage<unsigned char> &I)
1316 {
1317   m_impl->open(I);
1318 }
1319 
1320 /*!
1321  * Starts the driver and establishes the connection to the camera.
1322  * \param[out] I : Color image that is resized to match the capture settings.
1323  */
open(vpImage<vpRGBa> & I)1324 void vpUeyeGrabber::open(vpImage<vpRGBa> &I)
1325 {
1326   m_impl->open(I);
1327 }
1328 
1329 /*!
1330  * Select a camera from the camera list.
1331  * \param cam_index : Camera index.
1332  * \return True if successful, false otherwise.
1333  */
setActiveCamera(unsigned int cam_index)1334 bool vpUeyeGrabber::setActiveCamera(unsigned int cam_index)
1335 {
1336   return (m_impl->setActiveCamera(cam_index) ? false : true);
1337 }
1338 
1339 /*!
1340  * Updates active camera color mode.
1341  *
1342  * \warning Before caling this function the connexion with the active camera should be opened.
1343  *
1344  * \param[in] color_mode : Desired color mode. Admissible values are "MONO8", "RGB8" or "RGB32".
1345  * \note - When acquiring gray level images using acquire(vpImage<unsigned char> &) we strongly recommend to
1346  * set color mode to "MONO8".
1347  * \note - When acquiring color level images using acquire(vpImage<vpRGBa> &) we strongly recommend to
1348  * set color mode to "RGB32".
1349  * \return true if color mode is applied, false if the color mode is unsupported.
1350  *
1351  *  \sa open(), setExposure(), setFrameRate(), setGain(), setSubsampling(), setWhiteBalance()
1352  *
1353  */
setColorMode(const std::string & color_mode)1354 bool vpUeyeGrabber::setColorMode(const std::string &color_mode)
1355 {
1356   return (m_impl->setColorMode(color_mode) ? false : true);
1357 }
1358 
1359 /*!
1360  * Updates active camera exposure / shutter either to auto mode, or to specified manual parameters.
1361  *
1362  * \warning Before caling this function the connexion with the active camera should be opened.
1363  *
1364  * \param[in] auto_exposure : When true enable camera's hardware auto exposure / shutter.
1365  * This function returns false if the camera does not support auto exposure mode. When set to false, set manual exposure time.
1366  * \param[in] exposure_ms : Manual exposure setting time in ms. Valid value range depends on active camera pixel clock rate.
1367  * \return True if successful, false otherwise.
1368  *
1369  * \sa open(), setColorMode(), setFrameRate(), setGain(), setSubsampling(), setWhiteBalance()
1370  *
1371  */
setExposure(bool auto_exposure,double exposure_ms)1372 bool vpUeyeGrabber::setExposure(bool auto_exposure, double exposure_ms)
1373 {
1374   return (m_impl->setExposure(auto_exposure, exposure_ms) ? false : true);
1375 }
1376 
1377 /*!
1378  * Updates active camera frame rate either to auto mode, or to a specified manual value.
1379  *
1380  * Enabling auto frame rate mode requires to enable auto shutter mode.
1381  * Enabling auto frame rate mode will disable auto gain mode.
1382  *
1383  * \warning Before caling this function the connexion with the active camera should be opened.
1384  *
1385  * \param[in] auto_frame_rate : Updates camera's hardware auto frame rate mode. When true enable auto frame rate mode.
1386  * When set to false, enables manual frame rate mode.
1387  * \param[in] manual_frame_rate_hz : Desired manual frame rate in Hz. Valid value range depends on current camera pixel clock rate.
1388  * This parameter is only used when auto frame rate is disabled.
1389  * \return True if successful, false otherwise.
1390  *
1391  * A typical usage is the following:
1392  * \code
1393  * vpUeyeGrabber g;
1394  * vpImage<unsigned char> I;
1395  * g.open(I);
1396  * if (! g.setFrameRate(true)) {
1397  *   std::cout << "Unable to set auto frame rate" << std::endl;
1398  *   double manual_fps = 10.; // 10 Hz is required if auto frame rate is not possible
1399  *   if (g.setFrameRate(false, manual_fps)) {
1400  *     std::cout << "Framerate set to: " << manual_fps << std::endl;
1401  *   }
1402  * }
1403  * \endcode
1404  *
1405  * \sa open(), setColorMode(), setExposure(), setGain(), setSubsampling(), setWhiteBalance()
1406  */
setFrameRate(bool auto_frame_rate,double manual_frame_rate_hz)1407 bool vpUeyeGrabber::setFrameRate(bool auto_frame_rate, double manual_frame_rate_hz)
1408 {
1409   return (m_impl->setFrameRate(auto_frame_rate, manual_frame_rate_hz) ? false : true);
1410 }
1411 
1412 /*!
1413  * Updates active camera gain either to auto mode, or to specified manual parameters.
1414  *
1415  * Auto gain mode is disabled if auto frame rate mode is enabled.
1416  *
1417  * \warning Before caling this function the connexion with the active camera should be opened.
1418  *
1419  * \param[in] auto_gain : Updates camera's hardware auto gain mode.
1420  * - Set to true to enable auto gain.  If this mode is not supported, returns false.
1421  * - Set to false, to set manual gain and enable/disable gain boost/
1422  * \param[in] master_gain : Manual master gain percentage in range 0 - 100.
1423  * \param[in] gain_boost : Only in manual mode, enable/disable gain boost.
1424  * \return True if successful, false otherwise.
1425  *
1426  * \sa open(), setColorMode(), setExposure(), setFrameRate(), setSubsampling(), setWhiteBalance()
1427  */
setGain(bool auto_gain,int master_gain,bool gain_boost)1428 bool vpUeyeGrabber::setGain(bool auto_gain, int master_gain, bool gain_boost)
1429 {
1430   return (m_impl->setGain(auto_gain, master_gain, gain_boost) ? false : true);
1431 }
1432 
1433 /*!
1434  * Updates active camera image subsampling factor to reduce image size.
1435  *
1436  * \warning Before caling this function the connexion with the active camera should be opened.
1437  *
1438  * \param[in] factor : Desired subsampling factor. The number of rows and columns
1439  * of the resulting image corresponds to the full resolution image size divided by this factor.
1440  *
1441  * \sa open(), setColorMode(), setExposure(), setFrameRate(), setGain(), setWhiteBalance()
1442  */
setSubsampling(int factor)1443 void vpUeyeGrabber::setSubsampling(int factor)
1444 {
1445   m_impl->setSubsampling(factor);
1446 }
1447 
1448 /*!
1449  * Enables or disables the active camera auto white balance mode.
1450  *
1451  * \warning Before caling this function the connexion with the active camera should be opened.
1452  *
1453  * \param auto_wb : If true enable auto white balance mode. If false, disable auto white balance mode.
1454  *
1455  * \sa open(), setColorMode(), setExposure(), setFrameRate(), setGain(), setSubsampling()
1456  *
1457  */
setWhiteBalance(bool auto_wb)1458 void vpUeyeGrabber::setWhiteBalance(bool auto_wb)
1459 {
1460   m_impl->setWhiteBalance(auto_wb);
1461 }
1462 
1463 /*!
1464  * Enable/disable verbose mode.
1465  *
1466  * \param[in] verbose : true to enable, false to disable verbose mode.
1467  */
setVerbose(bool verbose)1468 void vpUeyeGrabber::setVerbose(bool verbose)
1469 {
1470   m_impl->setVerbose(verbose);
1471 }
1472 
1473 #elif !defined(VISP_BUILD_SHARED_LIBS)
1474 // Work arround to avoid warning: libvisp_sensor.a(vpUeyeGrabber.cpp.o) has no symbols
dummy_vpUeyeGrabber()1475 void dummy_vpUeyeGrabber(){};
1476 
1477 #endif
1478