我是靠谱客的博主 呆萌往事,最近开发中收集的这篇文章主要介绍openvx 2:设计概述(一)第二章:设计概述,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

第二章:设计概述

2.1 应用场景

Openvx可以直接用于应用程序,也可以作为高级框架或平台api的加速层。openvx常见使用场景如:​

此图描述得视觉处理常用得调度架构,用户要实现有关视觉得某些功能,首先设计顶层的app,然后调用一些cv得函数/框架,接着通过openvx将各函数部署在不同得硬件平台上运行;

2.2 设计目标

Openvx做为一个标准化的计算机视觉功能框架,能够在各种平台上运行,并允许供应商在其平台上进行加速优化。Openvx可以通过为常用视觉函数以及函数集合提供抽象来提高视觉应用程序的性能和效率,从而尽可能的减少运行时间。

Openvx的目标是尽可能多的覆盖常用的视觉程序。

2.2.1 硬件的优化

本文档中没有介绍在实现中可以使用哪种加速方法或技术,供应商可以选择任意不同的实现方法,比如使用并行方式,或者是采用专门的硬件设备。

本规范也没有对某个性能级别做出声明或要求,因为这可能在不同平台和使用场景之间存在明显的不同。

2.2.2 硬件约束

Openvx专注于在不同硬件设备上都能显著加速视觉函数。本规范的未来版本可能会在实现这些功能的硬件加速时将附加的视觉功能纳入核心标准。

2.3 设想

2.3.1 可移植性

Openvx的设计宗旨是尽可能地提高性能和可移植性,尽量让API函数不同的设备上能够使用。

在一些情况下对可移植性进行了折衷,比如用openvx API构造的图应该能在不同的设备上能运行,且能返回可能接近的结果;

在本规范中定义为“实现定义”(implementation-defined)的情况下,可移植性可能会收到损害。

2.3.2 不透明性

Openvx旨在解决广泛的设备和平台中的兼容性问题,从嵌入式系统到桌面机器及分布式计算架构。

openvx中除了面向用户的数据之外,所有的数据都是不可见的。每个实现都提供了用于访问数据的标准化接口,可以满足特定的硬件、平台的分配需求。

从其他API导入或共享的内存不属于openvx,这些仍需要创建者进行维护和访问。Openvx没有规定对内存分配方法或不透明内存对象布局的任何要求,也没有规定结构体的打包及对齐方式。

2.4 面向对象的行为

Openvx对象在编译时是 安全关键型 应用程序的强类型对象,在运行时是动态应用程序的强类型对象。每个对象在vx_type_e列表中都有其类型定义和关联枚举值。任何对象都可以向下安全的转为vx_reference,可以使用 vxQueryReference 来查询该refernece 的vx_enumvx_type_e

(简单理解,open_vx会把数据类型转为reference在内部进行传递)。

2.5 openvx框架对象

该规范定义了以下openvx框架对象:

  1. Object: Contex:openvx上下文是所有openvx对象的对象域。所有数据对象和所有框架对象都存在于上下文中。Openvx上下文保持所有对象的引用计数,并且会在析构过程中进行垃圾收集来释放使用的reference。虽然多个客户端可以连接到openvx上下文,但所有的数据都是私有的,因为对象的引用只提供给创建方。在不同context中创建的reference不支持在同一个函数中使用,需要用户自己去实现;
  2. Object: Kernel: openvx中的内核是计算机视觉函数的抽象表示,如“Sobel Gradient” 或 “Lucas Kanade Feature Tracking”. 一个视觉函数可以从其他函数中实现许多类似或相同的特性,但只要它使用相同的字符串和枚举来命名,并符合openvx指定的结果,它仍然被认为是一个单一的、唯一的内核。在这方面,内核类似于函数的签名。
  3. Object:Parameter:一种传递给openvx函数的抽象的输入或者输出。该节点包含该参数在kernel中的使用情况。包括:
    1. Signature Index:签名中参数的编号索引;就是第几个参数;
    2. Object Type:对象类型,如VX_TYPE_IMAGE等vx_type_e中定义的类型;
    3. Usage Model: VX_INPUT 或 VX_OUTPUT;
    4. Presence State:VX_PARAMETER_STATE_REQUIRED, or  VX_PARAMETER_STATE_OPTIONAL; 是必须的还是可选的,必须的就是有这个参数kernel才可以继续执行,注意输入输出参数均可以指定此属性;
  4. Object: Node: 节点可以理解为是一个kernel实例,它与一组特定的reference相匹配。节点是特定的图创建的并仅能用于当前图内。当从一个节点中提取一个vx_parameter时,可以访问一个额外的属性:
    1. Reference: 从节点创建函数中分配给这个参数索引的vx_reference(如 vxSobel2*3Node).
  5. Object: Graph: 一组以有向无环图方式连接的节点。一个图可能有一些点集,这些节点集与同一图中的其他节点集没有连接,具体看图的形式。

