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