文章目录
Silicon Software图像采集卡简介
介绍功能强大且灵活的microEnable Frame Grabber系列软件开发套件(SDK)。
在某些情况下,不同的参数将用于不同的图像采集卡设置(即彩色或灰度采集卡)。这些差异可以在相应相机制造商的软件手册中找到。
microEnable帧接收器系列是其基于FPGA技术的现代图像采集卡。
在Silicon Software图像采集卡上,基本上有3种可能性可以使用某些功能集(通过applet表示)。
- 可以加载和访问预定义的applet(称为Acquisition Applet or SmartApplets);
- 可以使用VisualApplets(称为VA Applet)创建和访问具有特定功能的自定义applet 。
一个主要区别是:
- 对于AcquisitionApplets / SmartApplets,处理.dll文件;
- 对于VA Applets,处理.hap文件;
初始化抓帧器
使用microEnable之前,必须先初始化抓帧器。初始化必须通过启动程序来处理。初始化与设备的连接时,将建立驱动程序并初始化所有必要的内部数据结构。
Fg_getParameter()或Fg_getParameterEx()会通知已设置的特殊值。
释放帧捕获器
完成采集或发生错误后,必须使用Fg_FreeGrabber()释放帧捕获器资源。
抓取帧并显示的步骤
-
搜索连接到电脑中的硬件板子数目,并选择一个将要被初始化的帧捕捉器编号。
-
通过帧捕捉器型号编号获取Applet。
必须在配置特殊参数之前创建并选择正确的applet。必须加载Applet以初始化帧抓取器。可以通过逻辑数字选择几种可能可用的图像采集卡之一。对于应用于采集的每个采集卡,必须加载一个applet。采集卡1的变量号必须为0,采集卡2的变量号必须为1,依此类推。
-
初始化帧抓取器
-
设置参数
-
创建显示窗口并设置窗口缓冲区
-
计算缓冲区大小并分配内存
-
开始抓取
-
循环抓取当前帧,并显示当前帧
-
释放资源:关闭显示窗口,停止抓帧,释放内存,释放帧捕捉器
sisoboards.h
板子类型的常数定义。
定义的板子类型
siso_board_type
enum siso_board_type {
PN_MICROENABLE = 0xa1, /**< microEnable I */
PN_MICROENABLEII = 0xa2, /**< microEnable II */
PN_MICROENABLE3I = 0xa3, /**< microEnable III */
PN_MICROENABLE3IXXL = 0xa31, /**< microEnable III-XXL */
PN_MICROENABLE4AD1CL = 0xa40, /**< microEnable IV AD1-CL */
PN_MICROENABLE4BASE =
PN_MICROENABLE4AD1CL, /**< \deprecated old name for PN_MICROENABLE4AD1CL, maintained only for source compatibility */
PN_MICROENABLE4BASEx4 = 0xa43, /**< \deprecated name for a prototype never used*/
PN_MICROENABLE4AD4CL = 0xa42, /**< microEnable IV AD4-CL */
PN_MICROENABLE4VD1CL = 0xa41, /**< microEnable IV VD1-CL */
PN_MICROENABLE4FULLx1 =
PN_MICROENABLE4VD1CL, /**< \deprecated old name for PN_MICROENABLE4VD1CL, maintained only for source compatibility */
PN_MICROENABLE4VD4CL = 0xa44, /**< microEnable IV VD4-CL */
PN_MICROENABLE4FULLx4 =
PN_MICROENABLE4VD4CL, /**< \deprecated old name for PN_MICROENABLE4VD4CL, maintained only for source compatibility */
PN_MICROENABLE4AS1CL = 0xa45, /**< microEnable IV AS1-CL */
PN_MICROENABLE4VQ4GE = 0xe44, /**< microEnable IV VQ4-GE */
PN_MICROENABLE4GIGEx4 =
PN_MICROENABLE4VQ4GE, /**< \deprecated old name for PN_MICROENABLE4VQ4GE, maintained only for source compatibility */
PN_MICROENABLE4AQ4GE = 0xe42, /**< microEnable IV AQ4-GE */
PN_MICROENABLE4_H264CLx1 = 0xb41, /**< kappa h264 Fujitsu MB86H51 */
PN_MICROENABLE4_H264pCLx1 = 0xb42, /**< kappa h264 Fujitsu MB86H46A */
PN_PX100 = 0xc41, /**< PixelPlant PX100 */
PN_PX200 = 0xc42, /**< PixelPlant PX200 */
PN_PX210 = 0xc43, /**< PixelPlant PX210-CL */
PN_PX300 = 0xc44, /**< PixelPlant PX300-CxP */
PN_MICROENABLE5A1CXP4 = 0xa51, /**< microEnable 5 A01-CXP */
PN_MICROENABLE5A1CLHSF2 = 0xa52, /**< microEnable 5 A1-CLHS-F2 */
PN_MICROENABLE5AQ8CXP6B = 0xa53, /**< microEnable 5 AQ8-CXP6B */
PN_MICROENABLE5AQ8CXP4 =
PN_MICROENABLE5AQ8CXP6B, /**< \deprecated old name for PN_MICROENABLE5AQ8CXP6B, maintained only for source compatibility */
PN_MICROENABLE5VQ8CXP6B = 0xa54, /**< microEnable 5 VQ8-CXP6B */
PN_MICROENABLE5VQ8CXP4 =
PN_MICROENABLE5VQ8CXP6B, /**<\deprecated old name for PN_MICROENABLE5VQ8CXP6B, maintained only for source compatibility */
PN_MICROENABLE5AD8CLHSF2 = 0xa55, /**< microEnable 5 AD8-CLHS-F2 */
PN_MICROENABLE5VQ8CXP6D = 0xa56, /**< microEnable 5 VQ8-CXP6D */
PN_MICROENABLE5AQ8CXP6D = 0xa57, /**< microEnable 5 AQ8-CXP6D */
PN_MICROENABLE5VD8CL = 0xa58, /**< microEnable 5 VD8-CL */
PN_MICROENABLE5VF8CL =
PN_MICROENABLE5VD8CL, /**< \deprecated old name for PN_MICROENABLE5VD8CL, maintained only for source compatibility */
PN_MICROENABLE5A2CLHSF2 = 0xa59, /**< microEnable 5 A2-CLHS-F2 */
PN_MICROENABLE5AD8CL = 0xa5a, /**< microEnable 5 AD8-CL */
PN_MICROENABLE5_LIGHTBRIDGE_VCL_PROTOTYPE = 0x750, /**< LightBridge VCL Prototype */
PN_MICROENABLE5_LIGHTBRIDGE_MARATHON_VCL = 0x751, /**< LightBridge/Marathon VCL */
PN_MICROENABLE5_LIGHTBRIDGE_VCL = 0x7510, /**< LightBridge VCL */
PN_MICROENABLE5_MARATHON_VCL = 0x7511, /**< mE5 marathon VCL */
PN_MICROENABLE5_MARATHON_AF2_DP = 0x752, /**< mE5 marathon AF2 (CLHS dual port) */
PN_MICROENABLE5_MARATHON_ACX_QP = 0x753, /**< mE5 marathon ACX QP (CXP quad port) */
PN_MICROENABLE5_LIGHTBRIDGE_MARATHON_ACL = 0x754, /**< LightBridge/Marathon ACL */
PN_MICROENABLE5_LIGHTBRIDGE_ACL = 0x7540, /**< LightBridge ACL */
PN_MICROENABLE5_MARATHON_ACL = 0x7541, /**< mE5 marathon ACL */
PN_MICROENABLE5_MARATHON_ACX_SP = 0x755, /**< mE5 marathon ACX SP (CXP single port) */
PN_MICROENABLE5_MARATHON_ACX_DP = 0x756, /**< mE5 marathon ACX DP (CXP dual port) */
PN_MICROENABLE5_MARATHON_VCX_QP = 0x757, /**< mE5 marathon VCX QP (CXP quad port) */
PN_MICROENABLE5_MARATHON_VF2_DP = 0x758, /**< mE5 marathon VF2 (CLHS dual port) */
PN_MICROENABLE5_LIGHTBRIDGE_MARATHON_VCLx = 0x759, /**< LightBridge/Marathon VCLx */
//PN_MICROENABLE5_LIGHTBRIDGE_VCLx = 0x7590, /**< LightBridge VCLx */
PN_MICROENABLE5_MARATHON_VCLx = 0x7591, /**< mE5 marathon VCLx (VCL with XC7K410T FPGA) */
PN_TDI = 0xb50, /**< Thunderbolt Device Interface/II */
PN_TDI_I = 0xb500, /**< Thunderbolt Device Interface */
PN_TDI_II = 0xb501, /**< Thunderbolt Device Interface II*/
PN_TGATE_USB = 0xb57, /**< T-Gate USB/II */
PN_TGATE_I_USB = 0xb570, /**< T-Gate USB/II */
PN_TGATE_II_USB = 0xb571, /**< T-Gate USB/II */
PN_TGATE = 0xb5e, /**< T-Gate/II */
PN_TGATE_I = 0xb5e0, /**< T-Gate/II */
PN_TGATE_II = 0xb5e1, /**< T-Gate/II */
PN_TGATE_35 = 0xb58, /**< T-Gate/II 35 USB */
PN_TGATE_I_35 = 0xb580, /**< T-Gate/II 35 USB */
PN_TGATE_II_35 = 0xb581, /**< T-Gate/II 35 USB */
PN_TGATE_35_USB = 0xb59, /**< T-Gate/II 35 USB */
PN_TGATE_I_35_USB = 0xb590, /**< T-Gate/II 35 USB */
PN_TGATE_II_35_USB = 0xb591, /**< T-Gate/II 35 USB */
PN_TTDI = 0xb5f, /**< Test Thunderbolt Device Interface */
PN_MICROENABLE5_ABACUS_4G_PROTOTYPE = 0xb51, /**< microEnable 5 Abacus 4G Prototype */
PN_MICROENABLE5_ABACUS_4G =
PN_MICROENABLE5_ABACUS_4G_PROTOTYPE, /**< \deprecated old name for PN_MICROENABLE5_ABACUS_4G_PROTOTYPE, maintained only for source compatibility */
PN_MICROENABLE5_ABACUS_4G_BASE = 0xb52, /**< microEnable 5 Abacus 4G Base */
PN_MICROENABLE5_ABACUS_4G_BASE_II = 0xb53, /**< microEnable 5 Abacus 4G Base II (7K70T FPGA) */
PN_MICROENABLE6_KCU105 = 0xA60, /**< microEnable 6 Evaluation Board */
#ifdef PLATFORM_PROTOTYPING
PN_ML605 = 0xff46, /**< Xilinx ML605 Evaluation board */
#endif
PN_UNKNOWN = 0xffff,
PN_GENERIC_EVA = 0x10000000,
PN_NONE = 0
};
板类型标识符。每个设备都由其中一个标识符标识。可以通过Fg_getBoardType函数或使用带FG_BOARD_INFORMATION参数的Fg_getParameterWithType函数来查询。
只有连接器的物理布局不同的板子变体(例如CL连接器和PoCL连接器)使用相同的类型值。
fgrab_prototyp.h
设备和Applet的信息
这些函数将返回给定设备或applet或其组合的静态信息。在相同的输入上再次调用这些函数通常会再次返回相同的信息。
Fg_getBoardType
int Fg_getBoardType(int BoardIndex);
-
说明
Fg_getBoardType()返回板的类型:如果是microEnable III / -XXL或microEnable IV-Full x1 / -Full x4。PixelPlant目前无法被检测到。 -
返回值
◼ BoardIndex
板子的索引。 -
返回值
fg_error:没有带有给定索引的板。
板子类型的定义可以看:sisoboards.h
举例:
uint32_t boardType = BINFO_BOARDTYPE; Fg_getParameterWithType(fg, FG_BOARD_INFORMATION, &boardType, 0, FG_PARAM_TYPE_UINT32_T);
Fg_getBoardNameByType
const char * Fg_getBoardNameByType(const int BoardType, const int UseShortName);
- 说明
Fg_getBoardNameByType()返回板类型的名称。 - 参数
◼ BoardType
板类型
◼ UseShortName
获取板的简名称 - 返回值
NULL:没有给定类型的板
Fg_getSerialNumber
unsigned int Fg_getSerialNumber(Fg_Struct *Fg);
- 说明
函数Fg_getSerialNumber()读取帧捕获器的序列号。 - 参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针。 - 返回值
板子的序列号。
要得到与板子上相同的表示法,应该用十六进制写出来。
Fg_getSWVersion
const char *const Fg_getSWVersion();
- 说明
函数Fg_getSWVersion()返回正在运行的SDK的版本。
Fg_getAppletVersion
const char *Fg_getAppletVersion(Fg_Struct *Fg, int AppletId);
- 说明
获取当前运行的applet的版本。 - 参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针。
◼ AppletId
由Fg_getappletId()返回的applet ID。 - 返回值
如果不是使用VisualApplets创建的设计,则返回设计的applet版本号。
Fg_getAppletId
int Fg_getAppletId(Fg_Struct *Fg, const char *ignored);
- 说明
获取当前运行的applet的ID。 - 参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针。
◼ ignored
should be NULL。
只是为了与早期的软件接口兼容。它被忽略,应该是NULL。 - 返回值
returns the applet ID of the design if it is not a design created using VisualApplets.
对于ID的定义可以看:fgrab_define.h
查询连接到系统中与帧捕获器相关的信息
Fg_getSystemInformation
int Fg_getSystemInformation(
Fg_Struct *Fg,
const enum Fg_Info_Selector selector,
const enum FgProperty propertyId,
int param1,
void* buffer,
unsigned int* bufLen
);
-
说明
以空终止字符串的形式返回当前帧捕获系统的各种信息。
对于要查询的附加控制/寻址信息,可以使用param1,这取决于要查询的值。例如:在多板系统中查询某个板的信息时,必须对该板进行寻址。Param1可用于板子的寻址。
当将空指针作为缓冲区传递时,函数将返回所需的缓冲大小(以字节为单位)来放置内容。
-
参数
◼ Fg
使用帧抓取器,可以设置为0作为全局信息,必须在一定的参数下设置。
◼ selector
要查询的关于帧捕获器的哪项信息。
◼ propertyid
确定要获取与FgProperty对应的哪些信息
◼ param1
寻址信息的第一个参数,取决于要查询的选择信息(选择器)。
如果有冲突,Fg参数被忽略。
◼ buffer
结果值缓冲区;对于某些查询,缓冲区同时用于输入和输出,在输出时缓冲区将被覆盖。
◼ bufLen
分配缓冲区的长度[in],向缓冲区填充的字节数[out] -
返回值
FG_OK 表示缓冲区内的成功和有效数据。此时参数bufLen相应地被填充。
FG_OK如果出现错误,调用fg_getLastErrorDescription函数获取详细信息。
例如
Fg_getSystemInformation(NULL,INFO_NR_OF_BOARDS,PROP_ID_VALUE,0,buffer, &buflen)
获取连接到计算机上的帧捕获器的数量
板的初始化
初始化后,将通过单独的数据结构Fg_Struct对每个帧采集卡进行唯一处理。帧采集卡的选择按PC中插槽数量的增加进行排序。请注意,每个PC的唯一ID可能不同。
此外,每个采集卡都有唯一的ID,即序列号,该序列号印在每个板上。可以通过microDiagnosis和microDisplay进行显示。识别多个采集卡的另一种可能性是使用函数Fg_getSerialNumber()通过SDK求序列号。
调用Fg_Init() 只是调用Fg_InitEx() 的缩写,最后一个参数为0(即主模式)。
Fg_InitEx
Fg_Struct *Fg_InitEx(const char *FileName, unsigned int BoardIndex, int flags);
-
说明
在主模式或从模式初始化帧捕获器。这个函数用给定的applet初始化一个帧抓取器。支持标准Applet和生成HAP文件的VisualApplet。BoardIndex参数用于处理同一系统中的多个帧捕获器。
板号取决于系统架构和操作系统。一般来说,板号取决于PCI设置,即板与较低的PCI总线和槽数将有较低的板号。在Windows系统上,meIII抓取器的数量总是比meIV设备少。在Linux上,顺序只取决于PCI总线号,导致meIII设备通常出现在更高的设备号上,因为PCI总线通常是PCI Express桥的最后一个子总线。找到从板到板id的映射的最简单的方法是使用microDiagnostics,它显示板类型、序列号和板索引。
-
参数
◼ FileName
用于初始化的Applet 名。
◼ BoardIndex
板的逻辑号。
◼ flags
修改初始化行为的标记。 -
返回值
返回初始化后板子的数据结构的指针。
NULL: 初始化失败。
- 如果该函数返回NULL,可以调用Fg_getLastErrorNumber(NULL)来获取错误代码。
- 由Fg_InitEx()初始化的帧抓取器资源必须由Fg_FreeGrabber()释放。
Fg_Init
Fg_Struct *Fg_Init(const char *FileName, unsigned int BoardIndex);
- 说明
这个函数相当于调用Fg_InitEx(FileName, BoardIndex, 0)。初始化型号为FileName,编号为BoardIndex的板子。 - 参数
◼ FileName
用于初始化的Applet的名字。
◼ BoardIndex
板的逻辑编号。 - 返回值
返回初始化后板子的数据结构的指针。
NULL: 初始化失败。
- 由Fg_Init()初始化的帧抓取器资源必须由Fg_FreeGrabber()释放。
- 如果该函数返回NULL,您可以调用Fg_getLastErrorNumber(NULL)来获取错误代码。
释放帧捕捉器
Fg_FreeGrabber
int Fg_FreeGrabber(Fg_Struct *Fg);
-
说明
释放帧捕捉器的资源。函数Fg_FreeGrabber()停止操作帧抓取器并释放资源。
◻◻ Fg_AllocMem已经分配的帧缓冲区将被释放。函数Fg_FreeMem将在内部执行。
◻◻否则,Fg_AllocMemEx分配的帧缓冲区将被释放,所有内部资源将被释放。 -
参数
◼ Fg
释放的帧抓取器。 -
返回值
返回值 说明 FG_OK 操作帧抓取器已成功停止。 FG_NOT_INIT 帧抓取器没有正确初始化。 FG_FILE_NOT_FOUND 文件找不到。 FG_INVALID_FILENAME 该文件名不是有效的文件名。 FG_SISODIR5_NOT_SET 没有设置SISODIR5环境变量。 FG_NOT_ENOUGH_MEM 系统内存不足以加载控制结构 FG_CANNOT_INIT_MICROENABLE 无法初始化帧抓取器 FG_HAP_FILE_NOT_LOAD Applet文件(HAP文件)不是有效的HAP文件。
设置帧捕获器参数
Fg_setParameter
int Fg_setParameter(Fg_Struct *Fg, const int Parameter, const void *Value, const unsigned int DmaIndex);
-
说明
每个由Fg_Init()或Fg_InitConfig()加载的applet都有一组用于更改和控制applet操作的参数。可用参数的数量、它们的名称和函数取决于使用VisualApplets创建的设计。
可用参数由设计中使用的VisualApplets操作符决定。
Applet参数通过它们的ID来访问。ID是一个整数值,可以使用两个SDK函数来确定。
这些函数是:Fg_getParameterId()和Fg_getParameterIdByName()。
通过参数ID,可以使用Fg_setParameter在applet中设置参数值,或者使用Fg_getParameter读取参数值。
可以通过调用Fg_getNrOfParameter来确定applet中可用参数的数量,即使用Fg_getParameterName来确定每个参数的名称。使用Fg_setParameter()设置applet参数。该函数接受Fg_Struct指针,因为它是由Fg_Init或Fg_InitConfig、参数ID、新值和关联的DMA编号返回的。
许多参数id已经预先定义,并且通常可用。可以使用预定义的常量访问它们。这些参数汇总如下表:
>类型 标志 值 说明 int FG_TIMEOUT min: 1秒;max: 2,147,483,646秒. 以秒为单位,直到设备驱动程序显示超时 int FG_GLOBAL_ACCESS auto = 0, read = 1, read write = 3, read write change = 7 可能性的访问标志 -
参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针.
◼ Parameter
作为参数,需要一个标识号。可以是Fg_getParameterId()或Fg_getParameterIdByName()返回的值,也可以是一般可用参数的ID。
如果识别号未知,则必须提供参数名称。有关可能的参数名称的更多信息,参见下表:
◼ Value
指向Parameter所需值的指针。
◼ DmaIndex
使用的DMA端口的逻辑号。与DMA端口相关联的摄像机取决于applet。Silicon Software Runtime随附的所有采集Applet都具有DMA端口和摄像机端口之间的直接映射。这意味着DmaIndex 0与PORT A相关联,DmaIndex 1与PORT B相关联,依此类推。 -
返回值
类型 说明 FG_OK 参数设置正确。 FG_NOT_INIT 初始化失败。 FG_INVALID_PARAMETER 输入了一个无效的参数。 FG_VALUE_OUT_OF_RANGE 输入的值在有效范围之外。
例子:
通过Fg_setParameter()选择性访问进行修改。
设置一定的图像宽度和高度。参数width和height必须包含以像素为单位的图像大小。unsigned int width = 1024; unsigned int height = 1024; Fg_setParameter(fg,FG_WIDTH,&width,1); Fg_setParameter(fg,FG_HEIGHT,&height,1);
查询错误信息
Fg_getLastErrorNumber
int Fg_getLastErrorNumber(Fg_Struct *Fg);
- 说明
函数Fg_getLastErrorNumber()显示最近发生的错误的错误代码。 - 参数
◼ Fg
使用的帧抓取器。 - 返回值
最后一个错误的错误编号。
getErrorDescription
const char *const getErrorDescription(int ErrorNumber);
- 说明
根据错误编号描述错误消息。 - 参数
◼ ErrorNumber
将要描述的错误的错误编号。 - 返回值
将返回给定错误代码的描述字符串。
Fg_getLastErrorDescription
const char *const Fg_getLastErrorDescription(Fg_Struct *Fg);
- 说明
描述最后一个错误信息。 - 参数
◼ Fg
使用的帧抓取器。 - 返回值
返回发生的最后一个错误的消息。
- 使用函数Fg_getLastErrorDescription()最后发生的错误将被返回作为错误消息。
- 该函数相当于getErrorDescription(Fg_getLastErrorNumber(Fg))。
Fg_getErrorDescription
const char *const Fg_getErrorDescription(Fg_Struct *Fg, int ErrorNumber);
-
说明
对错误代码的错误消息的简要描述。在接收错误代码时返回错误消息。
-
参数
◼ Fg
使用的帧抓取器。
◼ ErrorNumber
标识错误代码的编号。 -
返回值
返回指定的错误代码的错误描述消息。
内存管理
抓取图像之前,必须先分配内存以创建用于获取图像的帧缓冲区,然后将图像存储在其中。
内存管理是完全动态的,可以由系统以及帧捕获器提供,以供进一步使用。在每种情况下,将在PC中定义的图像缓冲区划分为用于存储图像数据的子缓冲区。
分配帧缓冲区有两种常规模式:
- 用户分配的帧存储器:数据存储在用户应用程序指定的存储位置中
- 采集器分配的帧内存:帧采集器库管理内存缓冲区
Fg_AllocMem
void *Fg_AllocMem(Fg_Struct *Fg, const size_t Size, const frameindex_t BufCnt, const unsigned int DmaIndex);
-
说明
函数Fg_AllocMem()将用户内存的一个定义区域保留为帧捕获内存,并将其阻塞在系统内存中。帧缓冲区可以细分为几个子缓冲区。
帧缓冲区组织为环形缓冲区。它的意思是,如果一个图像被写入帧缓冲区的最后一个子缓冲区,下一幅图像将在帧缓冲区的第一个子缓冲区中传输,现有的图像将被覆盖。
-
参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针。
◼ Size
所有图像内存的大小(以字节为单位)。
◼ BufCnt
子缓冲区数。在32位系统上为32位整数,在64位系统上为64位数字。双缓冲时,值必须为2。
◼ DmaIndex
已使用的Dma端口的逻辑号。与DMA端口关联的摄像机取决于applet。Silicon Software Runtime随附的所有采集Applet都具有DMA端口和摄像机端口之间的直接映射。这意味着DmaIndex 0与PORT A相关联,DmaIndex 1与PORT B相关联,依此类推。 -
返回值
返回一个指向分配帧内存/图像数据的指针。
NULL:发生错误。
- 可以使用Fg_FreeMemEx()释放已分配的内存。
- 发生错误时,使用Fg_getLastErrorDescription()来获取更多信息。
Fg_AllocMemEx
dma_mem *Fg_AllocMemEx(Fg_Struct *Fg, const size_t Size, const frameindex_t BufCnt);
-
说明
函数Fg_AllocMemEx()保留主内存的一个区域作为帧缓冲区,阻塞它并使其对用户可用。帧缓冲区被组织为一个环形缓冲区,它被细分为几个子缓冲区。只要不超过可配置帧缓冲区的最大大小,就可以分配最多256个不同的帧缓冲区。
获取的图像与包含在PC内存中的图像的子缓冲区之间的分配取决于获取模式。
-
参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针。
◼ Size
所有图像内存的大小(以字节为单位)。
◼ BufCnt
子缓冲区数。在32位系统上为32位整数,在64位系统上为64位数字。 -
返回值
返回的指针表示所有帧缓冲区的管理数据结构。
NULL:发生错误。
- 可以使用Fg_FreeMemEx()释放已分配的内存。
- 发生错误时,使用Fg_getLastErrorDescription()来获取更多信息。
Fg_FreeMem()
int Fg_FreeMem(Fg_Struct *Fg, const unsigned int DmaIndex);
-
说明
释放帧缓冲区。函数Fg_FreeMem()停止帧捕获器并释放之前使用Fg_AllocMem()分配的内存。
-
参数
◼ fg
指向帧抓取器结构Fg_Struct的指针。
◼ dmaindex
已使用的Dma端口的逻辑号。与DMA端口关联的摄像机取决于applet。Silicon Software Runtime随附的所有采集Applet都具有DMA端口和摄像机端口之间的直接映射。这意味着DmaIndex 0与PORT A相关联,DmaIndex 1与PORT B相关联,依此类推。 -
返回值
FG_OK:图像内存已成功释放。
FG_NOT_INIT:释放失败。帧抓取器没有正确初始化。
FG_STILL_ACTIVE:图像的传输仍然进行。在释放帧捕获缓冲区之前,必须停止传输。
Fg_FreeMemEx()
int Fg_FreeMemEx(Fg_Struct *Fg, dma_mem *mem);
-
说明
函数Fg_FreeMemEx()释放以前使用Fg_AllocMemEx()保留的内存。如果对内存的获取和访问仍然处于活动状态,则该函数无法释放内存区域,并返回一个错误消息。
-
参数
◼ Fg
指向帧抓取器结构Fg_Struct的指针。
◼ mem
用Fg_AllocMemEx()保留的内存区域的句柄。 -
返回值
开始/结束抓取图像
Fg_Acquire
int Fg_Acquire(Fg_Struct *Fg, const unsigned int DmaIndex, const frameindex_t PicCount);
-
说明
函数Fg_Acquire()开始连续抓取。启动后,将抓取确切数量的图像(PicCount)。
如果超时发生,抓取将被停止。
如果需要手动停止连续抓取(使用Fg_stopAcquire()显式停止抓取),则必须将最大图像数量设置为:GRAB_INFINITE。
当所有的缓冲区只能使用一次时,可以使用:GRAB_ALL_BUFFERS。这相当于传递缓冲区计数。在多DMA配置中,可以为每个DMA通道独立地启动和停止图像抓取。
-
参数
◼ Fg
帧抓取器
◼ DmaIndex
使用的摄像机端口的逻辑编号:camera port A = 0 and camera port B = 1。
◼ PicCount
要抓取的图像的最大数量,GRAB_INFINITE,表示无限抓取。 -
返回值
类型 说明 FG_OK 抓取已正确启动。(同步抓取时也能正确完成)。 FG_NOT_INIT 帧抓取器没有正确初始化。 FG_NO_VALID_DESIGN 没有加载有效的设计。 FG_INVALID_MEMORY 图像内存没有分配。 FG_MEMORY_IN_USE 图像内存已经被另一个DMA通道使用。 FG_NOT_ENOUGH_MEMORY 指定的图像参数分配的图像内存不足。 FG_ALREADY_STARTED 抓取已经开始,不能开始两次。 FG_INVALID_PARAMETER 设置无效参数。 - 抓取模式设置为#ACQ_STANDARD。图像内存用作环形缓冲区,所有子缓冲区将被循环覆盖。
- 即使没有图像数据存在,直到达到一定的超时时间,抓取过程仍继续运行。可以使用Fg_setParameterXXX()函数为每个抓取过程(由DMA通道标识)单独设置此超时。
Fg_AcquireEx
int Fg_AcquireEx(Fg_Struct *Fg, const unsigned int DmaIndex, const frameindex_t PicCount, const int nFlag, dma_mem *memHandle);
-
说明
函数Fg_AcquireEx开始连续抓取。启动后,将抓取确切数量的图像(PicCount)。如果超时发生,抓取将被停止。
如果需要手动停止连续抓取(使用Fg_stopAcquireEx()显式停止抓取),则必须将最大图像数量设置:GRAB_INFINITE。当所有的缓冲区只能使用一次时,可以使用:GRAB_ALL_BUFFERS。这相当于传递缓冲区计数。
在多DMA配置中,可以对每个DMA通道分别启动和停止图像抓取。
抓取模式由flag设置。可以在ACQ_STANDARD和ACQ_BLOCK之间进行选择。
- #ACQ_STANDARD:图像内存用作环形缓冲区,所有子缓冲区将被循环覆盖。
- #ACQ_BLOCK:获取的帧缓冲区只要被用户显式释放就会被阻塞。如果所有的子缓冲区都被阻塞,则获取的图像将存储在一个附加的可选缓冲区(DummyBuffer)中,该缓冲区是不可阻塞的。在这个抓取模型中,图像号和子缓冲区号之间没有唯一的分配。
-
参数
◼ Fg
帧抓取器
◼ DmaIndex
使用的摄像机端口的逻辑编号:camera port A = 0 and camera port B = 1。
◼ PicCount
要抓取的图像的最大数量,#GRAB_INFINITE,表示无限抓取。
◼ nFlag
设置抓取模式:#ACQ_STANDARD、 #ACQ_BLOCK
◼ memHandle
指向帧缓冲区句柄的指针。 -
返回值
类型 说明 FG_OK 抓取已正确启动。(同步抓取时也能正确完成)。 FG_NOT_INIT 帧抓取器没有正确初始化。 FG_INVALID_MEMORY 图像内存没有分配。 FG_MEMORY_IN_USE 图像内存已经被另一个DMA通道使用。 FG_NOT_ENOUGH_MEMORY 指定的图像参数分配的图像内存不足。 FG_ALREADY_STARTED 抓取已经开始,不能开始两次。 FG_INVALID_PARAMETER 设置无效参数。
Fg_stopAcquire
int Fg_stopAcquire(Fg_Struct *Fg, const unsigned int DmaIndex);
-
说明
停止抓帧。函数Fg_stopAcquire()停止使用Fg_Acquire()启动的正在运行的图像抓取。在双抓波配置中,每个端口可以分别停止。在一个单一的抓波配置中,只有活动端口。
函数Fg_stopAcquire()阻止异步获取图像,这意味着运行中的图像传输在任何情况下都不会完成。
-
参数
◼ Fg
帧抓取器
◼ DmaIndex
使用的摄像机端口的逻辑编号:camera port A = 0 and camera port B = 1。
◼ memHandle
指向帧缓冲区句柄的指针。
◼ nFlag
选择停止模式和超时(以秒为单位)(STOP_SYNC, STOP_ASYNC)。
使用STOP_SYNC时:超时由参数FG_STOP_TIMEOUT定义。 -
返回值
值 说明 FG_OK 传输已经成功完成。 FG_NOT_INIT 帧抓取器没有正确初始化。 FG_TRANSFER_NOT_ACTIVE 传输没有启动。 FG_INVALID_PARAMETER 设置无效参数。 FG_NOT_STOP 抓帧器无法停止。
Fg_stopAcquireEx
int Fg_stopAcquireEx(Fg_Struct *Fg, const unsigned int DmaIndex, dma_mem *memHandle, int nFlag);
-
说明
停止抓帧。函数Fg_stopAcquireEx()停止使用Fg_AquireEx()启动的正在运行的图像抓取。在双抓波配置中,每个端口可以分别停止。
函数Fg_stopAcquireEx()阻止图像的异步或同步获取。nFlag指示停止模式和超时时间(以秒为单位)。超时是最大时间,函数将在同步模式下等待,以停止获取。
-
参数
◼ Fg
帧抓取器
◼ DmaIndex
使用的摄像机端口的逻辑编号:camera port A = 0 and camera port B = 1。 -
返回值
值 说明 FG_OK 传输已经成功完成。 FG_NOT_INIT 帧抓取器没有正确初始化。 FG_TRANSFER_NOT_ACTIVE 传输没有启动。 FG_INVALID_PARAMETER 设置无效参数。
获取当前抓取的帧的编号
抓取编号为指定的PicNr的图像,抓取成功后返回当前抓取的帧的编号。
Fg_getLastPicNumberBlocking
frameindex_t Fg_getLastPicNumberBlocking(Fg_Struct *Fg, const frameindex_t PicNr, const unsigned int DmaIndex, const int Timeout);
-
说明
请求当前图像号(阻塞)。可以调用Fg_getLastPicNumberBlocking()请求最后一个完全传输的图像的编号。
与Fg_getLastPicNumber()相反,该函数将等待,直到成功地完成预选图像号的传输,或者经过最大时间。如果之前获得了图像编号,则函数立即返回。如果没有发生错误,第一个图像号的值将是1。
-
参数
◼ Fg
帧捕捉器。
◼ PicNr
请求的图片编号。
◼ DmaIndex
使用的摄像机端口逻辑编号, camera port A = 0 and camera port B = 1。
◼ Timeout
超时时间(秒)
◼ pMem
指向变量缓冲区的指针。 -
返回值
返回当前图像编号,从1开始。
FG_TIMEOUT_ERR:超时错误发生。
FG_INVALID_PARAMETER:函数的参数无效。
当处理极高的帧率时,函数的返回值可以大于预先选择的图像数。在这种情况下,分配足够的帧缓冲区是很重要的
Fg_getLastPicNumberBlockingEx
frameindex_t Fg_getLastPicNumberBlockingEx(Fg_Struct *Fg, const frameindex_t PicNr, const unsigned int DmaIndex, const int Timeout, dma_mem *pMem);
-
说明
请求当前图像编号(阻塞)。通过调用Fg_getLastPicNumberBlockingEx()请求最后一个完全传输的图像的编号。
与Fg_getLastPicNumberEx()相反,该函数将等待,直到成功地完成预选图像号的传输,或者经过最大时间。如果之前获得了图像编号,则函数立即返回。如果没有发生错误,第一个图像号的值将是1。
当处理极高的帧率时,函数的返回值可以大于预先选择的图像数。在这种情况下,分配足够的帧缓冲区是很重要的
-
参数
◼ Fg
帧捕捉器。
◼ PicNr
请求的图片编号。
◼ DmaIndex
使用的摄像机端口逻辑编号, camera port A = 0 and camera port B = 1。
◼ Timeout
超时时间(秒)
◼ pMem
指向变量缓冲区的指针。 -
返回值
返回当前图像编号,从1开始。
FG_TIMEOUT_ERR:超时错误发生。
FG_INVALID_PARAMETER:函数的参数无效。
Fg_getLastPicNumber
frameindex_t Fg_getLastPicNumber(Fg_Struct *Fg, const unsigned int DmaIndex);
-
说明
请求当前图像编号(非阻塞)。使用Fg_getLastPicNumber()的非阻塞调用可以请求最后一个完全传输的图像的编号。第一个完全传输的图像是图像1。图像编号0表示仍然没有传输完整的图像。
-
参数
◼ Fg
帧捕捉器。
◼ DmaIndex
使用的摄像机端口逻辑编号, camera port A = 0 and camera port B = 1。 -
返回值
返回最后一个完全传输的图像的编号,传输正在运行。
0:传输正在运行,还没有被完全传输的图像。
FG_TIMEOUT_ERR:超时发生。
FG_INVALID_PARAMETER:函数的参数无效。
Fg_getLastPicNumberEx
frameindex_t Fg_getLastPicNumberEx(Fg_Struct *Fg, const unsigned int DmaIndex, dma_mem *pMem);
-
说明
请求当前图像编号(非阻塞)。可以通过调用Fg_getLastPicNumberEx()请求最后一个完全传输的图像的数量。第一个完全传输的图像是图像1。图像编号0表示仍然没有传输完整的图像。
-
参数
◼ Fg
帧捕捉器。
◼ DmaIndex
使用的摄像机端口逻辑编号, camera port A = 0 and camera port B = 1。
◼ pMem
指向变量缓冲区的指针 -
返回值
返回最后一个完全传输的图像的编号,传输正在运行。
0:传输正在运行,还没有被完全传输的图像。
FG_TIMEOUT_ERR:超时发生。
FG_INVALID_PARAMETER:函数的参数无效。
指向当前图像位置的指针
Fg_getImagePtr
void *Fg_getImagePtr(Fg_Struct *Fg, const frameindex_t PicNr, const unsigned int DmaIndex);
- 说明
使用函数Fg_getImagePtr()创建一个指向帧缓冲区中的图像的指针。 - 参数
◼ Fg
帧捕捉器。
◼ PicNr
帧缓冲的编号或图片的编号。
◼ DmaIndex
使用的摄像机端口逻辑编号, camera port A = 0 and camera port B = 1。 - 返回值
返回指向当前图像位置的指针。
Fg_getImagePtrEx
void *Fg_getImagePtrEx(Fg_Struct *Fg, const frameindex_t PicNr, const unsigned int DmaIndex, dma_mem *pMem);
- 说明
使用函数Fg_getImagePtrEx()创建一个指向帧缓冲区中的图像的指针。 - 参数
◼ Fg
帧抓取器
◼ PicNr
帧缓冲的编号或图片的编号。
◼ DmaIndex
使用的摄像机端口逻辑编号, camera port A = 0 and camera port B = 1。
◼ pMem
指向缓冲区的指针 - 返回值
返回指向当前图像位置的指针。
SisoDisplay.h
关于帧的显示
CreateDisplay
int CreateDisplay(const unsigned int nDepth, const unsigned int nWidth, const unsigned int nHeight);
- 说明
函数CreateDisplay()创建一个显示窗口。它可以显示高达2GB大小的灰色和彩色图像。 - 参数
◼ nDepth
颜色深度b/w: 1bit
gray: 8bit, 16bit
color: 24bit, 48bit
Use the value 565 for 16Bit RGB 565
◼ nWidth
窗口宽度(以像素为单位)。
◼ nHeight
窗口的高度(以像素为单位)。 - 返回值
成功时返回显示的ID,如果出现错误则返回负值。
0 . .n:显示ID
FG_NOT_ENOUGH_MEM:内存不足
FG_INVALID_PARAMETER:深度无效
FG_INVALID_IMAGE_DIMENSIONS:图像大于2GB
SetBufferWidth
void SetBufferWidth(int nId, const unsigned int nWidth, const unsigned int nHeight);
- 说明
设置缓冲区宽度。
函数SetBufferWidth()配置帧缓冲区的大小。这样就可以显示一个比帧缓冲区小的窗口。 - 参数
◼ nId
显示图像的窗口Id。
◼ nWidth
窗口的宽度(以像素为单位)
◼ nHeight
窗口的高度(以像素为单位)
DrawBuffer
void DrawBuffer(int nId, const void *ulpBuf, const int nNr, const char *cpStr);
- 说明
画缓冲区。
函数DrawBuffer()显示一个图像。图像的当前指针将由函数Fg_getImagePtr()返回。 - 参数
◼ nId
创建窗口的id。
◼ ulpBuf
指向要显示帧的缓冲区的指针。
◼ nNr
图像的编号。
◼ cpStr
一个字符串,显示在windows栏中。
CloseDisplay
void CloseDisplay(int nId);
- 说明
关闭显示。
函数CloseDisplay()关闭窗口并释放分配的资源。 - 参数
◼ nID
显示的窗口ID。
SetDisplayDepth
int SetDisplayDepth(int nId, const unsigned int depth);
-
说明
设置显示深度。为Linux系统添加了SetDisplayDepth()。它支持用户特定的设置(在RGB 24位上使用32位)
-
参数
◼ nID
显示的窗口ID。
◼ depth
如果需要的话,深度32位。
实例
board_and_dll_chooser.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <fgrab_struct.h>
#include <fgrab_prototyp.h>
#include <fgrab_define.h>
#include <sisoboards.h>
//返回控制台输入的有效的数字
static int readIntFromStdin(char * buffer, const size_t len)
{
int readRet = 0;
memset(buffer, 0, len);
int inputIsInvalid = 0;
unsigned int i = 0;
for(i = 0; i < len; i++) {
readRet = read(0, buffer + i, 1);
if(readRet < 0) {
exit(readRet);
}
if(buffer[i] == '\r') {
readRet = read(0, buffer + i, 1);
if(readRet < 0) {
exit(readRet);
}
if(buffer[i] != '\n') {
exit(-1);
}
}
if(buffer[i] == '\n') {
break;
}
if(buffer[i] < '0' || buffer[i] > '9') {
inputIsInvalid = 1;
break;
}
if(i == len - 1 && '\n') {
inputIsInvalid = 1;
break;
}
}
if(inputIsInvalid) {
char ownBuff;
do {
readRet = read(0, &ownBuff, 1);
if(readRet < 0) {
exit(-1);
}
} while(ownBuff != '\n');
return -1;
}
if(i == 0) {
return -1;
}
return strtoul(buffer, NULL, 10);
}
// 获得系统中帧捕捉器的数量,即电脑连接的物理板子数量
static int getNrOfBoards()
{
int nrOfBoards = 0;
char buffer[256];
unsigned int buflen = 256;
buffer[0]= 0;
// availability : starting with RT 5.2
//NFO_NR_OF_BOARDS: get the number of frame grabbers in the system 获得帧捕捉器的数量
if (Fg_getSystemInformation(NULL,INFO_NR_OF_BOARDS,PROP_ID_VALUE,0,buffer, &buflen) == FG_OK){
nrOfBoards = atoi(buffer);
}
return nrOfBoards;
}
// 返回最终选择的有效的板子索引
static int selectBoardDialog()
{
int boardType;
int i = 0;
//假定最多连接的帧捕捉器数量=10
int maxNrOfboards = 10;// use a constant no. of boards to query, when evaluations versions minor to RT 5.2
//统计被找到的板子的数量
int nrOfBoardsFound = 0;
//真实获得连接到系统中的帧捕捉器的数量,即板子的数量
int nrOfBoardsPresent = getNrOfBoards();
//标记找到的最后一块板子的索引(从0找到maxNrOfboards)
int maxBoardIndex = -1;
for(i = 0; i < maxNrOfboards; i++) {
const char * boardName;
bool skipIndex = false;
//根据捕捉器的索引获取类型
boardType = Fg_getBoardType(i);
switch(boardType) {
case PN_MICROENABLE3I:
boardName = "MicroEnable III";
break;
case PN_MICROENABLE3IXXL:
boardName = "MicroEnable III XXL";
break;
case PN_MICROENABLE4AS1CL:
boardName = "MicroEnable IV AS1-CL";
break;
case PN_MICROENABLE4AD1CL:
boardName = "MicroEnable IV AD1-CL";
break;
case PN_MICROENABLE4VD1CL:
boardName = "MicroEnable IV VD1-CL";
break;
case PN_MICROENABLE4AD4CL:
boardName = "MicroEnable IV AD4-CL";
break;
case PN_MICROENABLE4VD4CL:
boardName = "MicroEnable IV VD4-CL";
break;
case PN_MICROENABLE4AQ4GE:
boardName = "MicroEnable IV AQ4-GE";
break;
case PN_MICROENABLE4VQ4GE:
boardName = "MicroEnable IV VQ4-GE";
break;
case PN_MICROENABLE5AQ8CXP4:
boardName = "MicroEnable V AQ8-CXP";
break;
case PN_MICROENABLE5VQ8CXP4:
boardName = "MicroEnable V VQ8-CXP";
break;
case PN_MICROENABLE5VD8CL:
boardName = "MicroEnable 5 VD8-CL";
break;
case PN_MICROENABLE5AD8CL:
boardName = "MicroEnable 5 AD8-CL";
break;
case PN_MICROENABLE5AQ8CXP6D:
boardName = "MicroEnable 5 AQ8-CXP6D";
break;
case PN_MICROENABLE5VQ8CXP6D:
boardName = "MicroEnable 5 VQ8-CXP6D";
break;
case PN_MICROENABLE5AD8CLHSF2:
boardName = "MicroEnable 5 AD8-CLHS-F2";
break;
default:
boardName = "Unknown / Unsupported Board";
skipIndex = true;
}
//查询到当前索引的板子,打印板子名和类型。
if (!skipIndex){
printf("Board ID %2u: %s (%x)\n", i, boardName, boardType);
//找到的板子数+1
nrOfBoardsFound++;
//找到的最后一块板子的索引等于当前索引值
maxBoardIndex = i;
}
//当找到的板子数大于等于查询到的连接到系统中板子的数量时,停止下次的循环
if (nrOfBoardsFound >= nrOfBoardsPresent){
break;// all boards are scanned
}
}
//当找到的板子小于0时:打印未找到板子
if(nrOfBoardsFound <= 0) {
printf("No Boards found!");
return -1;
}
//打印找到板子的范围为0--找到的最后一块板子的索引,即连接到系统上的帧捕捉器数量范围
printf("\n=====================================\n\nPlease choose a board[0-%u]: ", maxBoardIndex);
fflush(stdout);
//存放从控制台输入的所选择的板子索引
int userInput = -1;
//当输入的数据大于找到的最后一块板子的索引时,重复输入的数据
do {
//输入缓冲区
char inputBuffer[512];
// 获取从控制台输入的int数据
userInput = readIntFromStdin(inputBuffer, sizeof(inputBuffer));
//当输入的数据大于找到的最后一块板子的索引时,说明无效输入,不在范围内。提示重新输入
if (userInput > maxBoardIndex) {
printf("Invalid selection, retry[0-%u]: ", maxBoardIndex);
}
} while (userInput > maxBoardIndex);
//返回最终选择的有效的板子索引
return userInput;
}
static const char * selectDllSingleList(const char **dlls)
{
int i = 0;
for(i = 0; strlen(dlls[i]) > 0; i++) {
printf("%d: %s \n", i, dlls[i]);
}
if(i == 1) {
printf("\n No DLLs available for this board. \n");
return "";
}
printf("\nChoose a dll by entering a number between 0 and %d:", i-1);
int userInput = -1;
do {
char inputBuffer[512];
userInput = readIntFromStdin(inputBuffer, sizeof(inputBuffer));
if (userInput > i-1) {
printf("Invalid selection, retry[0-%u]: ", i-1);
}
} while (userInput >= i);
return dlls[userInput];
}
static const char * selectDll(unsigned int boardType, const char **me3dlls, const char **me3xxldlls,
const char **me4dualdlls, const char **me4singledlls, const char **me4dualdllsX4, const char **me4GEVdllsX4)
{
switch(boardType) {
case PN_MICROENABLE3I:
return selectDllSingleList(me3dlls);
case PN_MICROENABLE3IXXL:
return selectDllSingleList(me3xxldlls);
case PN_MICROENABLE4AD1CL:
case PN_MICROENABLE4VD1CL:
return selectDllSingleList(me4dualdlls);
case PN_MICROENABLE4AD4CL:
case PN_MICROENABLE4VD4CL:
return selectDllSingleList(me4dualdllsX4);
case PN_MICROENABLE4AS1CL:
return selectDllSingleList(me4singledlls);
case PN_MICROENABLE4AQ4GE:
case PN_MICROENABLE4VQ4GE:
return selectDllSingleList(me4GEVdllsX4);
default:
return NULL;
}
}
// returns the Board index for a certain type of Silicon Software frame grabber
// if multiple boards of the given board type are present or no board type is
// preselected, a user selection is showed
// returns the index of the board, which can be used at Fg_Init() functions of the
// Silicon Software framegabber SDK
// If the return value is < 0, no board is selected and / or found
int GetBoardIndex( int SiSoBoardType)
{
int result = -1;
int maxNrOfboards = 10;
int boardIndexFound = -1;
int boardTypesCount = 0;
for(int i = 0; i < maxNrOfboards; i++) {
int boardType = Fg_getBoardType(i);
if (SiSoBoardType > 0){
if (boardType == SiSoBoardType){
boardIndexFound = i;
boardTypesCount++;
}
}
}
if ((boardTypesCount == 1) && (boardIndexFound >= 0)){
// return the only one
result = boardIndexFound;
}
else{
// show the dialog
result = selectBoardDialog();
}
return result;
}
test.cpp
#pragma warning(disable:4996)
#include <stdio.h>
#include "board_and_dll_chooser.h"
#include <fgrab_struct.h>
#include <fgrab_prototyp.h>
#include <fgrab_define.h>
#include <SisoDisplay.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[], char* envp[])
{
Fg_Struct* fg = NULL;
//从控制台获取——用户将要初始化的有效帧捕获器的索引
int boardNr = selectBoardDialog();
//使用的DMA存储器存取通道的逻辑编号
//camPort使用的摄像机端口的逻辑编号
int camPort = PORT_A;
//捕捉的图片数量
frameindex_t nrOfPicturesToGrab = 1000;
//
frameindex_t nbBuffers = 4;
//图像宽和高
unsigned int width = 512;
unsigned int height = 512;
int samplePerPixel = 1;
size_t bytePerSample = 1;
//查询所选择的板子的型号,通过型号,获取applet
const char* applet;
switch (Fg_getBoardType(boardNr)) {
case PN_MICROENABLE4AS1CL:
applet = "SingleAreaGray16";
break;
case PN_MICROENABLE4AD1CL:
case PN_MICROENABLE4AD4CL:
case PN_MICROENABLE4VD1CL:
case PN_MICROENABLE4VD4CL:
applet = "DualAreaGray16";
break;
case PN_MICROENABLE4AQ4GE:
case PN_MICROENABLE4VQ4GE:
applet = "QuadAreaGray16";
break;
case PN_MICROENABLE3I:
applet = "DualAreaGray";
break;
case PN_MICROENABLE3IXXL:
applet = "DualAreaGray12XXL";
break;
default:
applet = "DualAreaGray16";
break;
}
/*
初始化
初始化Applet为FileName,编号为boardNr的板子。
fg: 返回初始化的板子的数据结构的指针。
*/
if ((fg = Fg_Init(applet, boardNr)) == NULL) {
fprintf(stderr, "error in Fg_Init: %s\n", Fg_getLastErrorDescription(NULL));
return FG_ERROR;
}
/*
创建显示窗口并设置窗口缓冲区
返回显示窗口的ID标识号。
设置窗口的显示大小。
*/
int dispId0 = CreateDisplay((unsigned int)(8 * bytePerSample * samplePerPixel), width, height);
SetBufferWidth(dispId0, width, height);
/*
计算缓冲区大小并分配内存
*/
size_t totalBufferSize = (size_t)width * height * samplePerPixel * bytePerSample * nbBuffers;
dma_mem* memHandle = Fg_AllocMemEx(fg, totalBufferSize, nbBuffers);
//分配内存出错,则打印原因
if (memHandle == NULL) {
fprintf(stderr, "error in Fg_AllocMemEx: %s\n", Fg_getLastErrorDescription(fg));
//关闭显示窗口
CloseDisplay(dispId0);
//释放捕捉器
Fg_FreeGrabber(fg);
return FG_ERROR;
}
/*Image width of the acquisition window.*/
//设置输出图像的宽度,在采集过程中不能改变
if (Fg_setParameter(fg, FG_WIDTH, &width, camPort) < 0) {
fprintf(stderr, "Fg_setParameter(FG_WIDTH) failed: %s\n", Fg_getLastErrorDescription(fg));
//释放以前使用Fg_AllocMemEx()保留的内存。
Fg_FreeMemEx(fg, memHandle);
CloseDisplay(dispId0);
Fg_FreeGrabber(fg);
return FG_ERROR;
}
//设置输出图像的高度,在采集过程中不能改变
/*Image height of the acquisition window.*/
if (Fg_setParameter(fg, FG_HEIGHT, &height, camPort) < 0) {
fprintf(stderr, "Fg_setParameter(FG_HEIGHT) failed: %s\n", Fg_getLastErrorDescription(fg));
Fg_FreeMemEx(fg, memHandle);
CloseDisplay(dispId0);
Fg_FreeGrabber(fg);
return FG_ERROR;
}
//设置输出图像对齐方式,左对齐
int bitAlignment = FG_LEFT_ALIGNED;
if (Fg_setParameter(fg, FG_BITALIGNMENT, &bitAlignment, camPort) < 0) {
fprintf(stderr, "Fg_setParameter(FG_BITALIGNMENT) failed: %s\n", Fg_getLastErrorDescription(fg));
Fg_FreeMemEx(fg, memHandle);
CloseDisplay(dispId0);
Fg_FreeGrabber(fg);
return FG_ERROR;
}
//开始抓取
//camPort: 使用的摄像机端口的逻辑编号
//nrOfPicturesToGrab: 要抓取的图像的最大数量
//ACQ_STANDARD: 图像内存用作环形缓冲区,所有子缓冲区将被循环覆盖。
//memHandle:指向帧缓冲区句柄的指针。
if ((Fg_AcquireEx(fg, camPort, nrOfPicturesToGrab, ACQ_STANDARD, memHandle)) < 0) {
fprintf(stderr, "Fg_AcquireEx() failed: %s\n", Fg_getLastErrorDescription(fg));
Fg_FreeMemEx(fg, memHandle);
CloseDisplay(dispId0);
Fg_FreeGrabber(fg);
return FG_ERROR;
}
//最后一帧
frameindex_t last_pic_nr = 0;
//当前抓取的帧数
frameindex_t cur_pic_nr;
//超时:4s
int timeout = 4;
//抓取编号为指定的PicNr的图像,抓取成功后返回当前抓取的帧的编号。
// 抓取当前帧: 当前帧小于抓取的总数
//last_pic_nr + 1:请求的图片编号。
//timeout:超时时间(秒)
//memHandle:指向变量缓冲区的指针
//返回当前帧编号,从1开始。
while ((cur_pic_nr = Fg_getLastPicNumberBlockingEx(fg, last_pic_nr + 1, camPort, timeout, memHandle)) < nrOfPicturesToGrab) {
cout << "当前帧数:" << cur_pic_nr << endl;
//失败
if (cur_pic_nr < 0) {
fprintf(stderr, "Fg_getLastPicNumberBlockingEx(%li) failed: %s\n", last_pic_nr + 1, Fg_getLastErrorDescription(fg));
//停止抓取
Fg_stopAcquire(fg, camPort);
//释放内存
Fg_FreeMemEx(fg, memHandle);
//关闭显示窗口
CloseDisplay(dispId0);
//释放帧捕捉器
Fg_FreeGrabber(fg);
return FG_ERROR;
}
//把当前抓取的图像编号+1:设置为下次要抓取的图像编号
last_pic_nr = cur_pic_nr;
//函数DrawBuffer()显示一个图像。图像的当前指针将由函数Fg_getImagePtr()返回。
// ispId0: 显示图像的窗口Id。
// Fg_getImagePtrEx(fg, last_pic_nr, camPort, memHandle): 指向要显示帧的缓冲区的指针。
// static_cast<int>(last_pic_nr): 图像的编号。
DrawBuffer(dispId0, Fg_getImagePtrEx(fg, last_pic_nr, camPort, memHandle), static_cast<int>(last_pic_nr), "");
}
//关闭显示窗口
CloseDisplay(dispId0);
//停止抓帧
Fg_stopAcquire(fg, camPort);
//释放内存
Fg_FreeMemEx(fg, memHandle);
//释放帧捕捉器
Fg_FreeGrabber(fg);
return FG_OK;
}
总结自:软件开发套件(SDK)-手册