cap_pvapi.cpp 11.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
////////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//

//
// The code has been contributed by Justin G. Eskesen on 2010 Jan
//

#include "precomp.hpp"

#ifdef HAVE_PVAPI
#if !defined WIN32 && !defined _WIN32 && !defined _LINUX
#define _LINUX
#endif

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 58 59
#endif

#include <PvApi.h>
60 61 62 63 64 65
#ifdef WIN32
#  include <io.h>
#else
#  include <unistd.h>
#endif

66
#include <string>
67
//#include <arpa/inet.h>
68 69 70 71 72 73 74 75 76

#define MAX_CAMERAS 10

/********************* Capturing video from camera via PvAPI *********************/

class CvCaptureCAM_PvAPI : public CvCapture
{
public:
    CvCaptureCAM_PvAPI();
77
    virtual ~CvCaptureCAM_PvAPI()
78 79 80 81 82 83 84 85 86 87
    {
        close();
    }

    virtual bool open( int index );
    virtual void close();
    virtual double getProperty(int);
    virtual bool setProperty(int, double);
    virtual bool grabFrame();
    virtual IplImage* retrieveFrame(int);
88
    virtual int getCaptureDomain()
89 90 91 92 93
    {
        return CV_CAP_PVAPI;
    }

protected:
94 95 96
#ifndef WIN32
    virtual void Sleep(unsigned int time);
#endif
97

98 99 100 101 102 103
    typedef struct
    {
        unsigned long   UID;
        tPvHandle       Handle;
        tPvFrame        Frame;
    } tCamera;
104

105
    IplImage *frame;
106
    IplImage *grayframe;
107 108
    tCamera  Camera;
    tPvErr   Errcode;
109
    bool monocrome;
110 111 112 113 114
};


CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI()
{
115
    monocrome=false;
116
    memset(&this->Camera, 0, sizeof(this->Camera));
117
}
118 119

#ifndef WIN32
120 121 122
void CvCaptureCAM_PvAPI::Sleep(unsigned int time)
{
    struct timespec t,r;
123

124
    t.tv_sec    = time / 1000;
125 126
    t.tv_nsec   = (time % 1000) * 1000000;

127 128 129
    while(nanosleep(&t,&r)==-1)
        t = r;
}
130 131
#endif

132 133
void CvCaptureCAM_PvAPI::close()
{
134 135 136
    // Stop the acquisition & free the camera
    PvCommandRun(Camera.Handle, "AcquisitionStop");
    PvCaptureEnd(Camera.Handle);
137 138
    PvCameraClose(Camera.Handle);
    PvUnInitialize();
139 140 141 142 143
}

// Initialize camera input
bool CvCaptureCAM_PvAPI::open( int index )
{
144
    tPvCameraInfo cameraList[MAX_CAMERAS];
145

146 147
    tPvCameraInfo  camInfo;
    tPvIpSettings ipSettings;
148

149

150 151
    if (PvInitialize()) {
    }
152 153
    //return false;

154 155
    Sleep(1000);

156
    //close();
157

158 159
    int numCameras=PvCameraList(cameraList, MAX_CAMERAS, NULL);

160 161 162
    if (numCameras <= 0 || index >= numCameras)
        return false;

163
    Camera.UID = cameraList[index].UniqueId;
164 165

    if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings)) {
166 167 168 169 170 171 172 173 174 175 176 177 178 179
        /*
        struct in_addr addr;
        addr.s_addr = ipSettings.CurrentIpAddress;
        printf("Current address:\t%s\n",inet_ntoa(addr));
        addr.s_addr = ipSettings.CurrentIpSubnet;
        printf("Current subnet:\t\t%s\n",inet_ntoa(addr));
        addr.s_addr = ipSettings.CurrentIpGateway;
        printf("Current gateway:\t%s\n",inet_ntoa(addr));
        */
    }
    else {
        fprintf(stderr,"ERROR: could not retrieve camera IP settings.\n");
        return false;
    }
180 181


182 183
    if (PvCameraOpen(Camera.UID, ePvAccessMaster, &(Camera.Handle))==ePvErrSuccess)
    {
184 185

        //Set Pixel Format to BRG24 to follow conventions
186
        /*Errcode = PvAttrEnumSet(Camera.Handle, "PixelFormat", "Bgr24");
187 188 189 190 191
        if (Errcode != ePvErrSuccess)
        {
            fprintf(stderr, "PvAPI: couldn't set PixelFormat to Bgr24\n");
            return NULL;
        }
192
        */
193 194
        tPvUint32 frameWidth, frameHeight, frameSize;
        unsigned long maxSize;
195
        char pixelFormat[256];
196 197 198
        PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize);
        PvAttrUint32Get(Camera.Handle, "Width", &frameWidth);
        PvAttrUint32Get(Camera.Handle, "Height", &frameHeight);
Stefano Fabri's avatar
Stefano Fabri committed
199
        PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
200
        maxSize = 8228;
201
        //PvAttrUint32Get(Camera.Handle,"PacketSize",&maxSize);
202
        if (PvCaptureAdjustPacketSize(Camera.Handle,maxSize)!=ePvErrSuccess)
203
            return false;
