Refactored the PvAPI capture class to better facilitate dynamic property changes
- Added Gain control - Changed default acquisition mode to grayscale - Fixed a signed/unsigned compare issue - Implemented frame resizing - Implemented automatic buffer resizing on frame resize - Corrected camera initialization so that it attempts to put the camera in Mono8 but does not fail if this doesn't succeed.
This commit is contained in:
parent
4d059e9e5b
commit
3923484341
@ -95,6 +95,10 @@ protected:
|
||||
virtual void Sleep(unsigned int time);
|
||||
#endif
|
||||
|
||||
void stopCapture();
|
||||
bool startCapture();
|
||||
bool resizeCaptureFrame (int frameWidth, int frameHeight);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long UID;
|
||||
@ -113,6 +117,8 @@ protected:
|
||||
CvCaptureCAM_PvAPI::CvCaptureCAM_PvAPI()
|
||||
{
|
||||
monocrome=false;
|
||||
frame = NULL;
|
||||
grayframe = NULL;
|
||||
memset(&this->Camera, 0, sizeof(this->Camera));
|
||||
}
|
||||
|
||||
@ -132,8 +138,7 @@ void CvCaptureCAM_PvAPI::Sleep(unsigned int time)
|
||||
void CvCaptureCAM_PvAPI::close()
|
||||
{
|
||||
// Stop the acquisition & free the camera
|
||||
PvCommandRun(Camera.Handle, "AcquisitionStop");
|
||||
PvCaptureEnd(Camera.Handle);
|
||||
stopCapture();
|
||||
PvCameraClose(Camera.Handle);
|
||||
PvUnInitialize();
|
||||
}
|
||||
@ -162,7 +167,8 @@ bool CvCaptureCAM_PvAPI::open( int index )
|
||||
|
||||
Camera.UID = cameraList[index].UniqueId;
|
||||
|
||||
if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings)) {
|
||||
if (!PvCameraInfo(Camera.UID,&camInfo) && !PvCameraIpSettingsGet(Camera.UID,&ipSettings))
|
||||
{
|
||||
/*
|
||||
struct in_addr addr;
|
||||
addr.s_addr = ipSettings.CurrentIpAddress;
|
||||
@ -173,7 +179,8 @@ bool CvCaptureCAM_PvAPI::open( int index )
|
||||
printf("Current gateway:\t%s\n",inet_ntoa(addr));
|
||||
*/
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"ERROR: could not retrieve camera IP settings.\n");
|
||||
return false;
|
||||
}
|
||||
@ -181,73 +188,33 @@ bool CvCaptureCAM_PvAPI::open( int index )
|
||||
|
||||
if (PvCameraOpen(Camera.UID, ePvAccessMaster, &(Camera.Handle))==ePvErrSuccess)
|
||||
{
|
||||
|
||||
//Set Pixel Format to BRG24 to follow conventions
|
||||
/*Errcode = PvAttrEnumSet(Camera.Handle, "PixelFormat", "Bgr24");
|
||||
if (Errcode != ePvErrSuccess)
|
||||
{
|
||||
fprintf(stderr, "PvAPI: couldn't set PixelFormat to Bgr24\n");
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
tPvUint32 frameWidth, frameHeight, frameSize;
|
||||
tPvUint32 frameWidth, frameHeight;
|
||||
unsigned long maxSize;
|
||||
char pixelFormat[256];
|
||||
PvAttrUint32Get(Camera.Handle, "TotalBytesPerFrame", &frameSize);
|
||||
|
||||
// By Default, try to set the pixel format to Mono8. This can be changed later
|
||||
// via calls to setProperty. Some colour cameras (i.e. the Manta line) have a default
|
||||
// image mode of Bayer8, which is currently unsupported, so Mono8 is a safe bet for
|
||||
// startup.
|
||||
|
||||
monocrome = (PvAttrEnumSet(Camera.Handle, "PixelFormat", "Mono8") == ePvErrSuccess);
|
||||
|
||||
PvAttrUint32Get(Camera.Handle, "Width", &frameWidth);
|
||||
PvAttrUint32Get(Camera.Handle, "Height", &frameHeight);
|
||||
PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
|
||||
|
||||
// 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;
|
||||
if (strcmp(pixelFormat, "Mono8")==0) {
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
resizeCaptureFrame(frameWidth, frameHeight);
|
||||
|
||||
if(PvCommandRun(Camera.Handle, "AcquisitionStart")!= ePvErrSuccess)
|
||||
{
|
||||
fprintf(stderr,"Could not start Prosilica acquisition\n");
|
||||
return false;
|
||||
}
|
||||
return startCapture();
|
||||
|
||||
if(PvAttrEnumSet(Camera.Handle, "FrameStartTriggerMode", "Freerun")!= ePvErrSuccess)
|
||||
{
|
||||
fprintf(stderr,"Error setting Prosilica trigger to \"Freerun\"");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
fprintf(stderr,"Error cannot open camera\n");
|
||||
return false;
|
||||
@ -264,8 +231,10 @@ bool CvCaptureCAM_PvAPI::grabFrame()
|
||||
IplImage* CvCaptureCAM_PvAPI::retrieveFrame(int)
|
||||
{
|
||||
|
||||
if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess) {
|
||||
if (!monocrome) {
|
||||
if (PvCaptureWaitForFrameDone(Camera.Handle, &(Camera.Frame), 1000) == ePvErrSuccess)
|
||||
{
|
||||
if (!monocrome)
|
||||
{
|
||||
cvMerge(grayframe,grayframe,grayframe,NULL,frame);
|
||||
return frame;
|
||||
}
|
||||
@ -287,26 +256,31 @@ double CvCaptureCAM_PvAPI::getProperty( int property_id )
|
||||
PvAttrUint32Get(Camera.Handle, "Height", &nTemp);
|
||||
return (double)nTemp;
|
||||
case CV_CAP_PROP_EXPOSURE:
|
||||
PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp);
|
||||
return (double)nTemp;
|
||||
PvAttrUint32Get(Camera.Handle,"ExposureValue",&nTemp);
|
||||
return (double)nTemp;
|
||||
case CV_CAP_PROP_FPS:
|
||||
tPvFloat32 nfTemp;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return -1.0;
|
||||
}
|
||||
@ -315,19 +289,50 @@ 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);
|
||||
{
|
||||
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:
|
||||
PvAttrUint32Set(Camera.Handle, "Heigth", (tPvUint32)value);
|
||||
{
|
||||
tPvUint32 currWidth;
|
||||
|
||||
PvAttrUint32Get(Camera.Handle, "Width", &currWidth);
|
||||
|
||||
stopCapture();
|
||||
|
||||
// Reallocate Frames
|
||||
if (!resizeCaptureFrame(value, currWidth))
|
||||
{
|
||||
startCapture();
|
||||
return false;
|
||||
}
|
||||
|
||||
startCapture();
|
||||
|
||||
break;
|
||||
*/
|
||||
}
|
||||
case CV_CAP_PROP_MONOCROME:
|
||||
if (value==1) {
|
||||
if (value==1)
|
||||
{
|
||||
char pixelFormat[256];
|
||||
PvAttrEnumGet(Camera.Handle, "PixelFormat", pixelFormat,256,NULL);
|
||||
if ((strcmp(pixelFormat, "Mono8")==0) || strcmp(pixelFormat, "Mono16")==0) {
|
||||
if ((strcmp(pixelFormat, "Mono8")==0) || strcmp(pixelFormat, "Mono16")==0)
|
||||
{
|
||||
monocrome=true;
|
||||
}
|
||||
else
|
||||
@ -338,31 +343,157 @@ bool CvCaptureCAM_PvAPI::setProperty( int property_id, double value )
|
||||
break;
|
||||
case CV_CAP_PROP_EXPOSURE:
|
||||
if ((PvAttrUint32Set(Camera.Handle,"ExposureValue",(tPvUint32)value)==ePvErrSuccess))
|
||||
break;
|
||||
break;
|
||||
else
|
||||
return false;
|
||||
return false;
|
||||
case CV_CAP_PROP_PVAPI_MULTICASTIP:
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
case CV_CAP_PROP_GAIN:
|
||||
if (PvAttrUint32Set(Camera.Handle,"GainValue",(tPvUint32)value)!=ePvErrSuccess)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
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 (grayframe)
|
||||
{
|
||||
cvReleaseImage(&grayframe);
|
||||
grayframe = NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CvCapture* cvCreateCameraCapture_PvAPI( int index )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user