GenIcam标准(四)
2.8.可用的节点类型
本章对每个可用的节点类型提供一个概要的描述,包括其功能、用途以及最关心的参数。另外,对于每个节点在GenICam标准的XML格式文件中的layout,会有一个正式的说明。这个格式文件可以用大多数XML编辑器来读,并且提供了语法检查和上下文相关的帮助,可以大大简化创建相机描述文件的工作。
本文档中的GenApiSchema_Version_1_0.xsd指的是GenApi schema version 1.0。注意,随着标准版本的增长,可能会加入新的节点类型,元素和属性,不过,如果可能的话会保持向下兼容。
2.8.1.Node
Node类型包含其它节点类型共通的元素和属性。一个孤立的Node类型没什么用处,但是可以用于测试。下面是一个例子:
<Node Name="Gain" NameSpace="Standard">
<Extension>
<MyElement>Something vendor specific</MyElement>
</Extension>
<ToolTip>The amplitication of the camera</ToolTip>
<Description>A more elborated description</Description>
<DisplayName>Gain</DisplayName>
<Visibility>Expert</Visibility>
<EventID>12fc</EventID>
<pIsImplemented>SomeNode1</pIsImplemented>
<pIsAvailable>SomeNode2</pIsAvailable>
<pIsLocked>SomeNode3</pIsLocked>
<ImposedAccessMode>RO</ImposedAccessMode>
<pAlias>SomeNode4</pAlias>
每个节点都有一个Name属性。Name在相机描述文件内必须是唯一的。Name可以是字符[A-Z a-z 0-9]的组合。格式也允许使用下划线,但是相机描述文件设计器不能使用下划线,因为参考实现把下划线用在自动生成的名称上。
每个Name存在于一个命名空间(name space)中。通过节点的NameSpace属性和外框元素<RegisterDescription>(参见2.7章)的StandardNameSpace属性的结合来标识命名空间。NameSpace属性有两个可能的值:Custom和Standard。如果是Custom,可以用任何名字,只要在相机描述文件内是唯一的就行了。如果是Standard,则必须用标准属性名列表(standard feature name lists)中提供的名字,列表对于下列相机类型可用(参见2.9章):
l IIDC: 符合1394 IIDC标准(也叫DCAM标准)的相机
l GEV: 符合GigE Vision标准的相机
l CL: 符合Camera Link标准的相机
l None: 未用任何标准
可以用一个<Extension>元素来把自定义的数据加到相机描述文件中。<Extension>元素内的所有元素都被忽略。
<ToolTip>元素给出了节点的一个短的说明。在由相机描述文件自动生成的参考文档中,也可以用这个元素作一个概要说明。
<Description>元素给出节点的更详细地说明。在由相机描述文件自动生成的参考文档中,也可以用这个元素作一个长的说明。
<DisplayName>元素让你定义属性的说明,可用来代替Name。
<Visibility>元素定义了要访问这个属性所需的用户级别。可能的级别有:Beginner、Expert、Guru和Invisible。最后一个用来让一个属性在API中可见,但在GUI中不可见(参见第2.8.2章)。
<EventID>元素用来分发异步事件。一台相机可能发送一个事件包,以表示相机上一个或多个数据项的值发生了改变。GenICam处理这个事件的方法是令数据项相应的节点无效。节点可以通过EventID找到,EventID是一个16进制数值,和事件包一起由相机发过来。每个节点可以有一个EventID元素(可选)。
<pIsImplemented>、<pIsAvaliable>和<pIsLocked>元素包含实现一个IInteger接口的节点的名称。如果提供这些元素,它们会影响节点的访问模式,如第2.5章所述。
<ImposedAccessMode>元素可用来减少访问模式。
<pAlias>指向用不同的方式实现相同属性的另一个节点。这个属性主要用在GUI:如果不是所有的成员都显示的话,一个Category可以用它的别名代替;如果一个整数和一个浮点数节点都表示一个属性的正的原始数值,则可以互为别名。
2.8.2.Category
Category节点用来组织要提供给用户的属性,它实现ICategory接口并继承所有的Node元素。它也提供一组指向包含在category中的属性的<pFeature>元素。Category可以包含别的Category,从而形成一棵任意深度的树。
有一个特殊的Category节点,带标准的名字Root(脚注:属性ICategory::Root在所有标准命名空间中定义),它是Category树的根。用户可能想从这里开始浏览相机的属性。下面的例子创建如图12所示的节点图。
<Category Name="Root" NameSpace=”Standard” >
<pFeature>ScalarFeatures</pFeature>
<pFeature>Trigger</pFeature>
</Category>
<Category Name="ScalarFeatures" >
<pFeature>Shutter</pFeature>
<pFeature>Gain</pFeature>
<pFeature>Offset</pFeature>
<pFeature>WhiteBalance</pFeature>
</Category>
<Category Name="WhiteBalance" >
<pFeature>RedGain</pFeature>
<pFeature>BlueGain</pFeature>
</Category>
<Category Name="Trigger" >
<pFeature>TriggerMode</pFeature>
<pFeature>TriggerPolarity</pFeature>
</Category>
注意,通过浏览目录树(category tree)来访问节点的用户可能只想看Category节点之下第一层的属性节点(features nodes)。图中更深的节点叫做实现节点(implementation nodes),只能通过名称或一种特殊的浏览模式得到,实现程序可能会提供这种浏览模式用于调试目的。要注意,在新发布的相机描述文件中,实现节点的名称和layout可能会发生变化,即使制造商声明它是向下兼容的(参见第2.7.3章)。
(图 略)
Figure 12 A tree of categories
2.8.3.Register
Register节点映射到相机的寄存器空间中一个连续的字节数组。Register节点实现IRegister接口,并从Node节点继承元素和属性。同时也向所有特殊的寄存器访问节点,例如IntReg,StringRet等等提供继承的元素。当然,Register节点也可以实例化自身,以访问原始的二进制数据。下面是一个简单的例子:
<Register Name="SensorTemperature">
<Address>0xff00</Address>
<Length>4</Length>
<AccessMode>RO</AccessMode>
<pPort>Device</pPort>
<Cachable>No</Cachable>
<PollingTime>10000</PollingTime>
</Register>
这里例子提供了相机传感器的温度。温度可以随时变化,所以是不能放入缓存的。如果显示的话,应该每10.000毫秒更新一次。
<Address>元素给出了寄存器在相机寄存器空间中的地址。
<Length>元素给出了寄存器的长度,单位是字节。
<AccessMode>元素可以取值RW (read/write)、RO (read only)或WO(write only),表示访问属性。
<pPort>元素包含一个Port节点的名称,通过这个端口可以访问相机的寄存器空间(详见2.8.15)。
<Cacheable>元素可以取值No(注:实际上应该是NoCache)、WriteThrough和WriteAround。其中WriteThrough意味着写到相机里的值也写入缓存;WriteAround的意思是只读这个值并写入缓存。我们举一个IFloat::Gain节点的例子来理解后一个动作,用户可以把任何值写入这个节点,但是再把这个值读回来的时候,会得到一个相机调整之后的值,相机调整这个值的目的是让内部的模数转换部分能够使用。注意,对任何实现来说,缓存都是一个可选的属性。
<PollingTime>元素表示推荐的读一个不能缓存的属性的polling时间间隔[单位ms], 注意,对任何实现来说,polling是一个可选的属性,polling时间仅仅是个暗示。
一个寄存器可以有多个<Address>、<pAddress>和 / 或<IntSwissKnife>类型的入口,而不是单个<Address>入口,这些入口的值合起来,产生寄存器节点的地址。
<pAddress>元素指向实现一个IInteger接口的节点,提供最终地址的一部分。
可用<IntSwissKnife>元素来把多个源计算生成地址的一部分(详见2.8.12)。
<pIndex Offset=”12”>元素指向实现一个IInteger接口的节点,提供一个index。这个元素有一个属性Offset。这个index和Offset要加到地址上。
<pInvalidator>元素包含一个节点的名称。当发生变化的时候,会令该节点的内容无效,如2.6章所述。
下面的例子显示了使用间接寻址机制的方法(同时参见图13)。
<Integer Name="BaseAddress">
<Value>0xff00</Value>
</Integer>
<IntReg Name="Gain">
<Address>0x04</Address>
<pAddress>BaseAddress</pAddress>
<Length>4</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<Sign>Unsigned</Sign>
<Endianess>LittleEndian</Endianess>
</IntReg>
<IntReg Name="Offset">
<Address>0x08</Address>
<pAddress>BaseAddress</pAddress>
<Length>4</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<Sign>Unsigned</Sign>
<Endianess>LittleEndian</Endianess>
</IntReg>
用一个C/C++结构体来模拟这个例子:
struct { // BaseAddress 0xff00
uint32_t Reserved;
uint32_t Gain; // Offset 0x04
uint32_t Offset; // Offset 0x08
};
结构体的基地址从一个叫BaseAddress的常量整数节点得到,本节点用一个<pAddress>元素和它关联。结构体的每个元素(Gain和Offset)都有一个偏移地址,可以用一个<Address>元素把基地址和偏移地址相加。
(图 略)
Figure 13 Indirect addressing: mapping a C/C++ struct
注意,对于1394 DCAM兼容相机来说,这一机制使用非常频繁。这类相机的整个标准寄存器都有一个共通基地址,运行时必须要通过IEEE 1212配置ROM结构来得到(参见ConfRom节点类型)。
2.8.4.数组和选择器
前一节所述的间接寻址也用于访问数组。下面的例子显示了这样做的方法(同时参见图14):
<Integer Name="LUTIndex">
<Value>0</Value>
<Min>0</Min>
<Max>255</Max>
<pSelected>LUTEntry</pSelected>
</Integer>
<IntReg Name="LUTEntry">
<IntSwissKnife Name="LUTEntryAddress">
<pVariable Name="INDEX">LUTIndex</pVariable>
<Formula>0xff00 + INDEX * 4</Formula>
</IntSwissKnife>
<Length>4</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<Sign>Unsigned</Sign>
<Endianess>LittleEndian</Endianess>
</IntReg>
一个LUT入口元素可用作LUT内的指针。这个元素的地址要通过一个内嵌的<IntSwissKnife>元素来计算,计算公式为:BaseAddress + LUTIndex × sizeof (LUTEntry)。LUTIndex是一个“浮动的”整数节点,没有联接到相机,相反,它从<Value>开始,可以被用户在<Min>和<Max>的范围内改变。
(图 略)
Figure 14 Accessing a LUT array
之所以可以用LUTIndex来选择一个特定的LUTEntry,是因为LUTIndex节点有一个 <pSelected>元素。实现IInteger或IEnumeration接口的节点可以有任意数目的pSelected入口,这表明,基于选择器节点(selector node)的值,被选择的节点(selected nodes)会表现出不同的值。关于一个节点是否是选择器,以及哪些是被选择的节点的信息,可以用ISelector接口得到,这个接口有对应的方法IsSelector和GetSelectedFeatures。例如,用这个接口,GUI可以显示一个LUTEntries的列表,因为它知道如果从min到max运行LUTIndex(选择器),就可以从LUTEntry(被选择)得到一组不同的值。
注意,利用多个索引,选择器和间接寻址方法可用来访问多维数组(multidimensional arrays)。
2.8.5.Integer, IntReg, MaskedIntReg
IInteger接口提供访问有符号的64位整型变量的方法,这个变量有一个受Minimum、Maximum和Increment参数制约的Value,公式为:Value = Minimum+ i × Increment,并且有

