1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4 // 5 // By downloading, copying, installing or using the software you agree to this license. 6 // If you do not agree to this license, do not download, install, 7 // copy or use the software. 8 // 9 // 10 // Intel License Agreement 11 // For Open Source Computer Vision Library 12 // 13 // Copyright (C) 2000, Intel Corporation, all rights reserved. 14 // Third party copyrights are property of their respective owners. 15 // 16 // Redistribution and use in source and binary forms, with or without modification, 17 // are permitted provided that the following conditions are met: 18 // 19 // * Redistribution's of source code must retain the above copyright notice, 20 // this list of conditions and the following disclaimer. 21 // 22 // * Redistribution's in binary form must reproduce the above copyright notice, 23 // this list of conditions and the following disclaimer in the documentation 24 // and/or other materials provided with the distribution. 25 // 26 // * The name of Intel Corporation may not be used to endorse or promote products 27 // derived from this software without specific prior written permission. 28 // 29 // This software is provided by the copyright holders and contributors "as is" and 30 // any express or implied warranties, including, but not limited to, the implied 31 // warranties of merchantability and fitness for a particular purpose are disclaimed. 32 // In no event shall the Intel Corporation or contributors be liable for any direct, 33 // indirect, incidental, special, exemplary, or consequential damages 34 // (including, but not limited to, procurement of substitute goods or services; 35 // loss of use, data, or profits; or business interruption) however caused 36 // and on any theory of liability, whether in contract, strict liability, 37 // or tort (including negligence or otherwise) arising in any way out of 38 // the use of this software, even if advised of the possibility of such damage. 39 // 40 // 41 42 // 43 // The code has been contributed by Justin G. Eskesen on 2010 Jan 44 // 45 46 #include "precomp.hpp" 47 48 #ifdef HAVE_PVAPI 49 #if !defined WIN32 && !defined _WIN32 && !defined _LINUX 50 #define _LINUX 51 #endif 52 53 #if defined(_x64) || defined (__x86_64) || defined (_M_X64) 54 #define _x64 1 55 #elif defined(_x86) || defined(__i386) || defined (_M_IX86) 56 #define _x86 1 57 #endif 58 59 #include <PvApi.h> 60 #ifdef WIN32 61 # include <io.h> 62 #else 63 # include <time.h> 64 # include <unistd.h> 65 #endif 66 67 //#include <arpa/inet.h> 68 69 #define MAX_CAMERAS 10 70 71 /********************* Capturing video from camera via PvAPI *********************/ 72 73 class CvCaptureCAM_PvAPI : public CvCapture 74 { 75 public: 76 CvCaptureCAM_PvAPI(); 77 virtual ~CvCaptureCAM_PvAPI() 78 { 79 close(); 80 } 81 82 virtual bool open( int index ); 83 virtual void close(); 84 virtual double getProperty(int) const; 85 virtual bool setProperty(int, double); 86 virtual bool grabFrame(); 87 virtual IplImage* retrieveFrame(int); 88 virtual int getCaptureDomain() 89 { 90 return CV_CAP_PVAPI; 91 } 92 93 protected: 94 #ifndef WIN32 95 virtual void Sleep(unsigned int time); 96 #endif 97 98 void stopCapture(); 99 bool startCapture(); 100 bool resizeCaptureFrame (int frameWidth, int frameHeight); 101 102 typedef struct 103 { 104 unsigned long UID; 105 tPvHandle Handle; 106 tPvFrame Frame; 107 } tCamera; 108 109 IplImage *frame; 110 tCamera Camera; 111 tPvErr Errcode; 112 }; 113 114 115 CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI() 116 { 117 frame = NULL; 118 memset(&this->Camera, 0, sizeof(this->Camera)); 119 } 120 121 #ifndef WIN32 122 void CvCaptureCAM_PvAPI::Sleep(unsigned int time) 123 { 124 struct timespec t,r; 125 126 t.tv_sec = time / 1000; 127 t.tv_nsec = (time % 1000) * 1000000; 128 129 while(nanosleep(&t,&r)==-1) 130 t = r; 131 } 132 #endif 133 134 void CvCaptureCAM_PvAPI::close() 135 { 136 // Stop the acquisition & free the camera 137 stopCapture(); 138 PvCameraClose(Camera.Handle); 139 PvUnInitialize(); 140 } 141 142 // Initialize camera input 143 bool CvCaptureCAM_PvAPI::open( int index ) 144 { 145 tPvCameraInfo cameraList[MAX_CAMERAS]; 146 147 tPvCameraInfo camInfo; 148 tPvIpSettings ipSettings; 149 150 151 if (PvInitialize()) { 152 } 153 //return false; 154 155 Sleep(1000); 156 157 //close(); 158 159 int numCameras=PvCameraList(cameraList, MAX_CAMERAS, NULL); 160 161 if (numCameras <= 0 || index >= numCameras) 162 return false; 163 164 Camera.UID = cameraList[index].UniqueId; 165 166 if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings)) 167 { 168 /* 169 struct in_addr addr; 170 addr.s_addr = ipSettings.CurrentIpAddress; 171 printf("Current address:\t%s\n",inet_ntoa(addr)); 172 addr.s_addr = ipSettings.CurrentIpSubnet; 173 printf("Current subnet:\t\t%s\n",inet_ntoa(addr)); 174 addr.s_addr = ipSettings.CurrentIpGateway; 175 printf("Current gateway:\t%s\n",inet_ntoa(addr)); 176 */ 177 } 178 else 179 { 180 fprintf(stderr,"ERROR: could not retrieve camera IP settings.\n"); 181 return false; 182 } 183 184 185 if (PvCameraOpen(Camera.UID, ePvAccessMaster, &(Camera.Handle))==ePvErrSuccess) 186 { 187 tPvUint32 frameWidth, frameHeight; 188 unsigned long maxSize; 189 190 PvAttrUint32Get(Camera.Handle, "Width", &frameWidth); 191 PvAttrUint32Get(Camera.Handle, "Height", &frameHeight); 192 193 // Determine the maximum packet size supported by the system (ethernet adapter) 194 // and then configure the camera to use this value. If the system's NIC only supports 195 // an MTU of 1500 or lower, this will automatically configure an MTU of 1500. 196 // 8228 is the optimal size described by the API in order to enable jumbo frames 197 198 maxSize = 8228; 199 //PvAttrUint32Get(Camera.Handle,"PacketSize",&maxSize); 200 if (PvCaptureAdjustPacketSize(Camera.Handle,maxSize)!=ePvErrSuccess) 201 return false; 202 203 resizeCaptureFrame(frameWidth, frameHeight); 204 205 return startCapture(); 206 207 } 208 fprintf(stderr,"Error cannot open camera\n"); 209 return false; 210 211 } 212 213 bool CvCaptureCAM_PvAPI::grabFrame() 214 { 215 //if(Camera.Frame.Status != ePvErrUnplugged && Camera.Frame.Status != ePvErrCancelled) 216 return PvCaptureQueueFrame(Camera.Handle, &(Camera.Frame), NULL) == ePvErrSuccess; 217 } 218 219 220 IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int) 221 { 222 if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess) 223 { 224 return frame; 225 } 226 else return NULL; 227 } 228 229 double CvCaptureCAM_PvAPI::getProperty( int property_id ) const 230 { 231 tPvUint32 nTemp; 232 233 switch ( property_id ) 234 { 235 case CV_CAP_PROP_FRAME_WIDTH: 236 PvAttrUint32Get(Camera.Handle, "Width", &nTemp); 237 return (double)nTemp; 238 case CV_CAP_PROP_FRAME_HEIGHT: 239 PvAttrUint32Get(Camera.Handle, "Height", &nTemp); 240 return (double)nTemp; 241 case CV_CAP_PROP_EXPOSURE: 242 PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp); 243 return (double)nTemp; 244 case CV_CAP_PROP_FPS: 245 tPvFloat32 nfTemp; 246 PvAttrFloat32Get(Camera.Handle, "StatFrameRate", &nfTemp); 247 return (double)nfTemp; 248 case CV_CAP_PROP_PVAPI_MULTICASTIP: 249 char mEnable[2]; 250 char mIp[11]; 251 PvAttrEnumGet(Camera.Handle,"MulticastEnable",mEnable,sizeof(mEnable),NULL); 252 if (strcmp(mEnable, "Off") == 0) 253 { 254 return -1; 255 } 256 else 257 { 258 long int ip; 259 int a,b,c,d; 260 PvAttrStringGet(Camera.Handle, "MulticastIPAddress",mIp,sizeof(mIp),NULL); 261 sscanf(mIp, "%d.%d.%d.%d", &a, &b, &c, &d); ip = ((a*256 + b)*256 + c)*256 + d; 262 return (double)ip; 263 } 264 case CV_CAP_PROP_GAIN: 265 PvAttrUint32Get(Camera.Handle, "GainValue", &nTemp); 266 return (double)nTemp; 267 case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE: 268 char triggerMode[256]; 269 PvAttrEnumGet(Camera.Handle, "FrameStartTriggerMode", triggerMode, 256, NULL); 270 if (strcmp(triggerMode, "Freerun")==0) 271 return 0.0; 272 else if (strcmp(triggerMode, "SyncIn1")==0) 273 return 1.0; 274 else if (strcmp(triggerMode, "SyncIn2")==0) 275 return 2.0; 276 else if (strcmp(triggerMode, "FixedRate")==0) 277 return 3.0; 278 else if (strcmp(triggerMode, "Software")==0) 279 return 4.0; 280 else 281 return -1.0; 282 case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL: 283 PvAttrUint32Get(Camera.Handle, "DecimationHorizontal", &nTemp); 284 return (double)nTemp; 285 case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL: 286 PvAttrUint32Get(Camera.Handle, "DecimationVertical", &nTemp); 287 return (double)nTemp; 288 case CV_CAP_PROP_PVAPI_BINNINGX: 289 PvAttrUint32Get(Camera.Handle,"BinningX",&nTemp); 290 return (double)nTemp; 291 case CV_CAP_PROP_PVAPI_BINNINGY: 292 PvAttrUint32Get(Camera.Handle,"BinningY",&nTemp); 293 return (double)nTemp; 294 case CV_CAP_PROP_PVAPI_PIXELFORMAT: 295 char pixelFormat[256]; 296 PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL); 297 if (strcmp(pixelFormat, "Mono8")==0) 298 return 1.0; 299 else if (strcmp(pixelFormat, "Mono16")==0) 300 return 2.0; 301 else if (strcmp(pixelFormat, "Bayer8")==0) 302 return 3.0; 303 else if (strcmp(pixelFormat, "Bayer16")==0) 304 return 4.0; 305 else if (strcmp(pixelFormat, "Rgb24")==0) 306 return 5.0; 307 else if (strcmp(pixelFormat, "Bgr24")==0) 308 return 6.0; 309 else if (strcmp(pixelFormat, "Rgba32")==0) 310 return 7.0; 311 else if (strcmp(pixelFormat, "Bgra32")==0) 312 return 8.0; 313 } 314 return -1.0; 315 } 316 317 bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value ) 318 { 319 tPvErr error; 320 321 switch ( property_id ) 322 { 323 case CV_CAP_PROP_FRAME_WIDTH: 324 { 325 tPvUint32 currHeight; 326 327 PvAttrUint32Get(Camera.Handle, "Height", &currHeight); 328 329 stopCapture(); 330 // Reallocate Frames 331 if (!resizeCaptureFrame(value, currHeight)) 332 { 333 startCapture(); 334 return false; 335 } 336 337 startCapture(); 338 339 break; 340 } 341 case CV_CAP_PROP_FRAME_HEIGHT: 342 { 343 tPvUint32 currWidth; 344 345 PvAttrUint32Get(Camera.Handle, "Width", &currWidth); 346 347 stopCapture(); 348 349 // Reallocate Frames 350 if (!resizeCaptureFrame(currWidth, value)) 351 { 352 startCapture(); 353 return false; 354 } 355 356 startCapture(); 357 358 break; 359 } 360 case CV_CAP_PROP_EXPOSURE: 361 if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess)) 362 break; 363 else 364 return false; 365 case CV_CAP_PROP_PVAPI_MULTICASTIP: 366 if (value==-1) 367 { 368 if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "Off")==ePvErrSuccess)) 369 break; 370 else 371 return false; 372 } 373 else 374 { 375 cv::String ip=cv::format("%d.%d.%d.%d", ((unsigned int)value>>24)&255, ((unsigned int)value>>16)&255, ((unsigned int)value>>8)&255, (unsigned int)value&255); 376 if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "On")==ePvErrSuccess) && 377 (PvAttrStringSet(Camera.Handle, "MulticastIPAddress", ip.c_str())==ePvErrSuccess)) 378 break; 379 else 380 return false; 381 } 382 case CV_CAP_PROP_GAIN: 383 if (PvAttrUint32Set(Camera.Handle,"GainValue",(tPvUint32)value)!=ePvErrSuccess) 384 { 385 return false; 386 } 387 break; 388 case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE: 389 if (value==0) 390 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun"); 391 else if (value==1) 392 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "SyncIn1"); 393 else if (value==2) 394 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "SyncIn2"); 395 else if (value==3) 396 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "FixedRate"); 397 else if (value==4) 398 error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Software"); 399 else 400 error = ePvErrOutOfRange; 401 if(error==ePvErrSuccess) 402 break; 403 else 404 return false; 405 case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL: 406 if (value >= 1 && value <= 8) 407 error = PvAttrUint32Set(Camera.Handle, "DecimationHorizontal", value); 408 else 409 error = ePvErrOutOfRange; 410 if(error==ePvErrSuccess) 411 break; 412 else 413 return false; 414 case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL: 415 if (value >= 1 && value <= 8) 416 error = PvAttrUint32Set(Camera.Handle, "DecimationVertical", value); 417 else 418 error = ePvErrOutOfRange; 419 if(error==ePvErrSuccess) 420 break; 421 else 422 return false; 423 case CV_CAP_PROP_PVAPI_BINNINGX: 424 error = PvAttrUint32Set(Camera.Handle, "BinningX", value); 425 if(error==ePvErrSuccess) 426 break; 427 else 428 return false; 429 case CV_CAP_PROP_PVAPI_BINNINGY: 430 error = PvAttrUint32Set(Camera.Handle, "BinningY", value); 431 if(error==ePvErrSuccess) 432 break; 433 else 434 return false; 435 case CV_CAP_PROP_PVAPI_PIXELFORMAT: 436 { 437 cv::String pixelFormat; 438 439 if (value==1) 440 pixelFormat = "Mono8"; 441 else if (value==2) 442 pixelFormat = "Mono16"; 443 else if (value==3) 444 pixelFormat = "Bayer8"; 445 else if (value==4) 446 pixelFormat = "Bayer16"; 447 else if (value==5) 448 pixelFormat = "Rgb24"; 449 else if (value==6) 450 pixelFormat = "Bgr24"; 451 else if (value==7) 452 pixelFormat = "Rgba32"; 453 else if (value==8) 454 pixelFormat = "Bgra32"; 455 else 456 return false; 457 458 if ((PvAttrEnumSet(Camera.Handle,"PixelFormat", pixelFormat.c_str())==ePvErrSuccess)) 459 { 460 tPvUint32 currWidth; 461 tPvUint32 currHeight; 462 463 PvAttrUint32Get(Camera.Handle, "Width", &currWidth); 464 PvAttrUint32Get(Camera.Handle, "Height", &currHeight); 465 466 stopCapture(); 467 // Reallocate Frames 468 if (!resizeCaptureFrame(currWidth, currHeight)) 469 { 470 startCapture(); 471 return false; 472 } 473 474 startCapture(); 475 return true; 476 } 477 else 478 return false; 479 } 480 default: 481 return false; 482 } 483 return true; 484 } 485 486 void CvCaptureCAM_PvAPI::stopCapture() 487 { 488 PvCommandRun(Camera.Handle, "AcquisitionStop"); 489 PvCaptureEnd(Camera.Handle); 490 } 491 492 bool CvCaptureCAM_PvAPI::startCapture() 493 { 494 // Start the camera 495 PvCaptureStart(Camera.Handle); 496 497 // Set the camera to capture continuously 498 if(PvAttrEnumSet(Camera.Handle, "AcquisitionMode", "Continuous")!= ePvErrSuccess) 499 { 500 fprintf(stderr,"Could not set PvAPI Acquisition Mode\n"); 501 return false; 502 } 503 504 if(PvCommandRun(Camera.Handle, "AcquisitionStart")!= ePvErrSuccess) 505 { 506 fprintf(stderr,"Could not start PvAPI acquisition\n"); 507 return false; 508 } 509 510 if(PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun")!= ePvErrSuccess) 511 { 512 fprintf(stderr,"Error setting PvAPI trigger to \"Freerun\""); 513 return false; 514 } 515 516 return true; 517 } 518 519 bool CvCaptureCAM_PvAPI::resizeCaptureFrame (int frameWidth, int frameHeight) 520 { 521 char pixelFormat[256]; 522 tPvUint32 frameSize; 523 tPvUint32 sensorHeight; 524 tPvUint32 sensorWidth; 525 526 if (frame) 527 { 528 cvReleaseImage(&frame); 529 frame = NULL; 530 } 531 532 if (PvAttrUint32Get(Camera.Handle, "SensorWidth", &sensorWidth) != ePvErrSuccess) 533 { 534 return false; 535 } 536 537 if (PvAttrUint32Get(Camera.Handle, "SensorHeight", &sensorHeight) != ePvErrSuccess) 538 { 539 return false; 540 } 541 542 // Cap out of bounds widths to the max supported by the sensor 543 if ((frameWidth < 0) || ((tPvUint32)frameWidth > sensorWidth)) 544 { 545 frameWidth = sensorWidth; 546 } 547 548 if ((frameHeight < 0) || ((tPvUint32)frameHeight > sensorHeight)) 549 { 550 frameHeight = sensorHeight; 551 } 552 553 554 if (PvAttrUint32Set(Camera.Handle, "Height", frameHeight) != ePvErrSuccess) 555 { 556 return false; 557 } 558 559 if (PvAttrUint32Set(Camera.Handle, "Width", frameWidth) != ePvErrSuccess) 560 { 561 return false; 562 } 563 564 PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL); 565 PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize); 566 567 568 if ( (strcmp(pixelFormat, "Mono8")==0) || (strcmp(pixelFormat, "Bayer8")==0) ) 569 { 570 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 1); 571 frame->widthStep = (int)frameWidth; 572 Camera.Frame.ImageBufferSize = frameSize; 573 Camera.Frame.ImageBuffer = frame->imageData; 574 } 575 else if ( (strcmp(pixelFormat, "Mono16")==0) || (strcmp(pixelFormat, "Bayer16")==0) ) 576 { 577 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 1); 578 frame->widthStep = (int)frameWidth*2; 579 Camera.Frame.ImageBufferSize = frameSize; 580 Camera.Frame.ImageBuffer = frame->imageData; 581 } 582 else if ( (strcmp(pixelFormat, "Rgb24")==0) || (strcmp(pixelFormat, "Bgr24")==0) ) 583 { 584 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3); 585 frame->widthStep = (int)frameWidth*3; 586 Camera.Frame.ImageBufferSize = frameSize; 587 Camera.Frame.ImageBuffer = frame->imageData; 588 } 589 else if ( (strcmp(pixelFormat, "Rgba32")==0) || (strcmp(pixelFormat, "Bgra32")==0) ) 590 { 591 frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 4); 592 frame->widthStep = (int)frameWidth*4; 593 Camera.Frame.ImageBufferSize = frameSize; 594 Camera.Frame.ImageBuffer = frame->imageData; 595 } 596 else 597 return false; 598 599 return true; 600 } 601 602 CvCapture* cvCreateCameraCapture_PvAPI( int index ) 603 { 604 CvCaptureCAM_PvAPI* capture = new CvCaptureCAM_PvAPI; 605 606 if ( capture->open( index )) 607 return capture; 608 609 delete capture; 610 return NULL; 611 } 612 #endif 613