Home | History | Annotate | Download | only in src
      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