IntReg节点映射到按字节对齐的整数寄存器。它从Register节点继承元素和属性,下面是映射到一个双字节无符号整数的一个例子。注意,这个变量有如下的约束参数:Minimum = 0,Maximum = 65535,Increment = 1。
<IntReg Name="Gain">
<Address>0x1234</Address>
<Length>2</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<Sign>Unsigned</Sign>
<Endianess>BigEndian</Endianess>
</IntReg>
<Sign>元素可以取值Singed或Unsigned。注意,无符号的int64不可用。
<Endianess>元素可以取值LittleEndian或BigEndian,表示的是以传输层的观点看到的设备的字节序。传输层必须尽量不去改变这个字节序。实现程序必须知道自己是运行在little-endian还是big-endian的机器上。
有时候一组整数不是按字节对齐的,但是合并在一个寄存器内。在这种情况下,可以使用MaskedIntReg,它从Register节点继承元素和属性。下面的XML代码所表示的例子中,一个12位整数被封装在一个双字节寄存器。<LSB>和<MSB>元素分别表示最低有效位和最高有效位。
<MaskedIntReg Name="Offset">
<Address>0x2345</Address>
<Length>2</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<LSB>11</LSB>
<MSB>0</MSB>
<Sign>Unsigned</Sign>
<Endianess>BigEndian</Endianess>
</MaskedIntReg>
对于只需要一位的情况——对于存在性查询很常见——你可以用一个<Bit>入口,来取代<LSB>和<MSB>元素。
<MaskedIntReg Name="OffsetInq">
<Address>0x2345</Address>
<Length>2</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<Bit>15</Bit>
<Sign>Unsigned</Sign>
<Endianess>BigEndian</Endianess>
</MaskedIntReg>
一个32位整数的big-endian和little-endian字节序的区别如下所示:
Little-Endian: MSB ... LSB
31 ... 0
Big-Endian: MSB ... LSB
0 ... 31
LSB是对应20的位。注意,对于big-endian。表达式MSB ≤ LSB总是true;而对little-endian则相反,是LSB ≤ MSB。
Integer节点类型用来合并来自不同源的Value、Minimum、Maximum和Increment参数。它从Node节点继承元素和属性。这些限定的参数,既可以是由<Min>、<Max>和<Inc>元素给出的常量,也可以是通过<pMin>、<pMax>和<pInc>元素指向别的IInteger节点的指针。
通常从另一个节点来的值用<pValue>元素。另外,在一个<Value>元素内可以给定一个常量。在这种情况下,节点是一个“浮动的”变量,用户可以在允许的范围内设置任何值,给定的常量就是开始的值。下面的Index节点是一个典型的例子,可以给它赋值0,2,4,…,254:
<Integer Name="Index">
<Value>0</Value>
<Min>0</Min>
<Max>255</Max>
<Inc>2</Inc>
</Integer>
<Representation>元素提示显示数字的方法,如果这个元素是Linear或Logarithmic,则应该实现一个有适当动作的滑块(slider);如果是Boolean,应该用复选框(checkbox);PureNumber意味着要用一个只显示10进制数字的编辑框;HexNumber的话用一个显示16进制数字的编辑框。
Integer、IntReg和MaskedInt节点也可以有一个<pSelected>元素。参见2.8.4。
2.8.6.StructReg
常用MaskedInt节点来从寄存器取得一段位域。如果每一位都用一个完整的MaskedInt入口,相机描述文件内将有很多不必要的重复数据,因为对于不同的MaskedInt入口,它们大多数的元素是相同的,例如<pPort>元素、<Endianess>元素等等。
为克服这个缺点,引入了StructReg节点,下面是一个例子:
<StructReg Comment="VFormat7InqReg">
<ToolTip>Inquiry register for video format 7 color codes</ToolTip>
<Address>0x14</Address>
<pAddress>VFormat7ModeCsrBase</pAddress>
<Length>4</Length>
<AccessMode>RO</AccessMode>
<pPort>Device</pPort>
<Endianess>BigEndian</Endianess>
<StructEntry Name="VFormat7Mono8InqReg">
<ToolTip>Inquiry for ColorCode Mono8</ToolTip>
<Bit>31</Bit>
</StructEntry>
<StructEntry Name="VFormat7YUV422InqReg">
<ToolTip>Inquiry for ColorCode YUV8 422</ToolTip>
<Bit>29</Bit>
</StructEntry>
</StructEntry>
<StructEntry Name="VFormat7Raw8InqReg">
<Bit>24</Bit>
</StructEntry>
</StructReg>
StructReg拥有和MaskedInt相同的元素。另外它还有一个或多个<StructEntry>元素,可用来再包含和MaskedInt一样的元素。预处理器用一组MaskedInt节点代替StructReg节点:根据每个<StructEntry>元素创建一个MaskedInt节点,这个MaskedInt节点从StructEntry元素取得Name属性、所有的子元素,加上未在<StructEntry>元素中出现的StructReg节点的所有元素。因此,根据上面的例子生成的MaskedInt节点看起来向这个样子。
<MaskedInt Name="VFormat7Mono8InqReg ">
<Address>0x14</Address>
<pAddress>VFormat7ModeCsrBase</pAddress>
<Length>4</Length>
<AccessMode>RO</AccessMode>
<pPort>Device</pPort>
<Endianess>BigEndian</Endianess>
<ToolTip>Inquiry for ColorCode Mono8</ToolTip>
<Bit>31</Bit>
</MaskedInt>
注意,<ToolTip>元素是从<StructEntry>而不是<StructReg>得到的。与之相对,名叫VFormat7Raw8InqReg的入口要从<StructReg>继承<ToolTip>元素,因为它没有自己的。<StructReg>有一个Comment属性用于描述。
2.8.7.Boolean
Boolean节点把<OnValue>元素的整数值映射为true,把<OffValue>的值映射为false。Boolean节点实现IBoolean接口,并从Node节点继承元素和属性。下面的例子显示了为一个Trigger节点使用这个功能的方法,在GUI上,这个节点可表示为一个复选框。
<Boolean Name="Trigger">
<pValue>TriggerReg</pValue>
<OnValue>1</OnValue>
<OffValue>0</OffValue>
</Boolean>
<IntReg Name="TriggerReg">
<Address>0x6789</Address>
<Length>1</Length>
<AccessMode>RW</AccessMode>
<pPort>Device</pPort>
<Sign>Unsigned</Sign>
<Endianess>BigEndian</Endianess>
</IntReg>
2.8.8.Command
Icommand接口让用户提交一个命令,方法是调用Execute,然后调用IsDone来判断执行是否完成。
相应的Command节点继承Node节点的元素和属性。
另外,它有一个CommandValue元素,这个元素有一个整型常量,这个常量要写入一个由pValue元素指向的节点,写入就是提交这条命令。IsDone读返回的值并返回false,直到返回的值等于命令的值。为了可以用一个浮动的Command节点来代替pValue元素,也允许一个Value元素。或者,也可以从pCommandValue得到命令值。提供一个<PollingTime>入口以便处理自动清除的命令。
2.8.9.Float, FloatReg
Ifloat接口的定义和前面所说的IInteger很相似。它有一个由Minimum和Maximum参数限定的Value,但与整数不同的是,它没有increment。另外,Ifloat提供一个Unit,这仅仅是个用来显示用途的字符串。
建立Float节点的方法和Integer类似,它有<Value>、<Min>、<Max>或<pValue>、<pMin>、<pMax>。另外,它可以有一个<Representation>元素,这个元素可以取值Linear和Logarithmic,还有一个<Unit>元素,它有一个字符串。下面是一个例子:
<Float Name="Exposure">
<pValue>ExposureReg</pValue>
<Min>0.02</Min>
<Max>10.0</Max>
<Unit>ms</Unit>
</Float>
可以用FloatReg从按字节对齐的寄存器中取出一个浮点值。FloatReg从Register节点继承元素和属性。它还有一个<Endianess>元素。Length可以是4个字节(单精度浮点)或8个字节(双精度浮点),数字格式必须符合IEEE standard 754-1985。
GenIcam标准(四)的更多相关文章
- GenIcam标准(二)
2 GenApi模块 – 配置相机 2.1. 简介 GenApi模块解决如何去配置相机的问题.主要的思路是,让相机生产厂商为他们的相机提供机器可以识别的产品说明.这些相机描述文件(camera ...
- GenIcam标准(一)
1.概述 如今的数码摄相机包含了很多的功能,而不仅仅是采集图像.对于机器视觉相机来说,处理图像并把结果附加到图像数据流上,控制附加的硬件,代替应用程序作实时的处理等都是很平常的事情.这也导致了相机的编 ...
- GenIcam标准(三)
2.6. 缓存 如果某个实现对每个写操作支持范围.实现和可用状态的检查,通常会触发一系列对相机的读操作.大多数用于有效性检查的数值很少或不会发生变化,所以可以放入缓存.相机描述文件包含所有必需的定义以 ...
- GenIcam标准介绍
GenICam TM的目标是为各种相机和设备提供通用编程接口.无论他们使用什么接口技术(GigE Vision,USB3 Vision,CoaXPress,Camera Link HS,Camera ...
- GenIcam标准(五)
2.8.10.Enumeration, EnumEntry Enumeration节点把一个名称(name)映射到一个索引值(index value),并实现Ienumeration接口.Enumer ...
- GenIcam标准(六)
2.9.可用的接口 本章用伪代码列出在2.3章介绍过的最重要的接口.对每个接口,实际的实现可以提供更多的方法,例如,除了SetValue(value)方法,还可以用直接映射到SetValue()的方式 ...
- GenIcam标准关键词整理
1.<?xml> 版本信息和编码方式 IntSwissKnife 需计算和判断的节点 MaskedIntReg 需查询的节点 2.<RegisterDescription> 寄 ...
- 机器视觉必知-GenICam相机通用接口标准
机器视觉必知-GenICam相机通用接口标准 GenICam(相机通用接口): 一种通用软件接口 通用相机接口标准 目前机器视觉行业所使用的相机几乎均以相同方式来进行配置,即:---通过在注册表中的读 ...
- jQuery dataTables四种数据来源[转]
2019独角兽企业重金招聘Python工程师标准>>> 四种数据来源 对于 dataTables 来说,支持四种表格数据来源. 最为基本的就是来源于网页,网页被浏览器解析为 DOM ...
随机推荐
- 51nod 1301 集合异或和(DP)
因为当\(A<B\)时,会存在在二进制下的一位,满足这一位B的这一位是\(1\),\(A\)的这一位是\(0\). 我们枚举最大的这一位.设为\(x\)吧. 设计状态.\(dp[i][j][1/ ...
- QT_圆_直线_三角t
MyImgTest.h: #ifndef MYIMGTEST_H#define MYIMGTEST_H #include <QWidget> class MyImgTest : publi ...
- django-7-django模型系统
<<<常用的模型字段类型>>>https://docs.djangoproject.com/en/2.1/ref/models/fields/#field-type ...
- 2019-03-28 Python SQL 的注释
SQL Server 多行注释 : ctrl + k + c SQL Server 单行注释: -- Python 单行注释:# Python多行注释:''' '''
- PL/SQL基本语法
*2.PL/SQL基本语法 1)匿名块 一段不能在数据库存储的PL/SQL. 基本结构如下: DECLARE //变量的声明定义区域(可省略) BEGIN //业务处理 ...
- jquery简直是太酷炫强大了
链接地址:http://www.yyyweb.com/350.html Web 开发中很实用的10个效果[源码下载] 小鱼 发布于 3年前 (2014-07-15) 分类:前端开发 阅读(303741 ...
- UVA 436 - Arbitrage (II)(floyd)
UVA 436 - Arbitrage (II) 题目链接 题意:给定一些国家货币的汇率.问是否能通过不断换货币使钱得到增长 思路:floyd,完事后推断一下有没有连到自己能大于1的情况 代码: #i ...
- 剪切具有CornerRadius的RectangleGeometry(可能在Ripple中用到)
剪切具有CornerRadius的RectangleGeometry(可能在Ripple中用到) 1.新建Converter public class BorderClipConverter : IM ...
- Android之使用weight属性实现控件的按比例分配空间
从今天開始,把看书时候的知识点整理成博客, 这个比較简单,预计有经验的都用过,weight属性 在做Android布局的时候,常常遇到须要几个控件按比例分配空间的情况 比方下图效果 在底部设置两个bu ...
- bzoj4868: [Shoi2017]期末考试(三分法)
4868: [Shoi2017]期末考试 题目:传送门 题解: Get到一个新姿势...三分法 一开始百度百科的时候下了一跳...中国...的根??? 学懂了之后其实运用起来就根二分差不多啊,不过证明 ...