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