• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "precomp.hpp"
2 
3 #ifdef WIN32
4 #include "xiApi.h"
5 #else
6 #include <m3api/xiApi.h>
7 #endif
8 
9 /**********************************************************************************/
10 
11 class CvCaptureCAM_XIMEA : public CvCapture
12 {
13 public:
CvCaptureCAM_XIMEA()14     CvCaptureCAM_XIMEA() { init(); }
~CvCaptureCAM_XIMEA()15     virtual ~CvCaptureCAM_XIMEA() { close(); }
16 
17     virtual bool open( int index );
18     virtual void close();
19     virtual double getProperty(int) const;
20     virtual bool setProperty(int, double);
21     virtual bool grabFrame();
22     virtual IplImage* retrieveFrame(int);
getCaptureDomain()23     virtual int getCaptureDomain() { return CV_CAP_XIAPI; } // Return the type of the capture object: CV_CAP_VFW, etc...
24 
25 private:
26     void init();
27     void errMsg(const char* msg, int errNum);
28     void resetCvImage();
29     int  getBpp();
30     IplImage* frame;
31 
32     HANDLE    hmv;
33     DWORD     numDevices;
34     int       timeout;
35     XI_IMG    image;
36 };
37 
38 /**********************************************************************************/
39 
cvCreateCameraCapture_XIMEA(int index)40 CvCapture* cvCreateCameraCapture_XIMEA( int index )
41 {
42     CvCaptureCAM_XIMEA* capture = new CvCaptureCAM_XIMEA;
43 
44     if( capture->open( index ))
45         return capture;
46 
47     delete capture;
48     return 0;
49 }
50 
51 /**********************************************************************************/
52 // Enumerate connected devices
init()53 void CvCaptureCAM_XIMEA::init()
54 {
55 #if defined WIN32 || defined _WIN32
56     xiGetNumberDevices( &numDevices);
57 #else
58     // try second re-enumeration if first one fails
59     if (xiGetNumberDevices( &numDevices) != XI_OK)
60     {
61         xiGetNumberDevices( &numDevices);
62     }
63 #endif
64     hmv = NULL;
65     frame = NULL;
66     timeout = 0;
67     memset(&image, 0, sizeof(XI_IMG));
68 }
69 
70 
71 /**********************************************************************************/
72 // Initialize camera input
open(int wIndex)73 bool CvCaptureCAM_XIMEA::open( int wIndex )
74 {
75 #define HandleXiResult(res) if (res!=XI_OK)  goto error;
76 
77     int mvret = XI_OK;
78 
79     if(numDevices == 0)
80         return false;
81 
82     if((mvret = xiOpenDevice( wIndex, &hmv)) != XI_OK)
83     {
84 #if defined WIN32 || defined _WIN32
85         errMsg("Open XI_DEVICE failed", mvret);
86         return false;
87 #else
88         // try opening second time if first fails
89         if((mvret = xiOpenDevice( wIndex, &hmv))  != XI_OK)
90         {
91             errMsg("Open XI_DEVICE failed", mvret);
92             return false;
93         }
94 #endif
95     }
96 
97     int width   = 0;
98     int height  = 0;
99     int isColor = 0;
100 
101     // always use auto exposure/gain
102     mvret = xiSetParamInt( hmv, XI_PRM_AEAG, 1);
103     HandleXiResult(mvret);
104 
105     mvret = xiGetParamInt( hmv, XI_PRM_WIDTH, &width);
106     HandleXiResult(mvret);
107 
108     mvret = xiGetParamInt( hmv, XI_PRM_HEIGHT, &height);
109     HandleXiResult(mvret);
110 
111     mvret = xiGetParamInt(hmv, XI_PRM_IMAGE_IS_COLOR, &isColor);
112     HandleXiResult(mvret);
113 
114     if(isColor) // for color cameras
115     {
116         // default image format RGB24
117         mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_RGB24);
118         HandleXiResult(mvret);
119 
120         // always use auto white balance for color cameras
121         mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1);
122         HandleXiResult(mvret);
123 
124         // allocate frame buffer for RGB24 image
125         frame = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
126     }
127     else // for mono cameras
128     {
129         // default image format MONO8
130         mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_MONO8);
131         HandleXiResult(mvret);
132 
133         // allocate frame buffer for MONO8 image
134         frame = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);
135     }
136 
137     //default capture timeout 10s
138     timeout = 10000;
139 
140     mvret = xiStartAcquisition(hmv);
141     if(mvret != XI_OK)
142     {
143         errMsg("StartAcquisition XI_DEVICE failed", mvret);
144         goto error;
145     }
146     return true;
147 
148 error:
149     errMsg("Open XI_DEVICE failed", mvret);
150     xiCloseDevice(hmv);
151     hmv = NULL;
152     return false;
153 }
154 
155 /**********************************************************************************/
156 
close()157 void CvCaptureCAM_XIMEA::close()
158 {
159     if(frame)
160         cvReleaseImage(&frame);
161 
162     if(hmv)
163     {
164         xiStopAcquisition(hmv);
165         xiCloseDevice(hmv);
166     }
167     hmv = NULL;
168 }
169 
170 /**********************************************************************************/
171 
grabFrame()172 bool CvCaptureCAM_XIMEA::grabFrame()
173 {
174     memset(&image, 0, sizeof(XI_IMG));
175     image.size = sizeof(XI_IMG);
176     int mvret = xiGetImage( hmv, timeout, &image);
177 
178     if(mvret == XI_ACQUISITION_STOPED)
179     {
180         xiStartAcquisition(hmv);
181         mvret = xiGetImage(hmv, timeout, &image);
182     }
183 
184     if(mvret != XI_OK)
185     {
186         errMsg("Error during GetImage", mvret);
187         return false;
188     }
189 
190     return true;
191 }
192 
193 /**********************************************************************************/
194 
retrieveFrame(int)195 IplImage* CvCaptureCAM_XIMEA::retrieveFrame(int)
196 {
197     // update cvImage after format has changed
198     resetCvImage();
199 
200     // copy pixel data
201     switch( image.frm)
202     {
203     case XI_MONO8       :
204     case XI_RAW8        : memcpy( frame->imageData, image.bp, image.width*image.height); break;
205     case XI_MONO16      :
206     case XI_RAW16       : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(WORD)); break;
207     case XI_RGB24       :
208     case XI_RGB_PLANAR  : memcpy( frame->imageData, image.bp, image.width*image.height*3); break;
209     case XI_RGB32       : memcpy( frame->imageData, image.bp, image.width*image.height*4); break;
210     default: break;
211     }
212     return frame;
213 }
214 
215 /**********************************************************************************/
216 
resetCvImage()217 void CvCaptureCAM_XIMEA::resetCvImage()
218 {
219     int width = 0, height = 0, format = 0;
220     xiGetParamInt( hmv, XI_PRM_WIDTH, &width);
221     xiGetParamInt( hmv, XI_PRM_HEIGHT, &height);
222     xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &format);
223 
224     if( (int)image.width != frame->width || (int)image.height != frame->height || image.frm != (XI_IMG_FORMAT)format)
225     {
226         if(frame) cvReleaseImage(&frame);
227         frame = NULL;
228 
229         switch( image.frm)
230         {
231         case XI_MONO8       :
232         case XI_RAW8        : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 1); break;
233         case XI_MONO16      :
234         case XI_RAW16       : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_16U, 1); break;
235         case XI_RGB24       :
236         case XI_RGB_PLANAR  : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 3); break;
237         case XI_RGB32       : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 4); break;
238         default :
239             return;
240         }
241     }
242     cvZero(frame);
243 }
244 /**********************************************************************************/
245 
getProperty(int property_id) const246 double CvCaptureCAM_XIMEA::getProperty( int property_id ) const
247 {
248     if(hmv == NULL)
249         return 0;
250 
251     int ival = 0;
252     float fval = 0;
253 
254     switch( property_id )
255     {
256     // OCV parameters
257     case CV_CAP_PROP_POS_FRAMES   : return (double) image.nframe;
258     case CV_CAP_PROP_FRAME_WIDTH  : xiGetParamInt( hmv, XI_PRM_WIDTH, &ival); return ival;
259     case CV_CAP_PROP_FRAME_HEIGHT : xiGetParamInt( hmv, XI_PRM_HEIGHT, &ival); return ival;
260     case CV_CAP_PROP_FPS          : xiGetParamFloat( hmv, XI_PRM_FRAMERATE, &fval); return fval;
261     case CV_CAP_PROP_GAIN         : xiGetParamFloat( hmv, XI_PRM_GAIN, &fval); return fval;
262     case CV_CAP_PROP_EXPOSURE     : xiGetParamInt( hmv, XI_PRM_EXPOSURE, &ival); return ival;
263 
264     // XIMEA camera properties
265     case CV_CAP_PROP_XI_DOWNSAMPLING  : xiGetParamInt( hmv, XI_PRM_DOWNSAMPLING, &ival); return ival;
266     case CV_CAP_PROP_XI_DATA_FORMAT   : xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &ival); return ival;
267     case CV_CAP_PROP_XI_OFFSET_X      : xiGetParamInt( hmv, XI_PRM_OFFSET_X, &ival); return ival;
268     case CV_CAP_PROP_XI_OFFSET_Y      : xiGetParamInt( hmv, XI_PRM_OFFSET_Y, &ival); return ival;
269     case CV_CAP_PROP_XI_TRG_SOURCE    : xiGetParamInt( hmv, XI_PRM_TRG_SOURCE, &ival); return ival;
270     case CV_CAP_PROP_XI_GPI_SELECTOR  : xiGetParamInt( hmv, XI_PRM_GPI_SELECTOR, &ival); return ival;
271     case CV_CAP_PROP_XI_GPI_MODE      : xiGetParamInt( hmv, XI_PRM_GPI_MODE, &ival); return ival;
272     case CV_CAP_PROP_XI_GPI_LEVEL     : xiGetParamInt( hmv, XI_PRM_GPI_LEVEL, &ival); return ival;
273     case CV_CAP_PROP_XI_GPO_SELECTOR  : xiGetParamInt( hmv, XI_PRM_GPO_SELECTOR, &ival); return ival;
274     case CV_CAP_PROP_XI_GPO_MODE      : xiGetParamInt( hmv, XI_PRM_GPO_MODE, &ival); return ival;
275     case CV_CAP_PROP_XI_LED_SELECTOR  : xiGetParamInt( hmv, XI_PRM_LED_SELECTOR, &ival); return ival;
276     case CV_CAP_PROP_XI_LED_MODE      : xiGetParamInt( hmv, XI_PRM_LED_MODE, &ival); return ival;
277     case CV_CAP_PROP_XI_AUTO_WB       : xiGetParamInt( hmv, XI_PRM_AUTO_WB, &ival); return ival;
278     case CV_CAP_PROP_XI_AEAG          : xiGetParamInt( hmv, XI_PRM_AEAG, &ival); return ival;
279     case CV_CAP_PROP_XI_EXP_PRIORITY  : xiGetParamFloat( hmv, XI_PRM_EXP_PRIORITY, &fval); return fval;
280     case CV_CAP_PROP_XI_AE_MAX_LIMIT  : xiGetParamInt( hmv, XI_PRM_AE_MAX_LIMIT, &ival); return ival;
281     case CV_CAP_PROP_XI_AG_MAX_LIMIT  : xiGetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, &fval); return fval;
282     case CV_CAP_PROP_XI_AEAG_LEVEL    : xiGetParamInt( hmv, XI_PRM_AEAG_LEVEL, &ival); return ival;
283     case CV_CAP_PROP_XI_TIMEOUT       : return timeout;
284 
285     }
286     return 0;
287 }
288 
289 /**********************************************************************************/
290 
setProperty(int property_id,double value)291 bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value )
292 {
293     int ival = (int) value;
294     float fval = (float) value;
295 
296     int mvret = XI_OK;
297 
298     switch(property_id)
299     {
300     // OCV parameters
301     case CV_CAP_PROP_FRAME_WIDTH  : mvret = xiSetParamInt( hmv, XI_PRM_WIDTH, ival); break;
302     case CV_CAP_PROP_FRAME_HEIGHT : mvret = xiSetParamInt( hmv, XI_PRM_HEIGHT, ival); break;
303     case CV_CAP_PROP_FPS          : mvret = xiSetParamFloat( hmv, XI_PRM_FRAMERATE, fval); break;
304     case CV_CAP_PROP_GAIN         : mvret = xiSetParamFloat( hmv, XI_PRM_GAIN, fval); break;
305     case CV_CAP_PROP_EXPOSURE     : mvret = xiSetParamInt( hmv, XI_PRM_EXPOSURE, ival); break;
306     // XIMEA camera properties
307     case CV_CAP_PROP_XI_DOWNSAMPLING  : mvret = xiSetParamInt( hmv, XI_PRM_DOWNSAMPLING, ival); break;
308     case CV_CAP_PROP_XI_DATA_FORMAT   : mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, ival); break;
309     case CV_CAP_PROP_XI_OFFSET_X      : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_X, ival); break;
310     case CV_CAP_PROP_XI_OFFSET_Y      : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_Y, ival); break;
311     case CV_CAP_PROP_XI_TRG_SOURCE    : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, ival); break;
312     case CV_CAP_PROP_XI_GPI_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_GPI_SELECTOR, ival); break;
313     case CV_CAP_PROP_XI_TRG_SOFTWARE  : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOFTWARE, 1); break;
314     case CV_CAP_PROP_XI_GPI_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_GPI_MODE, ival); break;
315     case CV_CAP_PROP_XI_GPI_LEVEL     : mvret = xiSetParamInt( hmv, XI_PRM_GPI_LEVEL, ival); break;
316     case CV_CAP_PROP_XI_GPO_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_GPO_SELECTOR, ival); break;
317     case CV_CAP_PROP_XI_GPO_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_GPO_MODE, ival); break;
318     case CV_CAP_PROP_XI_LED_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_LED_SELECTOR, ival); break;
319     case CV_CAP_PROP_XI_LED_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break;
320     case CV_CAP_PROP_XI_AUTO_WB       : mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, ival); break;
321     case CV_CAP_PROP_XI_MANUAL_WB     : mvret = xiSetParamInt( hmv, XI_PRM_MANUAL_WB, ival); break;
322     case CV_CAP_PROP_XI_AEAG          : mvret = xiSetParamInt( hmv, XI_PRM_AEAG, ival); break;
323     case CV_CAP_PROP_XI_EXP_PRIORITY  : mvret = xiSetParamFloat( hmv, XI_PRM_EXP_PRIORITY, fval); break;
324     case CV_CAP_PROP_XI_AE_MAX_LIMIT  : mvret = xiSetParamInt( hmv, XI_PRM_AE_MAX_LIMIT, ival); break;
325     case CV_CAP_PROP_XI_AG_MAX_LIMIT  : mvret = xiSetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, fval); break;
326     case CV_CAP_PROP_XI_AEAG_LEVEL    : mvret = xiSetParamInt( hmv, XI_PRM_AEAG_LEVEL, ival); break;
327     case CV_CAP_PROP_XI_TIMEOUT       : timeout = ival; break;
328     }
329 
330     if(mvret != XI_OK)
331     {
332         errMsg("Set parameter error", mvret);
333         return false;
334     }
335     else
336         return true;
337 
338 }
339 
340 /**********************************************************************************/
341 
errMsg(const char * msg,int errNum)342 void CvCaptureCAM_XIMEA::errMsg(const char* msg, int errNum)
343 {
344 #if defined WIN32 || defined _WIN32
345     char buf[512]="";
346     sprintf( buf, "%s : %d\n", msg, errNum);
347     OutputDebugString(buf);
348 #else
349     fprintf(stderr, "%s : %d\n", msg, errNum);
350 #endif
351 }
352 
353 /**********************************************************************************/
354 
getBpp()355 int  CvCaptureCAM_XIMEA::getBpp()
356 {
357     switch( image.frm)
358     {
359     case XI_MONO8       :
360     case XI_RAW8        : return 1;
361     case XI_MONO16      :
362     case XI_RAW16       : return 2;
363     case XI_RGB24       :
364     case XI_RGB_PLANAR  : return 3;
365     case XI_RGB32       : return 4;
366     default :
367         return 0;
368     }
369 }
370 
371 /**********************************************************************************/
372