2.6 openvx的数据对象

数据对象是由节点中的图形处理的对象

  1. Object:Array:不透明的数组对象,可以是基本数据类型或结构体的数组;
  2. Object:Convolution:卷积,包含一个由vx_int16类型值组成的M*N的矩阵,还包含一个用于归一化的比例因子。通常与vxuConvolve 和 vxConvolveNode一块使用;
  3. Object:Delay:包含一个由用户手动控制的、暂时延迟的对象列表;
  4. Object:Distribution: 包含频率分布(如直方图)的不透明对象;
  5. Object:Image:图像对象,可能是vx_df_image_e中的某种格式;
  6. Object:LUT:查找表对象;
  7. Object:matrix: 由标量值组成的M*N的矩阵;
  8. Object:Pyramid:包含多层缩放vx_image对象的对象;
  9. Object: Scalar: 包含单一基本数据类型;
  10. Object:Threshold:阈值配置;
  11. Object:ObjectArray:数组对象,可以是任何数据对象的数组(不包含Delay 与 ObjectArray对象) ;
  12. Object:Tensor:多维数据对象,用于神经网络等中的扩展函数。

2.7 错误对象 Error Objects

错误对象在平台发生严重的问题(如内存不足或句柄不足)时,会从创建对象的函数处返回。检查可以在创建或者其他api进行调用时进行。使用实例:

vx_<object> obj = vxCreate<Object>(context, ...);
vx_status status = vxGetStatus((vx_reference)obj);
if (status == VX_SUCCESS) {
// object is good
}

2.8 Graphs Concepts

graph 是openvx中至关重要得计算概念。使用graph作为解决计算机视觉问题目的是为任何得实现都提供可实现性,图在进行计算之前其所有得依赖关系都是知道得,所以这可以让在不同得实现方式下都能发挥其最大得计算能力。

graph是由许多nodes组成得,nodes可以通过其创建函数生成添加。graphs在处理时必须创建,在实现时必须验证。graphs创建完毕之后可以根据需求进行多次调整。

2.8.1 Linking Nodes

Graphs Nodes(图节点)通过数据依赖关系连接在一起,并没有固定的顺序,同一个引用可以连接到其他的节点。但是一个图中只有一个节点可以输出到任何特定的数据对象引用,也就是在一个给定的图中只能有一个输入(写入)。这种方式可以防止数据依赖关系的不确定排序,图中所有的写入者都必须在访问数据操作发生之前取出输出数据

2.8.2 虚拟数据对象

openvx中节点之间的连接是通过对象来实现的。当openvx的客户机知道它们不需要访问中间数据对象的时候,这些数据就可以被创建为虚拟对象。虚拟数据对象可以同非虚拟数据一样使用,也可以将图中的节点连接起来。虚拟数据存在以下几点不同:

  1. Inaccessible - 不可访问性。从图外引用虚拟数据对象会失败,map/unmap/cpoy操作此对象均会返回错误。虚拟数据属于节点内部,可以在节点内调用虚拟数据;
  2. Scoped  - 作用域:其作用域为创建他们的图中。注意虚拟数据活动范围仅限于单个图形,即要在图执行之前完成定义,且程序在连续的图执行中不应保留虚拟数据对象。(离开作用域即释放)。
  3. Intermediates - 中间使用:因为不能被客户机访问,所以只能用于图内的中间操作
  4. Dimensionless or Formatless - 无量纲或无格式:虚拟数据在创建时可能是未完全定义的,在具体使用时会从虚拟对象的节点来推到得出其具体形式。(类似多态。)
  5. Attributes - 属性:未完全定义的虚拟数据也可以查询其属性。若在对象参与图形验证之前查询,则返回的属性值是用户提供的值(如0维),若在图验证之后查询,返回的属性为图验证时确定的值。
  6. Inheritance - 继承性:子对象会继承父对象的属性。
  7. Optimizations - 最优化:在图形验证和执行过程中不需要创建虚拟数据对象,因此虚拟数据对象大小可能为0.