204
        if (strcmp(pixelFormat, "Mono8")==0) {
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
                grayframe = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 1);
                grayframe->widthStep = (int)frameWidth;
                frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3);
                frame->widthStep = (int)frameWidth*3;
                Camera.Frame.ImageBufferSize = frameSize;
                Camera.Frame.ImageBuffer = grayframe->imageData;
        }
        else if (strcmp(pixelFormat, "Mono16")==0) {
                grayframe = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 1);
                grayframe->widthStep = (int)frameWidth;
                frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 3);
                frame->widthStep = (int)frameWidth*3;
                Camera.Frame.ImageBufferSize = frameSize;
                Camera.Frame.ImageBuffer = grayframe->imageData;
        }
        else if (strcmp(pixelFormat, "Bgr24")==0) {
                frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 3);
                frame->widthStep = (int)frameWidth*3;
                Camera.Frame.ImageBufferSize = frameSize;
                Camera.Frame.ImageBuffer = frame->imageData;
        }
        else
                return false;
228 229 230 231 232 233 234 235 236
        // Start the camera
        PvCaptureStart(Camera.Handle);

        // Set the camera to capture continuously
        if(PvAttrEnumSet(Camera.Handle, "AcquisitionMode", "Continuous")!= ePvErrSuccess)
        {
            fprintf(stderr,"Could not set Prosilica Acquisition Mode\n");
            return false;
        }
237

238 239 240 241 242
        if(PvCommandRun(Camera.Handle, "AcquisitionStart")!= ePvErrSuccess)
        {
            fprintf(stderr,"Could not start Prosilica acquisition\n");
            return false;
        }
243

244 245 246 247 248
        if(PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun")!= ePvErrSuccess)
        {
            fprintf(stderr,"Error setting Prosilica trigger to \"Freerun\"");
            return false;
        }
249

250 251
        return true;
    }
252
    fprintf(stderr,"Error cannot open camera\n");
253 254 255 256 257 258
    return false;

}

bool CvCaptureCAM_PvAPI::grabFrame()
{
259 260
    //if(Camera.Frame.Status != ePvErrUnplugged && Camera.Frame.Status != ePvErrCancelled)
    return PvCaptureQueueFrame(Camera.Handle, &(Camera.Frame), NULL) == ePvErrSuccess;
261 262 263 264 265 266
}


IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int)
{

267
    if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess) {
268 269 270 271 272 273 274
        if (!monocrome) {
            cvMerge(grayframe,grayframe,grayframe,NULL,frame);
            return frame;
        }
        return grayframe;
    }
    else return NULL;
275 276 277 278 279 280 281 282 283 284 285 286 287 288
}

double CvCaptureCAM_PvAPI::getProperty( int property_id )
{
    tPvUint32 nTemp;

    switch ( property_id )
    {
    case CV_CAP_PROP_FRAME_WIDTH:
        PvAttrUint32Get(Camera.Handle, "Width", &nTemp);
        return (double)nTemp;
    case CV_CAP_PROP_FRAME_HEIGHT:
        PvAttrUint32Get(Camera.Handle, "Height", &nTemp);
        return (double)nTemp;
289
    case CV_CAP_PROP_EXPOSURE:
290 291
    PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp);
    return (double)nTemp;
292
    case CV_CAP_PROP_FPS:
293
    tPvFloat32 nfTemp;
294 295
        PvAttrFloat32Get(Camera.Handle, "StatFrameRate", &nfTemp);
        return (double)nfTemp;
296
    case CV_CAP_PROP_PVAPI_MULTICASTIP:
297 298 299 300 301 302 303 304 305 306 307 308 309
    char mEnable[2];
    char mIp[11];
    PvAttrEnumGet(Camera.Handle,"MulticastEnable",mEnable,sizeof(mEnable),NULL);
    if (strcmp(mEnable, "Off") == 0) {
        return -1;
    }
    else {
        long int ip;
        int a,b,c,d;
        PvAttrStringGet(Camera.Handle, "MulticastIPAddress",mIp,sizeof(mIp),NULL);
        sscanf(mIp, "%d.%d.%d.%d", &a, &b, &c, &d); ip = ((a*256 + b)*256 + c)*256 + d;
        return (double)ip;
    }
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
    }
    return -1.0;
}

bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
{
    switch ( property_id )
    {
    /*  TODO: Camera works, but IplImage must be modified for the new size
    case CV_CAP_PROP_FRAME_WIDTH:
        PvAttrUint32Set(Camera.Handle, "Width", (tPvUint32)value);
        break;
    case CV_CAP_PROP_FRAME_HEIGHT:
        PvAttrUint32Set(Camera.Handle, "Heigth", (tPvUint32)value);
        break;
    */
326
    case CV_CAP_PROP_MONOCROME:
327
        if (value==1) {
328 329 330 331 332 333 334 335 336 337 338
            char pixelFormat[256];
            PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
            if ((strcmp(pixelFormat, "Mono8")==0) || strcmp(pixelFormat, "Mono16")==0) {
                monocrome=true;
            }
            else
                return false;
        }
        else
            monocrome=false;
        break;
339
    case CV_CAP_PROP_EXPOSURE:
340 341 342 343
        if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess))
        break;
        else
        return false;
344
    case CV_CAP_PROP_PVAPI_MULTICASTIP:
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359

            if (value==-1) {
        if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "Off")==ePvErrSuccess))
            break;
        else
            return false;
        }
        else {
        std::string ip=cv::format("%d.%d.%d.%d", ((int)value>>24)&255, ((int)value>>16)&255, ((int)value>>8)&255, (int)value&255);
        if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "On")==ePvErrSuccess) &&
        (PvAttrStringSet(Camera.Handle, "MulticastIPAddress", ip.c_str())==ePvErrSuccess))
            break;
        else
            return false;
        }
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
    default:
        return false;
    }
    return true;
}


CvCapture* cvCreateCameraCapture_PvAPI( int index )
{
    CvCaptureCAM_PvAPI* capture = new CvCaptureCAM_PvAPI;

    if ( capture->open( index ))
        return capture;

    delete capture;
    return NULL;
}
#endif