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