虚拟数据对象的这些限制让供应商能够优化数据对象的某些应用,可能不分配这样的对象,也可以创建对象的中间子对象,当然供应商还可以在远程主机上分配对象。注意虚拟对象有时需要提前分配其大小,如image图像的输入,如果定义其为虚拟,仍要在初始化时指定其大小;对于未明确定义的reference,将会在图验证阶段自动适配参数大小;

更多不同vision function 输入输出参数类型见此;

2.8.3 Node Parameters 节点参数

节点的参数可以定义为原子类型(如vx_int32、vx_enum),也可以定义为对象(eg:vx_scalar、vx_image),其中原子变量将自动转为vx_scalar 的reference在节点中使用,vx_scalar类型的节点参数可以在图形执行过程中修改,但是在修改时要重新验证图。修改节点参数的方法是:通过vxGetParameterByindex获取对vx_parameter的ref,然后将该ref传递给vxQueryParameter以获取该对象的引用。

vx_parameter param = vxGetParameterByIndex(node, p);
vx_reference ref;
vxQueryParameter(param, VX_PARAMETER_REF, &ref, sizeof(ref));

参数类型未知的时候也可以使用相同的函数来进行检索:

vx_enum type;
vxQueryParameter(param, VX_PARAMETER_TYPE, &type, sizeof(type));
/* cast the ref to the correct vx_<type>. Atomics are now vx_scalar */

2.8.4 Graph Parameters

图参数是由用户定义的,每一个图的参数都是通过‘vxAddParameterToGraph’函数进行,该函数参数中指定特定节点内的特定参数 。若想不指定节点来设置某一参数为图参数,可以通过'vxSetGraphParameterByIndex'来设置。

更多参考: 
Framework: Graph Parameters.

2.8.5 Execution Model

图必须在以下两种情况下执行:

1. Synchronous blocking mode:同步阻塞模式,此过程中vxProcessGraph将阻塞,直到图完成;

2. Asynchronous single-issue-per-reference mode:

Asynchronous Mode:

在异步模式下,图必须是一个问题一个引用,这也就是说给定一个构造好的图G,它可能被调整多次,但是只能按照自身的顺序执行。多个图的并行等处理由开发者自己设计;

2.8.6 Graph Formalisms 图形式

使用图之前必须要设置一些规则来确定其具体的执行方式。processGraph(G) 图的处理是根据图的结构来决定的。processGraph(G)是由一组节点N和数据d组成的 bipartite graph,edge(连接)(Nx,Dy)与(Dx, Ny)表示节点N写入数据Dy及读取数据Dx, Nx -> Dy, Dx -> Ny,每个edge都有一个名字Name(e),它给出节点的参数名字,每个节点参数在{input,output}中也有一个类型type(Node,name)。此外还有virtual对象及delay 对象,delay可以简单理解为就是数据对象的索引集(有关delay对象见此);节点在构图中可能被作为头节点或尾节点;

processing Graph 有以下几个限制:

1. Output typing:输出类型,每个输出边edge(Nx,Dy)都需要在{output}中输入Type(Nx, Name(Nx,Dy));

2.  Input typing: 每个输入边edge(Dx,Ny)都需要在{input}中输入Type(Nx, Name(Dx,Ny));

3. Single Writer: 每个数据对象只能被一个edge写;

4. Broken Cycles:G中的每个循环至少要有一个输入;

5. Virtual images must have a source:若Dy是虚拟数据类型,那么至少有一个edge要对其写入Dy(Nx,Dy);

