A little about OpenCV’s UMat class
关于OpenCV的UMat类
Published by Jean on February 18, 2018
Jean于2018年2月18日出版
Everyone that uses OpenCV is familiar with cv::Mat. Although some developers never heard about UMat class and its advantages.
每个使用OpenCV的人都熟悉cv::Mat。尽管有些开发人员从未听说过UMat类及其优点。
The UMat class tells OpenCV functions to process images with an OpenCL-specific code which uses an OpenCL-enabled GPU if exists in the system (automatically switching to CPU otherwise). According to Khronos group OpenCL™ (Open Computing Language) is:
UMat类告诉OpenCV函数使用特定于OpenCL的代码处理图像,如果系统中存在支持OpenCL的GPU,则使用该代码(否则自动切换到CPU)。根据Khronos集团OpenCL™ (开放计算语言)是:
a royalty-free standard for cross-platform, parallel programming of diverse processors [..]. OpenCL greatly improves the speed and responsiveness of a wide spectrum of applications in numerous market categories including gaming and entertainment titles, scientific and medical software, professional creative tools, vision processing, and neural network training and inferencing.
一个跨平台、不同处理器并行编程的免版税标准[..]。OpenCL极大地提高了众多市场类别中广泛应用程序的速度和响应能力,包括游戏和娱乐游戏、科学和医疗软件、专业创意工具、视觉处理以及神经网络训练和推理。
OpenCV has had OpenCL implementations since its second version, but they weren’t simple and demanded a lot of adaptations to your code. Starting with the 3.0 version, OpenCV implemented the T-API (Transparent API), which adds hardware acceleration to a lot of “classic” functions. Since then, it has become able to detect, load, and utilize OpenCL devices and accelerated code automatically. So, you won’t need to implement any OpenCL code, it’s all “Transparent”.
OpenCV从第二个版本开始就有了OpenCL实现,但它们并不简单,需要对代码进行大量调整。从3.0版本开始,OpenCV实现了T-API(透明API),它为许多“经典”功能添加了硬件加速。从那时起,它已经能够自动检测、加载和利用OpenCL设备和加速代码。因此,不需要实现任何OpenCL代码,它都是“透明的”。
It is possible to see that by looking at this piece of code for Mat processing:
通过查看Mat处理的这段代码可以看出:
1 2 3 4 5 6 | void MatProcessing(const std::string& name){ Mat img,dst; img = imread(name.c_str()); cv::cvtColor(img,img,CV_BGR2GRAY); bilateralFilter(img, dst, 0, 10, 3); } |
Then compare with its UMat equivalent:
然后与UMat等效产品进行比较:
1 2 3 4 5 6 | void UMatProcessing(const std::string& name){ UMat Uimg, Udst; Uimg = imread(name.c_str(), IMREAD_UNCHANGED).getUMat(ACCESS_READ); cv::cvtColor(Uimg,Uimg,CV_BGR2GRAY); bilateralFilter(Uimg, Udst, 0, 10, 3); } |
As you can see, it’s almost the same code, with Mat changed to UMat and a small adaptation to imread function.
正如所看到的,它几乎是相同的代码,Mat改为UMat,并对imread函数进行了小的调整。
What about the performance change?
性能变化如何?
To see how UMat affects the performance, I coded a small program to find out what would be the gain here on my good ol’ i5 3330/Radeon HD 7970, the results are presented in Figure 1.
为了了解UMat是如何影响性能的,我编写了一个小程序来了解我的好ol’i5 3330/Radeon HD 7970的增益,结果如图1所示。
Figure 1 – Time comparison of Mat and UMat
图1–Mat和UMat的时间比较
The gain is substantial, the UMat took approximately 10% of Mat’s time in all cases. You can try and measure by yourself on your PC, the code is on my Github. You will just need to install OpenCV with the flag WITH_OPENCL set as on for it to work.
收益是巨大的,UMat在所有情况下都花费了Mat大约10%的时间。可以试着在电脑上自己测量,代码在我的Github上。只需要安装OpenCV,并将标志WITH_OPENCL设置为打开即可使其工作。
Ok, why don’t use UMat everywhere?
好吧,为什么不在任何地方使用UMat呢?
This huge performance improvement is enough to make everyone ask: “Ok why don’t change all my Mats to UMats?”. Over the internet, this adaptation seems to be strongly recommended. However, Intel says:
这种巨大的性能改进足以让每个人都问:“好吧,为什么不把我所有的Mat都改成UMats呢?”。在互联网上,这种改编似乎被强烈推荐。然而,英特尔表示:
Use the cv::UMat Datatype, But Not Everywhere. Use cv::UMat for images, and continue to use cv::Mat for other smaller data structures such as convolution matrices, transpose matrices, and so on.
使用cv::UMat数据类型,但不是无处不在。对图像使用cv::UMat,对其他较小的数据结构(如卷积矩阵、转置矩阵等)继续使用cv::Mat。
Also, the conversion of big code bases will probably not going to be as trivial as it sounds. Each case is different, a deep analysis of the problem must be considered.
此外,大代码库的转换可能不会像听起来那么琐碎。每种情况都不同,必须对问题进行深入分析。