为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

GenICam标准

2019-04-07 5页 doc 312KB 115阅读

用户头像 个人认证

xrp27580

暂无简介

举报
GenICam标准GenICam标准1、概述如今的数码摄相机包含了很多的功能,而不仅仅是采集图像。对于机器视觉相机来说,处理图像并把结果附加到图像数据流上,控制附加的硬件,代替应用程序作实时的处理等都是很平常的事情。这也导致了相机的编程接口变得越来越复杂。GenICam的目标是为所有类型的相机提供一个统一的编程接口。无论相机使用的是哪种传输协议或者实现了哪些功能,编程接口(API)都是一样的。见图1。图1TheGenICamvisionGenICam标准包含多个模块(module),按照主要功能分为如下部分:GenApi:用于设置相机的应用程序...
GenICam标准
GenICam标准1、概述如今的数码摄相机包含了很多的功能,而不仅仅是采集图像。对于机器视觉相机来说,处理图像并把结果附加到图像数据流上,控制附加的硬件,代替应用程序作实时的处理等都是很平常的事情。这也导致了相机的编程接口变得越来越复杂。GenICam的目标是为所有类型的相机提供一个统一的编程接口。无论相机使用的是哪种传输或者实现了哪些功能,编程接口(API)都是一样的。见图1。图1TheGenICamvisionGenICam标准包含多个模块(module),按照主要功能分为如下部分:GenApi:用于设置相机的应用程序开发接口(API)GenTL:获取图像用的传输层(TL)协议,尚未完成这两个模块可以相互独立地发布。2 GenApi模块–配置相机2.1. 简介 GenApi模块解决如何去配置相机的问题。主要的思路是,让相机生产厂商为他们的相机提供机器可以识别的产品说明。这些相机描述文件(cameradescriptionfiles)包含所有需要的信息,用以自动地把相机的属性(features)和其寄存器(registers)相对应。相机的Gain属性是一个典型的例子,假设用户想令Gain=42,利用GenICam,通用的软件可以读相机的描述文件并发现,要把Gain属性设成42意味着向地址为0x0815的寄存器写入值0x2A。其他要做的工作可能是检查相机是否提供Gain属性,并检查要写入的值是否在Gain的允许范围内。请注意,给相机添加新的属性仅仅意味着扩展相机的描述文件,就可以对所有符合GenICam标准的程序立即生效。  图2Layersforaccessingacamera  2.3. 节点、接口和抽象特征相机描述文件中的每个节点只描述一个项目。基于项目的自然性,节点有一个特定的类型(nodetype)和一个特定的接口(interface)。下列接口目前可用[footnoteRef:1]3(每个接口有一个控件用于映射到GUI):[1:]      IInteger–映射到一个带有value、min、max和increment的slider      IFloat–映射到一个带有value、min、max和一个物理单位的slider      IString–映射到一个显示字符串的编辑框      IEnumeration–映射到一个下拉框      ICommand–映射到一个命令按钮      IBoolean–映射到一个复选框(checkbox)      IRegister–映射到一个显示16进制字符串的编辑框      ICategory–映射到一个可以反映相机属性结构的树控件      IPort–映射到一个相机端口,通常不用图形显示第2.9章给出了接口特性的更多细节。可用的节点类型在第2.8章中说明。可能有多种节点类型实现同样的接口类型。例如,IInteger接口,被下列(不是全部)节点类型实现:      IntReg–根据字节边界,从寄存器取出一个整数      MaskedIntReg–从寄存器的一段取出一个整数,例如,从第8位到第12位      Integer–从不同的节点得到value、min、max和increment属性,合并在一起 每个节点类型从不同的源,用不同的取出一个整数值。对于需要输入一个整数值的连接,所有这些节点的输出值都可以用作类型安全的输入。抽象特征(Abstractfeatures)总是用一个接口类型(interfacetype)、一个名称(name)和一个含义(meaning)来描述。例如,相机的Gain(名称)可以被定义为IInteger(接口类型),并且可以描述相机内的增益(含义)。注意,其它的定义也可能存在,例如,Gain可以被定义为一个IEnumeration或一个IFloat。  2.4. 取得和设置值当用户读或写一个节点的值,节点会触发节点图内一系列的读写操作。为了说明这一点,图4显示了Gain属性的一个更复杂的例子。Gain属性可以抽象成一个IInteger接口,通过这个接口,用户可以设置Value并且可以读(或其它操作)Min和Max值。图4的例子假定相机有3个寄存器,一个是Gain的Value,另两个是Min和Max。利用IntReg节点可以从每个寄存器取出相应的值。名字为Gain的Integer节点收集并合并这些数据,再通过IInteger接口把结果传递出来。  图4Exampleofthecontrolflowwhengettingandsettingfeatures 如果用户读取Gain节点的值,调用会被分派到GainValue节点,而GainValue节点会通过IPort接口向Device节点查询正确的寄存器。如果用户试图设置Gain节点的值,实现程序可能首先会从GainMin和GainMax节点读出Min和Max值以检查范围。如果输入值在允许的范围内,Gain节点会通过GainValue节点和Device节点把值写入相机。注意,根据相应IntReg节点的Cacheable属性,实现程序可能会把Min和Max值放入缓存。  2.5. 访问模式每个节点都有一个下表定义的访问模式: Readable Writable Implemented AccessMode * * 0 NI–未实现 0 0 1 NA–不可用 0 1 1 WO–只写 1 0 1 RO–只读 1 1 1 RW–读写1=yes,0=no,*=don’tcare 属性可能已经被相机实现,但暂时不可用。如果可用,则根据定义,属性被实现并且可以读和/或写。有些节点由某些元素来控制访问权限,例如寄存器节点(参见2.8.3)。另外,GenICam还提供3种在运行时改变访问权限的机制。      根据另一个节点的值,属性可能暂时被锁定(locked)。属性在锁定的状态下不可写。根据上面的表格,写标志位暂时强制为0。      根据另一个节点的值,属性可能暂时不可用(notavailable)。根据上面的表格,写标志位和读标志位暂时强制为0。      根据另一个节点的值,属性可能没有实现(notimplemented)。根据上面的表格,实现标志位始终强制为0。 “可用”和“已实现”是不同的,因为GUI可能想用不同的方法来处理这两种情况。未实现的属性不会显示给用户;而暂时不可用的项目只是灰色的并且值会被替换,例如替换成“—”;暂时被锁定的属性是灰色的,但是属性的值仍然会显示。以硬件Trigger为例来说明让一个属性暂时不可用(temporarilynotavailable)的情况,硬件Trigger的值可以为On或Off。如果Trigger是On,另外一个属性TriggerPolarity变得可用,TriggerPolarity属性指示硬件信号是ActiveHigh还是ActiveLow。如果Trigger是Off,则TriggerPolarity属性是无意义的,应该被置为灰色。图5显示了这个信息在相机描述文件中如何处理,Trigger和TriggerPolarity属性用Enumeration类型的节点来实现,这种类型把一组枚举型的入口映射到整数值。例如,Trigger属性的入口是On=1和Off=0。利用IntReg类型的节点把整数值映射到寄存器。 图5Controllingwhetherafeatureisaccessible TriggerPolarity节点有个叫pIsAvailable的连接,这个连接需要指向一个提供IInteger接口的节点。如果这个被指向的节点的值为0,那么TriggerPolarity节点暂时不可访问。在这个例子中,pIsAvailable可以直接指向TriggerReg,因为Trigger=On被映射为1,Trigger=Off被映射为0。如果不是这样的话,一个类型为IntSwissKnife的节点会很有用,它能根据数学公式计算其他整数节点的值,并得到一个整数的结果。在XML文件中,节点看起来像这个样子:viewplaincopytoclipboardprint?1.<IntSwissKnife Name="TriggerEnabled">  2.<ToolTip>Determines if the Trigger feature is switched on</ToolTip>  3.<pVariable Name="TRIGGER">TriggerReg</pVariable>  4.<Formula>TRIGGER==1</Formula>  5.</IntSwissKnife>  <Formula>入口的数学公式被计算,得到节点的计算结果。在计算之前,变量的符号名称被对应节点的整数值替换。在本例中,只有一个<pVariable>入口指向TriggerReg节点,符号名称是TRIGGER。这个名称在公式“TRIGGER==1”中也有。如果GUI升级了,就会去查看TriggerPolarity节点是否可用。而TriggerPolarity节点会去检查IntSwissKnife,而IntSwissKnife又会根据TriggerReg节点的值去计算结果。兼容DCAM的1394相机的BytesPerPacket属性是“暂时锁定属性”(temporarilylocked)的一个典型例子。用户可以改变相机的这个参数,仅当PC适配器的DMA未被设定为采集图像的时候[footnoteRef:2]5。设定DMA的意思是,传输层查询相机的BytesPerPacket参数,并把这个参数设置到DMA。这个工作完成后,直到传输层释放DMA之后才能改变BytesPerPacket。在这之前,相机的这个参数必须被锁定。[2:] 注意,相机本身没有办法知道DMA是否设置。因此,相机描述文件中“普通的”节点不能被用来控制BytesPerPacket的锁定状态。 图6Lockingafeature GenApi内的解决方案是提供一个浮动的Boolean型节点TLParamsLocked(参见图6)。BytesPerPacket通过pIsLocked连接到这个节点。传输层(TL)需要通过更新TLParasLocked节点的值来反映其DMA状态。在设定DMA之前,它会通过令TLParamsLocked为true的方式来锁定相机参数(例如BytesPerPacket),在采集图像完成之后,它会把TLParamsLocked设置回false。改变TLParamsLocked节点会更新所有关联节点的锁定状态,例如BytesPerPacket节点。注意,为保证这种方式正常工作,TLParamsLocked必须是标准的节点名,并且传输层必须有访问相机的GenApi接口的权限。另外,相机描述文件的设计者必须注意哪个参数要被传输层锁定。这个信息包含在传输层标准之中,例如DCAM规范,这个规范规定,在采集数据的时候每桢的包数和每个包的大小必须固定。“属性没有被实现”(notimplemented)的一个典型的例子是,同一个家族的某些相机有Gamma属性而有些则没有。如果相机有一个查询位(inquirybit)来标识是否实现了Gamma属性,就可以为这个家族的所有相机维护一个相机描述文件。图7显示了GenICam如何处理这种情况。Gamma属性节点有一个叫pIsImplemented的连接指向GammaInq节点,GammaInq节点映射相机的查询位。通常把多个查询位合并到一个寄存器里。为了取得这些位,要使用MaskedIntReg节点类型。这个类型有点像IntReg节点,但是,你可以像查询整数一样取查询想要的一个或一组连续的位。 图7Checkingwhetherafeatureisimplemented2.6.缓存如果某个实现对每个写操作支持范围、实现和可用状态的检查,通常会触发一系列对相机的读操作。大多数用于有效性检查的数值很少或不会发生变化,所以可以放入缓存。相机描述文件包含所有必需的定义以确保缓存的一致性。图8AreaofInterest为说明这一点,需要用到更复杂的例子。图8显示了相机图像上的AOI。相机只需要发送AOI内的图像,图中的AOI是由Top、Left、Width和Height四个参数给出的矩形。图9ControllingtheAreaofInterest如图9所示,这四个参数都从寄存器中取出。当然,这种简单的方式不能很好地处理,因为这四个参数的取值范围都不是无限的。假定像素坐标从0开始,有下面的限制:0≤Left≤ImagerWidth−Width0≤Top≤ImagerHeight−Height1≤Width≤ImagerWidth−Left1≤Height≤ImagerHeight−Top为了处理这些限制,每个参数的最大值都必须用SwissKnife节点计算;最小值是固定的。结果GenApi节点图如图10所示。注意,这里加入了第二层的Integer节点并且最大值由IntSwissKnife节点处理。图10ControllingtheAreaofInterestwhiletakingrestrictionsintoaccount假定图像处理器有VGA模式(640x480),TopMax节点的XML代码看起来可能是这个样子的:<IntSwissKnifeName="TopMax"><pVariableName="CURHEIGHT">HeightReg</pVariable><Formula>480-CURHEIGHT</Formula></IntSwissKnife>让我们再回到缓存的话题,你应该不会希望每次设置Left属性的时候都去读一次HeightReg或者判断一次TopMax节点。这的确是不必要的,当(且仅当)你确定HeightReg只在GenApi自身写了一个新的值到这个寄存器的情况下才发生改变。这种情况下,你可以把HeightReg和TopMax的值放入缓存。如果用户写了一个新的值到HeightReg,HeightReg缓存的值可以立即发生变化,并且需要令TopMax缓存无效。当下一次有人要访问Left节点的时候,会去读TopMax,因此为TopMax创建一个新的缓存入口。规则:当一个节点的发生变化的时候,要通知其所有的客户端,以便客户端可以令缓存无效。通常,相机描述文件中结点间的连接包含了所有需要的信息,以便实现程序能处理缓存而不需要用户操心。不过,在有些情况下,相对于节点直接描述的,相机本身包含更多的依存关系。某些相机包含一个叫做Binning的属性,当Binning被置为ON,相邻像素的值(charge)被合并,实现较好的效果,但代价是分辨率较低。假设一个VGA分辨率的图像卡,典型的配置如下:l无Binning(640x480)l水平Binning(320x480)l垂直Binning(640x240)l全Binning(320x240)在GenICam中,这个属性要用一个含有四个值的枚举型来描述(见图11)。改变binning就意味着改变图像卡尺寸——不是实际的物理图像卡,而是用来表示AOI参数的限制的逻辑图像卡尺寸。图11ControllingtheAreaofInteresttakingbinningintoaccount我们假定相机通过寄存器提供有关当前(逻辑)图像卡尺寸的信息。如图11所示,我们引入了两个新的节点:ImagerHeightReg和ImagerWidthReg。TopMax的XML代码看起来像这个样子:<IntSwissKnifeName="TopMax"><pVariableName="CURHEIGHT">HeightReg</pVariable><pVariableName="IMAGERHEIGHT">ImagerHeightReg</pVariable><Formula>IMAGERHEIGHT-CURHEIGHT</Formula></IntSwissKnife>正如我们所见,如果用户改变Binning属性,ImagerHeightReg的值将会改变。然而这两个节点间没有数据流。为确保在BinningReg节点的内容变化的时候,ImagerHeightReg节点的缓存无效,必须在两个节点间引入一个<pInvalidator>连接。这个连接的唯一用途是,说明这两个属性间隐藏的依存关系,以及确保缓存总是一致的。2.7.识别并判断相机描述文件的版本必须能够通过一种统一的方式,来识别一个相机描述文件,及其所描述的相机。另外,随着时间的推移,相机描述文件也要相应地扩展,例如,当相应的相机产品增加了属性的时候。这就产生了对版本机制的需求。GenApi语法本身也要与时俱进,例如,当加入了新的节点类型的时候,所以也要求对规范提供版本机制。在<RegisterDescription>元素的属性列表中可以发现必要的方法,这个元素是XML文件最外层的框。下面来看一个例子:<RegisterDescriptionModelName="Example01"VendorName="Test"ToolTip="Example01fromtheGenApistandard"StandardNameSpace="None"SchemaMajorVersion="1"SchemaMinorVersion="0"SchemaSubMinorVersion="1"MajorVersion="1"MinorVersion="0"SubMinorVersion="0"ProductGuid="1F3C6A72-7842-4edd-9130-E2E90A2058BA"VersionGuid="7645D2A1-A41E-4ac6-B486-1531FB7BECE6"xmlns="http://www.genicam.org/GenApi/Version_1_0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.genicam.org/GenApi/Version_1_0../GenApiSchema_Version_1_0.xsd">所描述的相机由VendorName:/ModelName对来标识。因为有商标保护,我们可以假定VendorName是唯一的。ToolTip属性用来提供设备的附加信息,并且可以显示给用户,例如,用总线上设备的选择列表的方式。相机描述文件内的名称可能来自不同的命名空间,关于这一点在第2.8.1章有更详细的说明。在一个给定的相机描述文件中,名称要么来自自定义的命名空间,要么来自标准命名空间。属性StandardNameSpace表示文件中所使用的标准命名空间。一个相机描述文件中不同项目的版本信息遵循共通的规则,并使用一个由三部分组成的版本号(versionnumber):<Major>.<Minor>.<SubMinor>例如,“1.4.2”兼容性规则(compatibilityrules)如下:lMajor版本号高的文件不向下兼容lMinor版本号高的文件向下兼容l改变SubMinor仅仅表示修复了问题;总是应该使用SubMinor最高的文件例:版本1.3.0兼容版本1.1.*,1.2.*和1.3.*(星号表示不关心)。它不兼容版本2.*.*。如果版本1.3.2可用,则应该用它来代替1.3.0。2.7.1.格式的版本属性SchemaMajorVersion、SchemaMinorVersion和SchemaSubMinorVersion描述XML文件用的GenApi格式的版本。这些属性是强制的,目的是提供信息。另外,格式的Major和Minor版本号也反映在命名空间(参见xmlns入口)和格式的文件名(参见xsi:schemaLocation入口)。在这个例子中,命名空间是“http://www.genicam.org/GenApi/Version_1_0”。需要用到这个格式文件的程序既可以根据URL通过互联网来得到它,也可以通过由schemaLocation的第二部分给出的路径来找到这个文件,这个路径是可选的,在这个例子中是“../../GenApi/GenApiSchema_Version_1_0.xsd”,并假定XML文件存放在GenICam参考实现的目录结构中。xmlns:xsi入口的“http://www.w3.org/2001/XMLSchema-instance”描述了格式语言自身的命名空间。注意,如果一个实现支持,例如版本1.3.*的格式,则必须提供3个格式文件:版本1.0.*、1.2.*和1.3.*,这是向下兼容的要求,因为旧的XML文件带有旧的命名空间,需要旧的格式文件;另一方面,这个实现不支持使用新版本格式文件的XML文件,例如1.4.*要被拒绝。因此,有必要把版本号反映到格式的命名空间。2.7.2.相机描述文件的版本属性MajorVersion、MinorVersion和SubMinorVersion描述XML文件自身的版本。相机的制造商有责任遵守兼容性规则。相机描述文件的向下兼容是什么意思呢。假设一个相机,其版本1.0仅仅实现了一个属性。现在假定这个相机为另一个属性扩展了firmware。有两个方法可以在相机描述文件中处理这个情况。如果仅仅把这个属性添加到XML文件,就是暗示这个属性已经存在了。因为对旧版的相机来说情况并非如此,所以新的文件不是向下兼容的,结果其版本号必须是2.0。另一个更智能的解决办法是,在相机中(!)引入一个查询寄存器,用户可以检查这个寄存器以判断这个新的属性是否已经实现。现在可以加入这个新的属性,并允许用户通过属性的访问模式来判断属性是否实现。这样这个新的文件就是向下兼容的,其版本可以是1.1。当然,只有在一开始相机就提供这个查询机制的情况下,这个方法才是可行的。采用第二种方法的优点是,对于这个相机的整个家族,只需要维护一个相机描述文件。注意,这里的兼容性(compatibility)指的仅仅是属性节点(featurenodes)及其功能,而不是实现节点(implementationnodes,参见2.8.2章以获得详细信息)。2.7.3.识别并缓存相机描述文件加载一个相机描述文件可能包含一个或多个预处理步骤。为加快处理速度,预处理过的XML文件可以被放入缓存。在缓存中,需要一个key来唯一标识相机描述文件。把元素<RegisterDescription>的属性VendorName、ModelName、MajorVersion、MinorVersion和SubMinorVersion合并起来是足够了,但是用起来有点不方便。为简化缓存,引入了VersionGuid属性,属性VersionGuid含有一个GUID,每当属性VendorName、ModelName、MajorVersion、MinorVersion或SubMinorVersion中任何一个发生变化的时候,都必须要改变这个GUID。VersionGuid唯一地标识一个相机描述文件的某个版本,和文件名。不必把所有不同的相机描述文件都放入缓存,可以只放最新的文件,最新的文件通过向下兼容的方式包含了所有其它的。对于每个VendorName、ModelName和MajorVersion号,都有一个这样的文件。这种文件的缓存key是ProductGuid,ProductGuid也有一个GUID,每当VendorName、ModelName或MajorVersion发生改变的时候必须改变。这份资料本来是我08年初的时候工作中需要用到GenICam,为了方便就自己翻译给自己看。后来怕资料搞丢就放到CSDN上,但是感觉CSDN编辑不是很方便,而且没过多久就离开了摄像机的行业,就没有继续更新了。回国后一切从头开始,连CSDN都很少上都给忘记了,没想到偶尔上来一下,发现这么冷门的东西也有人看,那就赶紧发完。为了加快速度,图片都略掉。2.8.可用的节点类型本章对每个可用的节点类型提供一个概要的描述,包括其功能、用途以及最关心的参数。另外,对于每个节点在GenICam标准的XML格式文件中的layout,会有一个正式的说明。这个格式文件可以用大多数XML编辑器来读,并且提供了语法检查和上下文相关的帮助,可以大大简化创建相机描述文件的工作。本文档中的GenApiSchema_Version_1_0.xsd指的是GenApischemaversion1.0。注意,随着标准版本的增长,可能会加入新的节点类型,元素和属性,不过,如果可能的话会保持向下兼容。  2.8.1.NodeNode类型包含其它节点类型共通的元素和属性。一个孤立的Node类型没什么用处,但是可以用于测试。下面是一个例子: <NodeName="Gain"NameSpace="Standard"><Extension><MyElement>Somethingvendorspecific</MyElement></Extension><ToolTip>Theampliticationofthecamera</ToolTip><Description>Amoreelborateddescription</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-Za-z0-9]的组合。格式也允许使用下划线,但是相机描述文件设计器不能使用下划线,因为参考实现把下划线用在自动生成的名称上。每个Name存在于一个命名空间(namespace)中。通过节点的NameSpace属性和外框元素<RegisterDescription>(参见2.7章)的StandardNameSpace属性的结合来标识命名空间。NameSpace属性有两个可能的值:Custom和Standard。如果是Custom,可以用任何名字,只要在相机描述文件内是唯一的就行了。如果是Standard,则必须用标准属性名列表(standardfeaturenamelists)中提供的名字,列表对于下列相机类型可用(参见2.9章):      IIDC:符合1394IIDC标准(也叫DCAM标准)的相机      GEV:符合GigEVision标准的相机      CL:符合CameraLink标准的相机      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.CategoryCategory节点用来组织要提供给用户的属性,它实现ICategory接口并继承所有的Node元素。它也提供一组指向包含在category中的属性的<pFeature>元素。Category可以包含别的Category,从而形成一棵任意深度的树。有一个特殊的Category节点,带标准的名字Root(脚注:属性ICategory::Root在所有标准命名空间中定义),它是Category树的根。用户可能想从这里开始浏览相机的属性。下面的例子创建如图12所示的节点图。<CategoryName="Root"NameSpace=”Standard”><pFeature>ScalarFeatures</pFeature><pFeature>Trigger</pFeature></Category> <CategoryName="ScalarFeatures"><pFeature>Shutter</pFeature><pFeature>Gain</pFeature><pFeature>Offset</pFeature><pFeature>WhiteBalance</pFeature></Category> <CategoryName="WhiteBalance"><pFeature>RedGain</pFeature><pFeature>BlueGain</pFeature></Category> <CategoryName="Trigger"><pFeature>TriggerMode</pFeature><pFeature>TriggerPolarity</pFeature></Category> 注意,通过浏览目录树(categorytree)来访问节点的用户可能只想看Category节点之下第一层的属性节点(featuresnodes)。图中更深的节点叫做实现节点(implementationnodes),只能通过名称或一种特殊的浏览模式得到,实现程序可能会提供这种浏览模式用于调试目的。要注意,在新发布的相机描述文件中,实现节点的名称和layout可能会发生变化,即使制造商声明它是向下兼容的(参见第2.7.3章)。 (图略)Figure12Atreeofcategories  2.8.3.RegisterRegister节点映射到相机的寄存器空间中一个连续的字节数组。Register节点实现IRegister接口,并从Node节点继承元素和属性。同时也向所有特殊的寄存器访问节点,例如IntReg,StringRet等等提供继承的元素。当然,Register节点也可以实例化自身,以访问原始的二进制数据。下面是一个简单的例子:<RegisterName="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(readonly)或WO(writeonly),表示访问属性。<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)。<pIndexOffset=”12”>元素指向实现一个IInteger接口的节点,提供一个index。这个元素有一个属性Offset。这个index和Offset要加到地址上。<pInvalidator>元素包含一个节点的名称。当发生变化的时候,会令该节点的内容无效,如2.6章所述。下面的例子显示了使用间接寻址机制的方法(同时参见图13)。<IntegerName="BaseAddress"><Value>0xff00</Value></Integer> <IntRegName="Gain"><Address>0x04</Address><pAddress>BaseAddress</pAddress><Length>4</Length><AccessMode>RW</AccessMode><pPort>Device</pPort><Sign>Unsigned</Sign><Endianess>LittleEndian</Endianess></IntReg> <IntRegName="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{ //BaseAddress0xff00uint32_t Reserved;uint32_t Gain; //Offset0x04uint32_t Offset; //Offset0x08}; 结构体的基地址从一个叫BaseAddress的常量整数节点得到,本节点用一个<pAddress>元素和它关联。结构体的每个元素(Gain和Offset)都有一个偏移地址,可以用一个<Address>元素把基地址和偏移地址相加。(图略)Figure13Indirectaddressing:mappingaC/C++struct 注意,对于1394DCAM兼容相机来说,这一机制使用非常频繁。这类相机的整个标准寄存器都有一个共通基地址,运行时必须要通过IEEE1212配置ROM结构来得到(参见ConfRom节点类型)。  2.8.4.数组和选择器前一节所述的间接寻址也用于访问数组。下面的例子显示了这样做的方法(同时参见图14):<IntegerName="LUTIndex"><Value>0</Value><Min>0</Min><Max>255</Max><pSelected>LUTEntry</pSelected></Integer> <IntRegName="LUTEntry"><IntSwissKnifeName="LUTEntryAddress"><pVariableName="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>的范围内改变。 (图略)Figure14AccessingaLUTarray 之所以可以用LUTIndex来选择一个特定的LUTEntry,是因为LUTIndex节点有一个<pSelected>元素。实现IInteger或IEnumeration接口的节点可以有任意数目的pSelected入口,这表明,基于选择器节点(selectornode)的值,被选择的节点(selectednodes)会表现出不同的值。关于一个节点是否是选择器,以及哪些是被选择的节点的信息,可以用ISelector接口得到,这个接口有对应的方法IsSelector和GetSelectedFeatures。例如,用这个接口,GUI可以显示一个LUTEntries的列表,因为它知道如果从min到max运行LUTIndex(选择器),就可以从LUTEntry(被选择)得到一组不同的值。注意,利用多个索引,选择器和间接寻址方法可用来访问多维数组(multidimensionalarrays)。  2.8.5.Integer,IntReg,MaskedIntRegIInteger接口提供访问有符号的64位整型变量的方法,这个变量有一个受Minimum、Maximum和Increment参数制约的Value,公式为:Value=Minimum+i×Increment,并且有   IntReg节点映射到按字节对齐的整数寄存器。它从Register节点继承元素和属性,下面是映射到一个双字节无符号整数的一个例子。注意,这个变量有如下的约束参数:Minimum=0,Maximum=65535,Increment=1。<IntRegName="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>元素分别表示最低有效位和最高有效位。<MaskedIntRegName="Offset"><Address>0x2345</Address><Length>2</Length><AccessMode>RW<
/
本文档为【GenICam标准】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索