6. Delay data objects shall not be virtual : 延时的数据类型不能是虚拟的;

7. 无法输出归一化的图像(image)数据;

注:图中的每个节点都要有输入输出参数,且一个节点的输入需要和另一个节点的输出相匹配,只有这样构图时候才能成功将不同节点连接起来;

G中每个节点执行时间为一个原子时间(输入输出数据,数据计算完成共花费的时间),当G的所有输入都被标记为存在的时候才可以执行,所以图执行之前需要进行以下几种初始标记:来自非虚拟数据对象Dx的输入边(Dx,Ny)都被标记;所有带有输出边(Nz, Dx)的输入边(Dx, Ny)都没有被标记;延时数据的输入边必须标记;

一个节点的处理就是取消所有输入的标记并标记所有的输出edge

包含和重叠的数据对象

有一种情况:多个节点的输出构成一个参数来作为另一个节点的输入,这时前面任意一个节点的改变都会造成后一个节点的输入数据发生变化;如在图像金字塔情况中,node4的输入参数会受123结果的影响,这时图就是 implementation-defined的;

就是如果有一个数据对象I,然后I'是由I得到的,I''是由I'得到的,那么实际上I''也是从I继承得到,此时对I'或者I''进行处理都会造成二者同时改变。为了确保这些,有以下定义:

1. Containment Set - C(d),递归的包含数据对象d,定义方式如下:

  • C0(d) = {d};
  • C1(d)是直接包含d的所有数据对象的集合;
    • 如果d是一幅图像,则d的ROI或通道生成的所有图像都直接包含在d中;
    • 如果d是一个金字塔,d的所有金字塔层都直接包含在d中;
    • 如果d是一个对象数组,则d的所有元素都直接包含在d中;
    • 如果d是延迟对象,则d的所有槽位都直接包含在d中。
  • i>1时,Ci(d)是d第i阶包含的所有数据对象的集合:
    • C(d)是包含d本身的集合,d包含的数据对象,d包含的数据对象包含的数据对象,以此类推:
      • c(d)=u_{i=0}^{infty}c_i(d)

2. 当且仅当d是一个图像得时候,I(d)始终和I相同;

3. Overlapping Relationship:Rov是表示图像重叠,比如i1 和 i2有公共部分,那么 i1 Rov i2 = true, if and only i1 and i2 is overlap; 注意Rov具有反射性和对称性,但是不具有传递性。如i1 overlaps i2, i2 overlaps i3, but is not necessarily imply i1 is overlaps i3;

4. Dependency Relationship: N1-> N2, 表示N2依赖与N1,就是N2必须在N1执行之后运行。

5. 若N1 -> N2, N1输出数据为d1, N2输入数据为d2,那么

d_1in c(d_2) or d_2in c(d_1) or I(d1) and I(d2) and d1 Rov d2

问题:

openvx包括几个框架:Context、Kernel、Parameter、Node及graph。context就是作用域,相当于一个文件(工程项目?);Kernel就是封装得各种视觉函数,可直接通过api调用函数(也就是调用kernel?);Node是运算结点,多个节点组成graph以完成某一任务。对问题处理主要是靠graph进行,图由好多节点组成,节点之间通过数据依赖得关系连接在一起。数据依赖是指两个节点通过共享数据得方式来实现连接?比如一个节点对某类型得数据进行操作,另一节点对操作完后得数据进行进一步处理,算是连接起来了吧(留验证)。虚拟数据相较于具体得数据类型不需要给与其严格得定义,会根据节点内的输入或计算信息等确定出具体的形式,但是其使用有一定限制。节点内部的参数可以定义为基本类型和标准数据类型,图参数是节点参数提取得到的,可以修改。图有许多节点组成,使用之前要先构建好每一个节点。每个节点要有输入和输出edge,进行计算之前要将输入edge标记,输出不标记。节点处理完成之后回把所有的输入edge取消标记同时标记所有的输出edge。

最后

以上就是呆萌往事为你收集整理的openvx 2:设计概述(一)第二章:设计概述的全部内容,希望文章能够帮你解决openvx 2:设计概述(一)第二章:设计概述所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部