目录
前言
关于Pylon SDK的主要流程在上篇文章已经介绍过,有兴趣的读者可以点下面的链接。
Pylon SDK的C语言使用流程详解及代码示例_黑化咸鱼的博客-CSDN博客
本文主要解决Pylon中的相机配置问题。提到新的函数时笔者会首先列出其在头文件的定义,然后列出使用示例。
1.相机参数配置
1.1检验可访问性
在配置相机参数之前,需要确定相机每个参数的可访问性,Pylon配置了以下函数以提前检验相机参数的可访问性:
PylonDeviceFeatureIsImplemented():检查是否实现了某个特征
PylonDeviceFeatureIsAvailable():检查当前是否有该功能可用
PylonDeviceFeatureIsReadable() :检查某特征是否可读
PylonDeviceFeatureIsWritable():检查某特征是否可写
PYLONC_API _Bool PYLONC_CC
PylonDeviceFeatureIsImplemented(PYLON_DEVICE_HANDLE hDev, const char* pName);
PYLONC_API _Bool PYLONC_CC
PylonDeviceFeatureIsAvailable(PYLON_DEVICE_HANDLE hDev, const char* pName);
PYLONC_API _Bool PYLONC_CC
PylonDeviceFeatureIsReadable(PYLON_DEVICE_HANDLE hDev, const char* pName);
PYLONC_API _Bool PYLONC_CC
PylonDeviceFeatureIsWritable(PYLON_DEVICE_HANDLE hDev, const char* pName);
使用示例如下:
/* This function demonstrates how to check the presence, readability, and writability
of a feature. */
void demonstrateAccessibilityCheck( PYLON_DEVICE_HANDLE hDev )
{
_Bool val; /* Output of the check functions */
val = PylonDeviceFeatureIsImplemented(hDev, "Width");
printf("The 'Width' feature %s implemented\n", val ? "is" : "isn't");
val = PylonDeviceFeatureIsImplemented(hDev, "MyCustomFeature");
printf("The 'MyCustomFeature' feature %s implemented\n", val ? "is" : "isn't");
val = PylonDeviceFeatureIsAvailable(hDev, "BinningVertical");
printf("The 'BinningVertical' feature %s available\n", val ? "is" : "isn't");
val = PylonDeviceFeatureIsReadable(hDev, "Width");
printf("The 'Width' feature %s readable\n", val ? "is" : "isn't");
val = PylonDeviceFeatureIsImplemented( hDev, "MyCustomFeature");
printf("The 'MyCustomFeature' feature %s readable\n", val ? "is" : "isn't");
val = PylonDeviceFeatureIsWritable( hDev, "Width");
printf("The 'Width' feature %s writable\n", val ? "is" : "isn't");
printf("\n");
}
1.2枚举特征
我们可以在Pylon Viewer中看到相机的许多特征,如曝光时间等。有一些相机的特征有类似枚举的形式,即枚举特征。枚举特征可以从一组固定的可能值中获取一个值,比如相机中像素格式的特性。我们可以通过Pylon Viewer的特征文档窗口查看可能值有哪些,比如还是查看像素格式,在特征界面我们选中时,特征文档窗口会出现对应的可能值。
使用PylonDeviceFeatureFromString()和PylonDeviceFeatureToString()用于设置和获取相机特性的值,来处理枚举特性。注意枚举特性在函数中以字符串形式表示。
IDL_ENTRY(PYLONC_MODULE, "_PylonDeviceFeatureFromString@12", "Set a feature's value from a string.")
PYLONC_API GENAPIC_RESULT PYLONC_CC PINVOKE
PylonDeviceFeatureFromString(PYLON_DEVICE_HANDLE hDev, STRING_PAR const char* pName, STRING_PAR const char* pValue);
PYLONC_API GENAPIC_RESULT PYLONC_CC
PylonDeviceFeatureToString(PYLON_DEVICE_HANDLE hDev, const char *pName, char* pBuf, size_t* pBufLen);
使用示例如下:
void demonstrateEnumFeature( PYLON_DEVICE_HANDLE hDev )
{
char value[64]; /* The current value of the feature */
size_t len; /* The length of the string */
GENAPIC_RESULT res; /* Return value */
_Bool isWritable,
supportsMono8,
supportsYUV422Packed,
supportsMono16;
/* The allowed values for an enumeration feature are represented as strings. Use the
PylonDeviceFeatureFromString() and PylonDeviceFeatureToString() methods for setting and getting
the value of an enumeration feature. */
/* Get the current value of the enumeration feature. */
len = sizeof(value);
res = PylonDeviceFeatureToString( hDev, "PixelFormat", value, &len );
CHECK(res);
printf("PixelFormat: %s\n", value);
/*
For an enumeration feature, the pylon Viewer's "Feature Documentation" window lists the the
names of the possible values. Some of the values might not be supported by the device.
To check if a certain "SomeValue" value for a "SomeFeature" feature can be set, call the
PylonDeviceFeatureIsAvailable() function with "EnumEntry_SomeFeature_SomeValue" as an argument.
*/
/* Check to see if the Mono8 pixel format can be set. */
supportsMono8 = PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono8");
printf("Mono8 %s a supported value for the PixelFormat feature\n", supportsMono8 ? "is" : "isn't");
/* Check to see if the YUV422Packed pixel format can be set. */
supportsYUV422Packed = PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_YUV422Packed");
printf("YUV422Packed %s a supported value for the PixelFormat feature\n", supportsYUV422Packed ? "is" : "isn't");
/* Check to see if the Mono16 pixel format can be set. */
supportsMono16 = PylonDeviceFeatureIsAvailable(hDev, "EnumEntry_PixelFormat_Mono16");
printf("Mono16 %s a supported value for the PixelFormat feature\n", supportsMono16 ? "is" : "isn't");
/* Before writing a value, we recommend checking to see if the enumeration feature is
currently writable. */
isWritable = PylonDeviceFeatureIsWritable(hDev, "PixelFormat");
if ( isWritable )
{
/* The PixelFormat feature is writable, set it to one of the supported values. */
if ( supportsMono16 )
{
printf("Setting PixelFormat to Mono16\n");
res = PylonDeviceFeatureFromString( hDev, "PixelFormat", "Mono16" );
CHECK(res);
}
else if ( supportsYUV422Packed )
{
printf("Setting PixelFormat to YUV422Packed\n");
res = PylonDeviceFeatureFromString( hDev, "PixelFormat", "YUV422Packed" );
CHECK(res);
}
else if ( supportsMono8 )
{
printf("Setting PixelFormat to Mono8\n");
res = PylonDeviceFeatureFromString( hDev, "PixelFormat", "Mono8" );
CHECK(res);
}
/* Reset the PixelFormat feature to its previous value. */
PylonDeviceFeatureFromString( hDev, "PixelFormat", value );
}
}
1.3整数特征
对于相机的某些整数特征,仅允许设置范围内的整数值。例如,对于某些相机,宽度参数必须是2的倍数。整数的约束由增量值表示,采用如下约束形式:
val >= min && val <= max && val == min + n * inc.
整数特征值的获取调用如下函数:
PylonDeviceGetIntegerFeatureMin():获得最小值
PylonDeviceGetIntegerFeatureMax():获得最大值
PylonDeviceGetIntegerFeatureInc():获得增量值
PylonDeviceGetIntegerFeature():获得当前值
PYLONC_API GENAPIC_RESULT PYLONC_CC PINVOKE
PylonDeviceGetIntegerFeature(PYLON_DEVICE_HANDLE hDev, const char *pName, PINVOKE_RETVAL_PAR int64_t *pValue);
PYLONC_API GENAPIC_RESULT PYLONC_CC PINVOKE
PylonDeviceGetIntegerFeatureMin(PYLON_DEVICE_HANDLE hDev, const char *pName, PINVOKE_RETVAL_PAR int64_t *pValue);
PYLONC_API GENAPIC_RESULT PYLONC_CC PINVOKE
PylonDeviceGetIntegerFeatureMax(PYLON_DEVICE_HANDLE hDev, const char *pName, PINVOKE_RETVAL_PAR int64_t *pValue);
PYLONC_API GENAPIC_RESULT PYLONC_CC PINVOKE
PylonDeviceGetIntegerFeatureInc(PYLON_DEVICE_HANDLE hDev, const char *pName, PINVOKE_RETVAL_PAR int64_t *pValue);
注意到上述函数的pValue值类型定义适用于64位整数,Pylon也提供了适用32位整数的对应函数如下:
PYLONC_API GENAPIC_RESULT PYLONC_CC
PylonDeviceGetIntegerFeatureInt32(PYLON_DEVICE_HANDLE dev, const char *name, int32_t *value);
PYLONC_API GENAPIC_RESULT PYLONC_CC
PylonDeviceGetIntegerFeatureMinInt32(PYLON_DEVICE_HANDLE dev, const char *name, int32_t *value);
PYLONC_API GENAPIC_RESULT PYLONC_CC
PylonDeviceGetIntegerFeatureMaxInt32(PYLON_DEVICE_HANDLE dev, const char *name, int32_t *value);
PYLONC_API GENAPIC_RESULT PYLONC_CC
PylonDeviceGetIntegerFeatureIncInt32(PYLON_DEVICE_HANDLE dev, const char *name, int32_t *value);
使用示例如下:
/* This function demonstrates how to handle integer camera parameters. */
void demonstrateIntFeature( PYLON_DEVICE_HANDLE hDev )
{
staticconstchar featureName[] = "Width"; /* Name of the feature used in this sample: AOI Width */
int64_t val, min, max, incr; /* Properties of the feature */
GENAPIC_RESULT res; /* Return value */
if ( PylonDeviceFeatureIsReadable(hDev, featureName) )
{
/*
Query the current value, the allowed value range, and the increment of the feature.
For some integer features, you are not allowed to set every value within the
value range. For example, for some cameras the Width parameter must be a multiple
of 2. These constraints are expressed by the increment value. Valid values
follow the rule: val >= min && val <= max && val == min + n * inc. */
res = PylonDeviceGetIntegerFeatureMin( hDev, featureName, &min ); /* Get the minimum value. */
CHECK(res);
res = PylonDeviceGetIntegerFeatureMax( hDev, featureName, &max ); /* Get the maximum value. */
CHECK(res);
res = PylonDeviceGetIntegerFeatureInc( hDev, featureName, &incr); /* Get the increment value. */
CHECK(res);
res = PylonDeviceGetIntegerFeature( hDev, featureName, &val ); /* Get the current value. */
CHECK(res);
#if __STDC_VERSION__ >= 199901L || defined(__GNUC__)
printf("%s: min= %lld max= %lld incr=%lld Value=%lld\n", featureName, (longlong ) min, (longlong ) max, (longlong ) incr, (longlong ) val );
#else
printf("%s: min= %I64d max= %I64d incr=%I64d Value=%I64d\n", featureName, min, max, incr, val );
#endif
if ( PylonDeviceFeatureIsWritable(hDev, featureName) )
{
/* Set the Width half-way between minimum and maximum. */
res = PylonDeviceSetIntegerFeature( hDev, featureName, min + (max - min) / incr / 2 * incr );
CHECK(res);
}
else
fprintf(stderr, "The %s feature is not writable.\n", featureName );
}
else
fprintf(stderr, "The %s feature is not readable.\n", featureName );
}
2.应用一:打印相机参数
相机设备的信息参数是枚举特征之一,我们可以在官网文档的Device Information Parameters找到相机的设备参数,并传入PylonDeviceFeatureToString()来获取。
以下仅列出部分参数,更多参数请见官网产品文档:Device Information Parameters | Basler
比如我们想打印相机的型号名称,就可以传DeviceModelName参数,使用示例如下:
/* Print out the name of the camera we are using. */
{
char buf[256];
size_t siz = sizeof(buf);
_Bool isReadable;
isReadable = PylonDeviceFeatureIsReadable(hDev, "DeviceModelName");
if ( isReadable )
{
res = PylonDeviceFeatureToString(hDev, "DeviceModelName", buf, &siz );
CHECK(res);
printf("Using camera %s\n", buf);
}
}
3.应用二:优化Basler GigE相机性能
对Basler GigE相机,Pylon 提供的网络化参数可以用于该类型相机的优化,这里仅介绍常用的两种枚举特征参数:PayloadSize、GevSCPSPacketSize
。官方文档的描述如下:
有效负载大小#
PayloadSize
参数的值指示图像数据加上传输的任何块数据的总大小(以字节为单位)。数据包headers不包括在内。此为只读参数。
在流抓取器抓取图像时,将该整形特征传入PylonDeviceGetIntegerFeatureInt32(),可以获得采集图像时缓冲区所需大小,并为每个缓冲区分配足够的空间。
使用示例如下:
/* Determine the required size of the grab buffer. */
if ( PylonDeviceFeatureIsReadable(hDev, "PayloadSize") )
{
res = PylonDeviceGetIntegerFeatureInt32( hDev, "PayloadSize", &payloadSize );
}
else
{
;
}
/* Allocate memory for grabbing. */
for ( i = 0; i < NUM_BUFFERS; ++i )
{
buffers[i] = (unsigned char*) malloc ( payloadSize );
if ( NULL == buffers[i] )
{
PylonTerminate();
}
}
数据包大小#
GevSCPSPacketSize
参数指定通过以太网传输的数据包的最大大小。该值以字节为单位。该参数应始终设置为网络硬件可以处理的最大大小。
默认情况下,数据包大小设置为 1500 字节。这对于大多数配置已经足够。如果需要,可以增加数据包大小以减少以太网开销负载并提高网络效率。
无论数据包大小如何,前导和尾随部分的大小始终保持不变。您应该记住,在大多数情况下,最后一个数据包比其他数据包小。
注意:
- 如果将数据包大小增加到 1500 字节以上,则必须在所有涉及的网络设备(包括任何交换机)上启用所谓的巨型帧支持。
- 每当增加相机端的数据包大小时,还必须调整网络控制器卡的数据包大小。否则,数据流可能会由于数据包阻塞而失败。
对于GigE摄像头,官方建议增加包的大小以获得更好的性能。当网卡支持巨帧时,可以将数据包大小设置为> 1500,例如8192。在下面示例中,我们设置包装尺寸为1500。
/* ... Check first to see if the GigE camera packet size parameter is supported and if it is writable. */
isAvail = PylonDeviceFeatureIsWritable(hDev, "GevSCPSPacketSize");
if ( isAvail )
{
/* ... The device supports the packet size feature, set a value. */
res = PylonDeviceSetIntegerFeature( hDev, "GevSCPSPacketSize", 1500 );
}