mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
613 lines
18 KiB
613 lines
18 KiB
//////////////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// 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" |
|
#include "cap_interface.hpp" |
|
|
|
#ifdef HAVE_PVAPI |
|
#if !defined _WIN32 && !defined _LINUX |
|
#define _LINUX |
|
#endif |
|
|
|
#if defined(_x64) || defined (__x86_64) || defined (_M_X64) |
|
#define _x64 1 |
|
#elif defined(_x86) || defined(__i386) || defined (_M_IX86) |
|
#define _x86 1 |
|
#endif |
|
|
|
#include <PvApi.h> |
|
#ifdef _WIN32 |
|
# include <io.h> |
|
#else |
|
# include <time.h> |
|
# include <unistd.h> |
|
#endif |
|
|
|
//#include <arpa/inet.h> |
|
|
|
#define MAX_CAMERAS 10 |
|
|
|
/********************* Capturing video from camera via PvAPI *********************/ |
|
|
|
class CvCaptureCAM_PvAPI : public CvCapture |
|
{ |
|
public: |
|
CvCaptureCAM_PvAPI(); |
|
virtual ~CvCaptureCAM_PvAPI() |
|
{ |
|
close(); |
|
} |
|
|
|
virtual bool open( int index ); |
|
virtual void close(); |
|
virtual double getProperty(int) const CV_OVERRIDE; |
|
virtual bool setProperty(int, double) CV_OVERRIDE; |
|
virtual bool grabFrame() CV_OVERRIDE; |
|
virtual IplImage* retrieveFrame(int) CV_OVERRIDE; |
|
virtual int getCaptureDomain() CV_OVERRIDE |
|
{ |
|
return CV_CAP_PVAPI; |
|
} |
|
|
|
protected: |
|
#ifndef _WIN32 |
|
virtual void Sleep(unsigned int time); |
|
#endif |
|
|
|
void stopCapture(); |
|
bool startCapture(); |
|
bool resizeCaptureFrame (int frameWidth, int frameHeight); |
|
|
|
typedef struct |
|
{ |
|
unsigned long UID; |
|
tPvHandle Handle; |
|
tPvFrame Frame; |
|
} tCamera; |
|
|
|
IplImage *frame; |
|
tCamera Camera; |
|
tPvErr Errcode; |
|
}; |
|
|
|
|
|
CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI() |
|
{ |
|
frame = NULL; |
|
memset(&this->Camera, 0, sizeof(this->Camera)); |
|
} |
|
|
|
#ifndef _WIN32 |
|
void CvCaptureCAM_PvAPI::Sleep(unsigned int time) |
|
{ |
|
struct timespec t,r; |
|
|
|
t.tv_sec = time / 1000; |
|
t.tv_nsec = (time % 1000) * 1000000; |
|
|
|
while(nanosleep(&t,&r)==-1) |
|
t = r; |
|
} |
|
#endif |
|
|
|
void CvCaptureCAM_PvAPI::close() |
|
{ |
|
// Stop the acquisition & free the camera |
|
stopCapture(); |
|
PvCameraClose(Camera.Handle); |
|
PvUnInitialize(); |
|
} |
|
|
|
// Initialize camera input |
|
bool CvCaptureCAM_PvAPI::open( int index ) |
|
{ |
|
tPvCameraInfo cameraList[MAX_CAMERAS]; |
|
|
|
tPvCameraInfo camInfo; |
|
tPvIpSettings ipSettings; |
|
|
|
|
|
if (PvInitialize()) { |
|
} |
|
//return false; |
|
|
|
Sleep(1000); |
|
|
|
//close(); |
|
|
|
int numCameras=PvCameraList(cameraList, MAX_CAMERAS, NULL); |
|
|
|
if (numCameras <= 0 || index >= numCameras) |
|
return false; |
|
|
|
Camera.UID = cameraList[index].UniqueId; |
|
|
|
if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings)) |
|
{ |
|
/* |
|
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; |
|
} |
|
|
|
|
|
if (PvCameraOpen(Camera.UID, ePvAccessMaster, &(Camera.Handle))==ePvErrSuccess) |
|
{ |
|
tPvUint32 frameWidth, frameHeight; |
|
unsigned long maxSize; |
|
|
|
PvAttrUint32Get(Camera.Handle, "Width", &frameWidth); |
|
PvAttrUint32Get(Camera.Handle, "Height", &frameHeight); |
|
|
|
// Determine the maximum packet size supported by the system (ethernet adapter) |
|
// and then configure the camera to use this value. If the system's NIC only supports |
|
// an MTU of 1500 or lower, this will automatically configure an MTU of 1500. |
|
// 8228 is the optimal size described by the API in order to enable jumbo frames |
|
|
|
maxSize = 8228; |
|
//PvAttrUint32Get(Camera.Handle,"PacketSize",&maxSize); |
|
if (PvCaptureAdjustPacketSize(Camera.Handle,maxSize)!=ePvErrSuccess) |
|
return false; |
|
|
|
resizeCaptureFrame(frameWidth, frameHeight); |
|
|
|
return startCapture(); |
|
|
|
} |
|
fprintf(stderr,"Error cannot open camera\n"); |
|
return false; |
|
|
|
} |
|
|
|
bool CvCaptureCAM_PvAPI::grabFrame() |
|
{ |
|
//if(Camera.Frame.Status != ePvErrUnplugged && Camera.Frame.Status != ePvErrCancelled) |
|
return PvCaptureQueueFrame(Camera.Handle, &(Camera.Frame), NULL) == ePvErrSuccess; |
|
} |
|
|
|
|
|
IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int) |
|
{ |
|
if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess) |
|
{ |
|
return frame; |
|
} |
|
else return NULL; |
|
} |
|
|
|
double CvCaptureCAM_PvAPI::getProperty( int property_id ) const |
|
{ |
|
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; |
|
case CV_CAP_PROP_EXPOSURE: |
|
PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp); |
|
return (double)nTemp; |
|
case CV_CAP_PROP_FPS: |
|
tPvFloat32 nfTemp; |
|
PvAttrFloat32Get(Camera.Handle, "StatFrameRate", &nfTemp); |
|
return (double)nfTemp; |
|
case CV_CAP_PROP_PVAPI_MULTICASTIP: |
|
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; |
|
} |
|
case CV_CAP_PROP_GAIN: |
|
PvAttrUint32Get(Camera.Handle, "GainValue", &nTemp); |
|
return (double)nTemp; |
|
case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE: |
|
char triggerMode[256]; |
|
PvAttrEnumGet(Camera.Handle, "FrameStartTriggerMode", triggerMode, 256, NULL); |
|
if (strcmp(triggerMode, "Freerun")==0) |
|
return 0.0; |
|
else if (strcmp(triggerMode, "SyncIn1")==0) |
|
return 1.0; |
|
else if (strcmp(triggerMode, "SyncIn2")==0) |
|
return 2.0; |
|
else if (strcmp(triggerMode, "FixedRate")==0) |
|
return 3.0; |
|
else if (strcmp(triggerMode, "Software")==0) |
|
return 4.0; |
|
else |
|
return -1.0; |
|
case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL: |
|
PvAttrUint32Get(Camera.Handle, "DecimationHorizontal", &nTemp); |
|
return (double)nTemp; |
|
case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL: |
|
PvAttrUint32Get(Camera.Handle, "DecimationVertical", &nTemp); |
|
return (double)nTemp; |
|
case CV_CAP_PROP_PVAPI_BINNINGX: |
|
PvAttrUint32Get(Camera.Handle,"BinningX",&nTemp); |
|
return (double)nTemp; |
|
case CV_CAP_PROP_PVAPI_BINNINGY: |
|
PvAttrUint32Get(Camera.Handle,"BinningY",&nTemp); |
|
return (double)nTemp; |
|
case CV_CAP_PROP_PVAPI_PIXELFORMAT: |
|
char pixelFormat[256]; |
|
PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL); |
|
if (strcmp(pixelFormat, "Mono8")==0) |
|
return 1.0; |
|
else if (strcmp(pixelFormat, "Mono16")==0) |
|
return 2.0; |
|
else if (strcmp(pixelFormat, "Bayer8")==0) |
|
return 3.0; |
|
else if (strcmp(pixelFormat, "Bayer16")==0) |
|
return 4.0; |
|
else if (strcmp(pixelFormat, "Rgb24")==0) |
|
return 5.0; |
|
else if (strcmp(pixelFormat, "Bgr24")==0) |
|
return 6.0; |
|
else if (strcmp(pixelFormat, "Rgba32")==0) |
|
return 7.0; |
|
else if (strcmp(pixelFormat, "Bgra32")==0) |
|
return 8.0; |
|
} |
|
return -1.0; |
|
} |
|
|
|
bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value ) |
|
{ |
|
tPvErr error; |
|
|
|
switch ( property_id ) |
|
{ |
|
case CV_CAP_PROP_FRAME_WIDTH: |
|
{ |
|
tPvUint32 currHeight; |
|
|
|
PvAttrUint32Get(Camera.Handle, "Height", &currHeight); |
|
|
|
stopCapture(); |
|
// Reallocate Frames |
|
if (!resizeCaptureFrame(value, currHeight)) |
|
{ |
|
startCapture(); |
|
return false; |
|
} |
|
|
|
startCapture(); |
|
|
|
break; |
|
} |
|
case CV_CAP_PROP_FRAME_HEIGHT: |
|
{ |
|
tPvUint32 currWidth; |
|
|
|
PvAttrUint32Get(Camera.Handle, "Width", &currWidth); |
|
|
|
stopCapture(); |
|
|
|
// Reallocate Frames |
|
if (!resizeCaptureFrame(currWidth, value)) |
|
{ |
|
startCapture(); |
|
return false; |
|
} |
|
|
|
startCapture(); |
|
|
|
break; |
|
} |
|
case CV_CAP_PROP_EXPOSURE: |
|
if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess)) |
|
break; |
|
else |
|
return false; |
|
case CV_CAP_PROP_PVAPI_MULTICASTIP: |
|
if (value==-1) |
|
{ |
|
if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "Off")==ePvErrSuccess)) |
|
break; |
|
else |
|
return false; |
|
} |
|
else |
|
{ |
|
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); |
|
if ((PvAttrEnumSet(Camera.Handle,"MulticastEnable", "On")==ePvErrSuccess) && |
|
(PvAttrStringSet(Camera.Handle, "MulticastIPAddress", ip.c_str())==ePvErrSuccess)) |
|
break; |
|
else |
|
return false; |
|
} |
|
case CV_CAP_PROP_GAIN: |
|
if (PvAttrUint32Set(Camera.Handle,"GainValue",(tPvUint32)value)!=ePvErrSuccess) |
|
{ |
|
return false; |
|
} |
|
break; |
|
case CV_CAP_PROP_PVAPI_FRAMESTARTTRIGGERMODE: |
|
if (value==0) |
|
error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun"); |
|
else if (value==1) |
|
error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "SyncIn1"); |
|
else if (value==2) |
|
error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "SyncIn2"); |
|
else if (value==3) |
|
error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "FixedRate"); |
|
else if (value==4) |
|
error = PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Software"); |
|
else |
|
error = ePvErrOutOfRange; |
|
if(error==ePvErrSuccess) |
|
break; |
|
else |
|
return false; |
|
case CV_CAP_PROP_PVAPI_DECIMATIONHORIZONTAL: |
|
if (value >= 1 && value <= 8) |
|
error = PvAttrUint32Set(Camera.Handle, "DecimationHorizontal", value); |
|
else |
|
error = ePvErrOutOfRange; |
|
if(error==ePvErrSuccess) |
|
break; |
|
else |
|
return false; |
|
case CV_CAP_PROP_PVAPI_DECIMATIONVERTICAL: |
|
if (value >= 1 && value <= 8) |
|
error = PvAttrUint32Set(Camera.Handle, "DecimationVertical", value); |
|
else |
|
error = ePvErrOutOfRange; |
|
if(error==ePvErrSuccess) |
|
break; |
|
else |
|
return false; |
|
case CV_CAP_PROP_PVAPI_BINNINGX: |
|
error = PvAttrUint32Set(Camera.Handle, "BinningX", value); |
|
if(error==ePvErrSuccess) |
|
break; |
|
else |
|
return false; |
|
case CV_CAP_PROP_PVAPI_BINNINGY: |
|
error = PvAttrUint32Set(Camera.Handle, "BinningY", value); |
|
if(error==ePvErrSuccess) |
|
break; |
|
else |
|
return false; |
|
case CV_CAP_PROP_PVAPI_PIXELFORMAT: |
|
{ |
|
cv::String pixelFormat; |
|
|
|
if (value==1) |
|
pixelFormat = "Mono8"; |
|
else if (value==2) |
|
pixelFormat = "Mono16"; |
|
else if (value==3) |
|
pixelFormat = "Bayer8"; |
|
else if (value==4) |
|
pixelFormat = "Bayer16"; |
|
else if (value==5) |
|
pixelFormat = "Rgb24"; |
|
else if (value==6) |
|
pixelFormat = "Bgr24"; |
|
else if (value==7) |
|
pixelFormat = "Rgba32"; |
|
else if (value==8) |
|
pixelFormat = "Bgra32"; |
|
else |
|
return false; |
|
|
|
if ((PvAttrEnumSet(Camera.Handle,"PixelFormat", pixelFormat.c_str())==ePvErrSuccess)) |
|
{ |
|
tPvUint32 currWidth; |
|
tPvUint32 currHeight; |
|
|
|
PvAttrUint32Get(Camera.Handle, "Width", &currWidth); |
|
PvAttrUint32Get(Camera.Handle, "Height", &currHeight); |
|
|
|
stopCapture(); |
|
// Reallocate Frames |
|
if (!resizeCaptureFrame(currWidth, currHeight)) |
|
{ |
|
startCapture(); |
|
return false; |
|
} |
|
|
|
startCapture(); |
|
return true; |
|
} |
|
else |
|
return false; |
|
} |
|
default: |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
void CvCaptureCAM_PvAPI::stopCapture() |
|
{ |
|
PvCommandRun(Camera.Handle, "AcquisitionStop"); |
|
PvCaptureEnd(Camera.Handle); |
|
} |
|
|
|
bool CvCaptureCAM_PvAPI::startCapture() |
|
{ |
|
// Start the camera |
|
PvCaptureStart(Camera.Handle); |
|
|
|
// Set the camera to capture continuously |
|
if(PvAttrEnumSet(Camera.Handle, "AcquisitionMode", "Continuous")!= ePvErrSuccess) |
|
{ |
|
fprintf(stderr,"Could not set PvAPI Acquisition Mode\n"); |
|
return false; |
|
} |
|
|
|
if(PvCommandRun(Camera.Handle, "AcquisitionStart")!= ePvErrSuccess) |
|
{ |
|
fprintf(stderr,"Could not start PvAPI acquisition\n"); |
|
return false; |
|
} |
|
|
|
if(PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun")!= ePvErrSuccess) |
|
{ |
|
fprintf(stderr,"Error setting PvAPI trigger to \"Freerun\""); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
bool CvCaptureCAM_PvAPI::resizeCaptureFrame (int frameWidth, int frameHeight) |
|
{ |
|
char pixelFormat[256]; |
|
tPvUint32 frameSize; |
|
tPvUint32 sensorHeight; |
|
tPvUint32 sensorWidth; |
|
|
|
if (frame) |
|
{ |
|
cvReleaseImage(&frame); |
|
frame = NULL; |
|
} |
|
|
|
if (PvAttrUint32Get(Camera.Handle, "SensorWidth", &sensorWidth) != ePvErrSuccess) |
|
{ |
|
return false; |
|
} |
|
|
|
if (PvAttrUint32Get(Camera.Handle, "SensorHeight", &sensorHeight) != ePvErrSuccess) |
|
{ |
|
return false; |
|
} |
|
|
|
// Cap out of bounds widths to the max supported by the sensor |
|
if ((frameWidth < 0) || ((tPvUint32)frameWidth > sensorWidth)) |
|
{ |
|
frameWidth = sensorWidth; |
|
} |
|
|
|
if ((frameHeight < 0) || ((tPvUint32)frameHeight > sensorHeight)) |
|
{ |
|
frameHeight = sensorHeight; |
|
} |
|
|
|
|
|
if (PvAttrUint32Set(Camera.Handle, "Height", frameHeight) != ePvErrSuccess) |
|
{ |
|
return false; |
|
} |
|
|
|
if (PvAttrUint32Set(Camera.Handle, "Width", frameWidth) != ePvErrSuccess) |
|
{ |
|
return false; |
|
} |
|
|
|
PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL); |
|
PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize); |
|
|
|
|
|
if ( (strcmp(pixelFormat, "Mono8")==0) || (strcmp(pixelFormat, "Bayer8")==0) ) |
|
{ |
|
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 1); |
|
frame->widthStep = (int)frameWidth; |
|
Camera.Frame.ImageBufferSize = frameSize; |
|
Camera.Frame.ImageBuffer = frame->imageData; |
|
} |
|
else if ( (strcmp(pixelFormat, "Mono16")==0) || (strcmp(pixelFormat, "Bayer16")==0) ) |
|
{ |
|
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_16U, 1); |
|
frame->widthStep = (int)frameWidth*2; |
|
Camera.Frame.ImageBufferSize = frameSize; |
|
Camera.Frame.ImageBuffer = frame->imageData; |
|
} |
|
else if ( (strcmp(pixelFormat, "Rgb24")==0) || (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 if ( (strcmp(pixelFormat, "Rgba32")==0) || (strcmp(pixelFormat, "Bgra32")==0) ) |
|
{ |
|
frame = cvCreateImage(cvSize((int)frameWidth, (int)frameHeight), IPL_DEPTH_8U, 4); |
|
frame->widthStep = (int)frameWidth*4; |
|
Camera.Frame.ImageBufferSize = frameSize; |
|
Camera.Frame.ImageBuffer = frame->imageData; |
|
} |
|
else |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
cv::Ptr<cv::IVideoCapture> cv::create_PvAPI_capture( int index ) |
|
{ |
|
CvCaptureCAM_PvAPI* capture = new CvCaptureCAM_PvAPI; |
|
|
|
if ( capture->open( index )) |
|
return cv::makePtr<cv::LegacyCapture>(capture); |
|
|
|
delete capture; |
|
return NULL; |
|
} |
|
#endif
|
|
|