- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
G-API背后的动机
G-API模块为OpenCV带来了基于图的执行模型。本章简要描述了这种新模型如何在两个方面帮助软件开发者:优化和移植图像处理算法。
使用Graph API进行优化
传统上,OpenCV提供了大量的独立图像处理函数(参见core和imgproc模块)。许多函数都经过了良好的优化(例如,针对特定CPU进行了向量化、并行化等),但是开箱即用的优化范围仅限于单个函数——构建在这些函数之上的整个算法的优化是程序员的责任。
OpenCV 3.0引入了透明API(或T-API),它允许透明地将OpenCV函数调用卸载到OpenCL设备,并通过cv::UMat减少主机/设备数据传输——这是向前迈出的一大步。然而,T-API是一个动态API——用户代码仍然不受约束,OpenCL内核以任意顺序排队,因此消除了进一步的流水线级别优化潜力。
G-API为OpenCV 4.0带来了隐式的图模型。图模型捕获流水线中的所有操作及其数据依赖关系,从而为G-API框架提供了额外的信息来进行流水线级别的优化。
基于图的优化的核心是分块(Tiling)。分块允许将处理分解为较小的部分并重新组织操作以启用数据并行性、改善数据局部性并节省内存占用。由于现代计算机架构中内存访问的不同成本,数据局部性是软件优化的一个特别重要的方面——在第一级缓存中重用的数据越多,流水线就越高效。
当然,上述技术可以手动应用——但这需要额外的技能和对目标平台的了解,且算法实现会变得不可逆地更加具体、灵活性降低、更难扩展和维护。
G-API从用户那里接手了这一责任和复杂性,并自行完成了大部分工作,保持算法代码免受设备或优化细节的影响。然而,这种方法也有其自身的局限性,因为图模型是一种受限模型,并非每个算法都可以表示为图,所以G-API的范围仅限于常规图像处理——各种滤镜、算术运算、二进制操作以及定义明确的几何变换。
使用Graph API进行移植
G-API的本质在于声明一系列要运行的操作,然后执行该序列。G-API是一个受限的API,因此它对哪些操作可以形成一个流水线以及这些操作之间可以交换哪些数据施加了一些限制。
实际上,这种形式化有助于使算法具有可移植性。G-API清晰地分离了操作接口与其实现。
一个操作(内核)可能有多个实现,甚至在同一设备上(例如,基于OpenCV的“参考”实现和分块优化的实现,两者都在CPU上运行)。在G-API术语中,图(或计算)仅使用操作接口构建,而不是使用实现——因此相同的图可以在不同的设备上执行(当然,也可以使用不同的优化技术),而几乎不需要改变图本身。
G-API支持插件(后端),这些插件聚集了关于在特定平台上最佳执行方式的逻辑和智能。一旦使用G-API构建了一个流水线,就可以参数化以使用其中任何一种后端(或它们的组合),从而使图能够轻松移植到新平台。