Merge pull request #1263 from abidrahmank:pyCLAHE_24
[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     frame = NULL;
56     timeout = 0;
57     memset(&image, 0, sizeof(XI_IMG));
58 }
59
60
61 /**********************************************************************************/
62 // Initialize camera input
63 bool CvCaptureCAM_XIMEA::open( int wIndex )
64 {
65 #define HandleXiResult(res) if (res!=XI_OK)  goto error;
66
67     int mvret = XI_OK;
68
69     if(numDevices == 0)
70         return false;
71
72     if((mvret = xiOpenDevice( wIndex, &hmv)) != XI_OK)
73     {
74         errMsg("Open XI_DEVICE failed", mvret);
75         return false;
76     }
77
78     // always use auto exposure/gain
79     mvret = xiSetParamInt( hmv, XI_PRM_AEAG, 1);
80     HandleXiResult(mvret);
81
82     int width = 0;
83     mvret = xiGetParamInt( hmv, XI_PRM_WIDTH, &width);
84     HandleXiResult(mvret);
85
86     int height = 0;
87     mvret = xiGetParamInt( hmv, XI_PRM_HEIGHT, &height);
88     HandleXiResult(mvret);
89
90     int isColor = 0;
91     mvret = xiGetParamInt(hmv, XI_PRM_IMAGE_IS_COLOR, &isColor);
92     HandleXiResult(mvret);
93
94     if(isColor) // for color cameras
95     {
96         // default image format RGB24
97         mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_RGB24);
98         HandleXiResult(mvret);
99
100         // always use auto white ballance for color cameras
101         mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, 1);
102         HandleXiResult(mvret);
103
104         // allocate frame buffer for RGB24 image
105         frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 3);
106     }
107     else // for mono cameras
108     {
109         // default image format MONO8
110         mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, XI_MONO8);
111         HandleXiResult(mvret);
112
113         // allocate frame buffer for MONO8 image
114         frame = cvCreateImage(cvSize( width, height), IPL_DEPTH_8U, 1);
115     }
116
117     //default capture timeout 10s
118     timeout = 10000;
119
120     mvret = xiStartAcquisition(hmv);
121     if(mvret != XI_OK)
122     {
123         errMsg("StartAcquisition XI_DEVICE failed", mvret);
124         goto error;
125     }
126     return true;
127
128 error:
129     errMsg("Open XI_DEVICE failed", mvret);
130     xiCloseDevice(hmv);
131     hmv = NULL;
132     return false;
133 }
134
135 /**********************************************************************************/
136
137 void CvCaptureCAM_XIMEA::close()
138 {
139     if(frame)
140         cvReleaseImage(&frame);
141     
142     if(hmv)
143     {
144         xiStopAcquisition(hmv);
145         xiCloseDevice(hmv);
146     }
147     hmv = NULL;
148 }
149
150 /**********************************************************************************/
151
152 bool CvCaptureCAM_XIMEA::grabFrame()
153 {
154     memset(&image, 0, sizeof(XI_IMG));
155     image.size = sizeof(XI_IMG);
156     int mvret = xiGetImage( hmv, timeout, &image);
157
158     if(mvret == MM40_ACQUISITION_STOPED)
159     {
160         xiStartAcquisition(hmv);
161         mvret = xiGetImage(hmv, timeout, &image);
162     }
163
164     if(mvret != XI_OK)
165     {
166         errMsg("Error during GetImage", mvret);
167         return false;
168     }
169
170     return true;
171 }
172
173 /**********************************************************************************/
174
175 IplImage* CvCaptureCAM_XIMEA::retrieveFrame(int)
176 {
177     // update cvImage after format has changed
178     resetCvImage();
179     
180     // copy pixel data
181     switch( image.frm)
182     {
183     case XI_MONO8       : 
184     case XI_RAW8        : memcpy( frame->imageData, image.bp, image.width*image.height); break;
185     case XI_MONO16      :
186     case XI_RAW16       : memcpy( frame->imageData, image.bp, image.width*image.height*sizeof(WORD)); break;
187     case XI_RGB24       :
188     case XI_RGB_PLANAR  : memcpy( frame->imageData, image.bp, image.width*image.height*3); break;
189     case XI_RGB32       : memcpy( frame->imageData, image.bp, image.width*image.height*4); break;
190     default: break;
191     }
192     return frame;
193 }
194
195 /**********************************************************************************/
196
197 void CvCaptureCAM_XIMEA::resetCvImage()
198 {
199     int width = 0, height = 0, format = 0;
200     xiGetParamInt( hmv, XI_PRM_WIDTH, &width);
201     xiGetParamInt( hmv, XI_PRM_HEIGHT, &height);
202     xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &format);
203
204     if( (int)image.width != width || (int)image.height != height || image.frm != (XI_IMG_FORMAT)format)
205     {
206         if(frame) cvReleaseImage(&frame);
207         frame = NULL;
208
209         switch( image.frm)
210         {
211         case XI_MONO8       :
212         case XI_RAW8        : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 1); break;
213         case XI_MONO16      : 
214         case XI_RAW16       : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_16U, 1); break;
215         case XI_RGB24       : 
216         case XI_RGB_PLANAR  : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 3); break;
217         case XI_RGB32       : frame = cvCreateImage(cvSize( image.width, image.height), IPL_DEPTH_8U, 4); break;
218         default :
219             return;
220         }
221     }   
222     cvZero(frame);
223 }
224 /**********************************************************************************/
225
226 double CvCaptureCAM_XIMEA::getProperty( int property_id )
227 {
228     if(hmv == NULL)
229         return 0;
230
231     int ival = 0;
232     float fval = 0;
233
234     switch( property_id )
235     {
236     // OCV parameters
237     case CV_CAP_PROP_POS_FRAMES   : return (double) image.nframe;
238     case CV_CAP_PROP_FRAME_WIDTH  : xiGetParamInt( hmv, XI_PRM_WIDTH, &ival); return ival;
239     case CV_CAP_PROP_FRAME_HEIGHT : xiGetParamInt( hmv, XI_PRM_HEIGHT, &ival); return ival;
240     case CV_CAP_PROP_FPS          : xiGetParamFloat( hmv, XI_PRM_FRAMERATE, &fval); return fval;
241     case CV_CAP_PROP_GAIN         : xiGetParamFloat( hmv, XI_PRM_GAIN, &fval); return fval;
242     case CV_CAP_PROP_EXPOSURE     : xiGetParamInt( hmv, XI_PRM_EXPOSURE, &ival); return ival;
243
244     // XIMEA camera properties
245     case CV_CAP_PROP_XI_DOWNSAMPLING  : xiGetParamInt( hmv, XI_PRM_DOWNSAMPLING, &ival); return ival;
246     case CV_CAP_PROP_XI_DATA_FORMAT   : xiGetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, &ival); return ival;
247     case CV_CAP_PROP_XI_OFFSET_X      : xiGetParamInt( hmv, XI_PRM_OFFSET_X, &ival); return ival;
248     case CV_CAP_PROP_XI_OFFSET_Y      : xiGetParamInt( hmv, XI_PRM_OFFSET_Y, &ival); return ival;
249     case CV_CAP_PROP_XI_TRG_SOURCE    : xiGetParamInt( hmv, XI_PRM_TRG_SOURCE, &ival); return ival;
250     case CV_CAP_PROP_XI_GPI_SELECTOR  : xiGetParamInt( hmv, XI_PRM_GPI_SELECTOR, &ival); return ival;
251     case CV_CAP_PROP_XI_GPI_MODE      : xiGetParamInt( hmv, XI_PRM_GPI_MODE, &ival); return ival;
252     case CV_CAP_PROP_XI_GPI_LEVEL     : xiGetParamInt( hmv, XI_PRM_GPI_LEVEL, &ival); return ival;
253     case CV_CAP_PROP_XI_GPO_SELECTOR  : xiGetParamInt( hmv, XI_PRM_GPO_SELECTOR, &ival); return ival;
254     case CV_CAP_PROP_XI_GPO_MODE      : xiGetParamInt( hmv, XI_PRM_GPO_MODE, &ival); return ival;
255     case CV_CAP_PROP_XI_LED_SELECTOR  : xiGetParamInt( hmv, XI_PRM_LED_SELECTOR, &ival); return ival;
256     case CV_CAP_PROP_XI_LED_MODE      : xiGetParamInt( hmv, XI_PRM_LED_MODE, &ival); return ival;
257     case CV_CAP_PROP_XI_AUTO_WB       : xiGetParamInt( hmv, XI_PRM_AUTO_WB, &ival); return ival;
258     case CV_CAP_PROP_XI_AEAG          : xiGetParamInt( hmv, XI_PRM_AEAG, &ival); return ival;
259     case CV_CAP_PROP_XI_EXP_PRIORITY  : xiGetParamFloat( hmv, XI_PRM_EXP_PRIORITY, &fval); return fval;
260     case CV_CAP_PROP_XI_AE_MAX_LIMIT  : xiGetParamInt( hmv, XI_PRM_EXP_PRIORITY, &ival); return ival;
261     case CV_CAP_PROP_XI_AG_MAX_LIMIT  : xiGetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, &fval); return fval;
262     case CV_CAP_PROP_XI_AEAG_LEVEL    : xiGetParamInt( hmv, XI_PRM_AEAG_LEVEL, &ival); return ival;
263     case CV_CAP_PROP_XI_TIMEOUT       : return timeout;
264
265     }
266     return 0;
267 }
268
269 /**********************************************************************************/
270
271 bool CvCaptureCAM_XIMEA::setProperty( int property_id, double value )
272 {
273     int ival = (int) value;
274     float fval = (float) value;
275
276     int mvret = XI_OK;
277
278     switch(property_id)
279     {
280     // OCV parameters
281     case CV_CAP_PROP_FRAME_WIDTH  : mvret = xiSetParamInt( hmv, XI_PRM_WIDTH, ival); break;
282     case CV_CAP_PROP_FRAME_HEIGHT : mvret = xiSetParamInt( hmv, XI_PRM_HEIGHT, ival); break;
283     case CV_CAP_PROP_FPS          : mvret = xiSetParamFloat( hmv, XI_PRM_FRAMERATE, fval); break;
284     case CV_CAP_PROP_GAIN         : mvret = xiSetParamFloat( hmv, XI_PRM_GAIN, fval); break;
285     case CV_CAP_PROP_EXPOSURE     : mvret = xiSetParamInt( hmv, XI_PRM_EXPOSURE, ival); break;
286     // XIMEA camera properties
287     case CV_CAP_PROP_XI_DOWNSAMPLING  : mvret = xiSetParamInt( hmv, XI_PRM_DOWNSAMPLING, ival); break;
288     case CV_CAP_PROP_XI_DATA_FORMAT   : mvret = xiSetParamInt( hmv, XI_PRM_IMAGE_DATA_FORMAT, ival); break;
289     case CV_CAP_PROP_XI_OFFSET_X      : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_X, ival); break;
290     case CV_CAP_PROP_XI_OFFSET_Y      : mvret = xiSetParamInt( hmv, XI_PRM_OFFSET_Y, ival); break;
291     case CV_CAP_PROP_XI_TRG_SOURCE    : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, ival); break;
292     case CV_CAP_PROP_XI_GPI_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_GPI_SELECTOR, ival); break;
293     case CV_CAP_PROP_XI_TRG_SOFTWARE  : mvret = xiSetParamInt( hmv, XI_PRM_TRG_SOURCE, 1); break;
294     case CV_CAP_PROP_XI_GPI_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_GPI_MODE, ival); break;
295     case CV_CAP_PROP_XI_GPI_LEVEL     : mvret = xiSetParamInt( hmv, XI_PRM_GPI_LEVEL, ival); break;
296     case CV_CAP_PROP_XI_GPO_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_GPO_SELECTOR, ival); break;
297     case CV_CAP_PROP_XI_GPO_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_GPO_MODE, ival); break;
298     case CV_CAP_PROP_XI_LED_SELECTOR  : mvret = xiSetParamInt( hmv, XI_PRM_LED_SELECTOR, ival); break;
299     case CV_CAP_PROP_XI_LED_MODE      : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break;
300     case CV_CAP_PROP_XI_AUTO_WB       : mvret = xiSetParamInt( hmv, XI_PRM_AUTO_WB, ival); break;
301     case CV_CAP_PROP_XI_MANUAL_WB     : mvret = xiSetParamInt( hmv, XI_PRM_LED_MODE, ival); break;
302     case CV_CAP_PROP_XI_AEAG          : mvret = xiSetParamInt( hmv, XI_PRM_AEAG, ival); break;
303     case CV_CAP_PROP_XI_EXP_PRIORITY  : mvret = xiSetParamFloat( hmv, XI_PRM_EXP_PRIORITY, fval); break;
304     case CV_CAP_PROP_XI_AE_MAX_LIMIT  : mvret = xiSetParamInt( hmv, XI_PRM_EXP_PRIORITY, ival); break;
305     case CV_CAP_PROP_XI_AG_MAX_LIMIT  : mvret = xiSetParamFloat( hmv, XI_PRM_AG_MAX_LIMIT, fval); break;
306     case CV_CAP_PROP_XI_AEAG_LEVEL    : mvret = xiSetParamInt( hmv, XI_PRM_AEAG_LEVEL, ival); break;
307     case CV_CAP_PROP_XI_TIMEOUT       : timeout = ival; break;
308     }
309
310     if(mvret != XI_OK)
311     {
312         errMsg("Set parameter error", mvret);
313         return false;
314     }
315     else
316         return true;
317
318 }
319
320 /**********************************************************************************/
321
322 void CvCaptureCAM_XIMEA::errMsg(const char* msg, int errNum)
323 {
324 #if defined WIN32 || defined _WIN32
325     char buf[512]="";
326     sprintf( buf, "%s : %d\n", msg, errNum);
327     OutputDebugString(buf);
328 #else
329     fprintf(stderr, "%s : %d\n", msg, errNum);
330 #endif
331 }
332
333 /**********************************************************************************/
334
335 int  CvCaptureCAM_XIMEA::getBpp()
336 {
337     switch( image.frm)
338     {
339     case XI_MONO8       :
340     case XI_RAW8        : return 1;
341     case XI_MONO16      : 
342     case XI_RAW16       : return 2;
343     case XI_RGB24       : 
344     case XI_RGB_PLANAR  : return 3;
345     case XI_RGB32       : return 4;
346     default :
347         return 0;
348     }
349 }
350
351 /**********************************************************************************/