Home | History | Annotate | Download | only in src
      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) const;
     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 (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
     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 
    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 
    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 
    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 
    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 
    246 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 
    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 
    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 
    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