cap_ximea.cpp

Marian Zajko, 2015-03-10 10:15 am

Download (12.8 kB)

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