OpenCV Transparent API

来源:互联网 发布:下载应用的软件 编辑:程序博客网 时间:2024/06/05 21:58

>此文章内容源自人工智能研究 www.studyai.cn


>一个牛逼的大师能用短短的几句话给你讲一个牛逼的故事。

一个牛逼的艺术家可以使用很少的东西做出非常牛逼的艺术品。这一牛逼原理同样适用于那些牛逼的码农和牛逼的工程师。 他们似乎总是寻求额外的盎司的性能从他们的机器.。这就是伟大与平庸之间的区别。 这一神奇的秘密是如此的浅显易懂而且早就被公之于众. 然而不幸的是牛逼的人物如此凤毛麟角而泛泛平庸之辈却多如牛毛.

在此博客中你将学到最简单易用但是却最最重要的OpenCV3.x技能,这将会极大的提升你的牛逼度。这一技能的名字就叫 Transparent API ( T-api or TAPI ).

啥是Transparent API ( T-API or TAPI ) ?

Transparent API 是一个简单的方法,可以以对现有代码最少的修改无缝添加硬件来加速你的opencv代码。你可以让你的代码加快几乎一个数量级的速度通过一个可笑的小变化。

使用 Transparent API 超级简单. 你可以获得显著的性能提升仅仅多敲击一下键盘上的某个按键。

不相信我?下面的例子是一个标准的opencv代码不使用Transparent API 。它读取一个图像,将其转换为灰度图,采用高斯模糊,最后是Canny边缘检测。

#include "opencv2/opencv.hpp"using namespace cv;int main(int argc, char** argv){    Mat img, gray;    img = imread("image.jpg", 1);    cvtColor(img, gray, COLOR_BGR2GRAY);    GaussianBlur(gray, gray,Size(7, 7), 1.5);    Canny(gray, gray, 0, 50);    imshow("edges", gray);    waitKey();    return 0;}

如果上面的代码用 Transparent API 重写, 会是啥样子呢?.

OpenCV Transparent API 的例子

我稍微修改了一下上面的代码来使用 Transparent API. 所做的修改只有两句,已经被我标志出来了。注意到我们所做的全部工作只是将Mat格式的image拷贝到UMat ( Unified Matrix ) 中,然后就可以像以前一样使用OpenCV的函数了.

#include "opencv2/opencv.hpp"using namespace cv;int main(int argc, char** argv){    UMat img, gray;  //不一样的地方    imread("image.jpg", 1).copyTo(img);//不一样的地方    cvtColor(img, gray, COLOR_BGR2GRAY);    GaussianBlur(gray, gray,Size(7, 7), 1.5);    Canny(gray, gray, 0, 50);    imshow("edges", gray);    waitKey();    return 0;}

在我的笔记本上运行上面的代码比原来快了5倍多。

我们来快速总结一下使用 Transparent API 的几个步骤。
第一步: . 转换 Mat 到 UMat. 有两种方法可以实现这样的转换:

Mat mat = imread("image.jpg", IMREAD_COLOR); // Copy Mat to UMatUMat umat; mat.copyTo(umat);

或者你可以使用 函数: getUMat

Mat mat = imread("image.jpg", IMREAD_COLOR); // Get umat from umat. UMat umat = mat.getUMat( flag );

参数 flag 可以取的值有以下几个:* ACCESS_READ, ACCESS_WRITE, ACCESS_RW and ACCESS_FAST*.

第二步: Use standard OpenCV functions that you would use with Mat.
第三步: If necessary, convert UMat back to Mat.. Most of the time you do not need to do this. Here is how you do it in case you need to.

Mat mat = umat.getMat( flag );

where umat is a UMat image. flag is the same as described above.

Now we know how to use the Transparent API. So what is under the hood that magically improves performance ? The answer is OpenCL. In the section below I briefly explain OpenCL.

啥是 OpenCL ?

异构平台(heterogeneous platform)是现在常见的计算设备所采取的架构,通常由多核CPU,多核GPU,以及DSP等组成。在一般的电脑和智能手机上都有这些计算设备。
OpenCL 是一个用于异构平台(heterogeneous platform)下编写并行程序的框架. OpenCL 的开发者可以使用所有可用的兼容计算设备, 他们找到计算机上的相应设备,然后将合适的计算任务分配给这些设备。 但是OpenCV开发者无须知道任何关于OpenCL的底层实现,因为OpenCV已经将OpenCL的细节隐藏在了 Transparent API 中.

OCL Module and Transparent API有撒区别 ?

一言以蔽之,OCL Module 已经死掉了,T-API 将会永生!

OpenCL was supported in OpenCV 2.4 via the OCL module. There were a set of functions defined under the ocl namespace that you could use to call the underlying OpenCL code. Below is an example for reading an image, and using OpenCL to convert it to grayscale.

// Example for using OpenCL is OpenCV 2.4// In OpenCV 3 the OCL module is gone. // It is replaced by the much nicer Transparent API// Initialize OpenCLstd::vector<ocl::Info> param;ocl::getDevice(param, ocl::CVCL_DEVICE_TYPE_GPU);// Read imageMat im = imread("image.jpg"); // Convert it to oclMat ocl::oclMat ocl_im(im);// Container for OpenCL gray image. ocl::oclMat ocl_gray; // BGR2GRAY using OpenCL. cv::ocl::cvtColor( ocl_im, ocl_gray, CV_BGR2GRAY );// Container for OpenCV Mat gray image. Mat gray; // Convert back to OpenCV Matocl_gray.download(gray);

As you can see it was a lot more cumbersome. With OpenCV 3 the OCL module is gone! All this complexity is hidden behind the so-called transparent API and all you need to do is use UMat instead of Mat and the rest of the code remains unchanged. You just need to write the code once!

1 0
原创粉丝点击