之前老板已经编译好了OpenCV3.2.0 ,但是好像无法使用ocl模块?
所以我想应该是他当初编译的时候没有选择WITH_OPENCL,所以我决定重新编译一遍。
一、下载CMake并安装
1、我下载的是CMake3.4.0并安装完毕(教程网上有太多 就不重复);
但我运行./configure时出现:
解决办法:yum install ncurses-devel 如果下载不了,就自己手动下载:我是手动下载的:ncurses-devel-5.9-14.20130511.el7_4.x86_64.rpm (然后用rpm命令安装即可)。
2、安装cmake-gui
yum install cmake-gui
检验是否安装成功 :直接运行 cmake-gui 即可出现cmake界面
二、下载安装OpenCV
我是手动去官网下载OpenCV3.2.0.tar.gz的,然后解压在opencv-OpenCL-3.2.0文件夹下。
三、编译OpenCV-OCL
1、新建一个OpenCV3.2_With_OpenCL文件夹
2、终端下运行cmake-gui打开界面
3、像下面那样填写目录,开始编译:(等了很久)
a.我试着手动下载这个红色部分提示缺少的文件:ippicv_linux_20151201.tgz
https://raw.githubusercontent.com/Itseez/opencv_3rdparty/81a676001ca8075ada498583e4166079e5744668/ippicv/ippicv_linux_20151201.tgz 在这里下载。如果这个下载不了就在: http://download.csdn.net/download/chu_ying/9432287 下载。
然后,将刚才下载的文件直接拷贝进入opencv3.1源码的下面这个目录:opencv-OpenCL-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e
类似这个目录下。
b.终端下打开cmake-gui 点击configure 就会接着之前失败的地方进行(这次速度很快):
c.点击generate (速度比较快)(没有出现什么错误)
d.在文件夹OpenCV3.2_With_OpenCL下打开终端 运行 make (出现很多东西 等待。。。)
e.接着运行 make install
这样编译好的OpenCV3.2.0的lib和include原来都在usr/include/下面 ,去找就找到了。(其实最好不搞在这里 开始应该指定目录的)
可以在此运行 opencv_version -v 应该出现像我一样的画面:
这样创建工程时加上库路径和头文件路径等 就OK了。运行了一个简单例子,成功。
奇怪之处:在记录这篇文章之前 我的OpenCL版本是2.0的:
但这次编译之后却变成了1.2的了?tell me why????????哦我知道了,不是编译的原因,而是硬件原因:我的驱动是OpenCL2.0,但我的显卡是Rx 560不支持OpenCL 2.0 只支持OpenCL1.2 !!! ps:大神说:当前能支持OpenCL 2.0的是 AMD GPU基于GCN 1.1或更高版本架构的GPU,比如R9 285支持。R9 3XX很多都支持。另外就是Broadwell处理器架构或更新架构的Intel HD(或Iris) Graphics能支持。
刚刚查了下:GPU型号与OpenCL版本支持关系:https://en.wikipedia.org/wiki/List_of_AMD_graphics_processing_units
Chip series | Micro-architecture | Fab | Supported APIs | Introduced with | ||||
---|---|---|---|---|---|---|---|---|
rendering | computing | |||||||
Vulkan | OpenGL[4] | Direct3D | HSA | OpenCL | ||||
R100 | fixed-pipeline | 180 nm 150 nm |
No | 1.3 | 7.0 | No | No | Original "ATI Radeon", as well as Radeon DDR, 7000, 7500, VE, and LE models |
R200 | programmable pixel&vertex pipelines | 150 nm | 1.4 | 8.1 | 8500, 9000, 9200 and 9250 | |||
R300 | 150 nm 130 nm 110 nm |
2.0 | 9.0 11 (FL 9_2) |
9500–9800, X300-X600, X1050 | ||||
R420 | 130 nm 110 nm |
9.0b 11 (FL 9_2) |
X700–X850 | |||||
R520 | 90 nm 80 nm |
9.0c 11 (FL 9_3) |
X1300–X1950 | |||||
R600 | TeraScale 1 | 80 nm 65 nm |
3.3 | 10.0 11 (FL 10_0) |
ATI Stream | HD 2000 series, HD 3410 | ||
RV670 | 55 nm | 10.1 11 (FL 10_1) |
ATI Stream APP[5] | HD 3450-3870, Mobility HD 2000 and 3000 series | ||||
RV770 | 55 nm 40 nm |
1.0 | HD 4000 series | |||||
Evergreen | TeraScale 2 | 40 nm | 4.4 | 11 (FL 11_0) 12 (FL 11_0) |
1.2 | HD 5000 series | ||
Northern Islands | TeraScale 3 | HD 6000 series, and IGP 7000 series | ||||||
Southern Islands | GCN 1st gen | 28 nm | 1.0 | 4.5 | 11 (FL 11_1) 12 (FL11_1) |
Yes | 1.2, new driver 2.0 possible | HD 7000 series |
Sea Islands | GCN 2nd gen | 11 (FL 12_0) 12 (FL 12_0) |
2.0 (2.1 in Beta and 2.2 with driver update) | Radeon 200 series | ||||
Volcanic Islands | GCN 3rd gen | Radeon 300 series | ||||||
Arctic Islands | GCN 4th gen | 14 nm | Radeon 400 series | |||||
Vega | Vega | 12 (FL 12_1) | Radeon VEGA series |
四、运行ocl的例子
但运行ocl的例子时还是报错说:oclMat 不是‘cv::ocl’成员 ??
最近谷歌打不开。
终于知道了:http://blog.csdn.net/jia20003/article/details/69802932 原来OpenCV3.x后使用UMat取代了OpenCV2.x的oclMat!难怪无论是我编译的还是之前老板编译的OpenCV3.2使用oclMat都错的!(不过发现还是要自己编译,最好不用老板编译好的,因为刚刚发现老板编译好的include下没有3rdparty更没有CL文件夹,所以想了下,如果不要用到opencv-ocl模块,还是可以用老板编译的版本;但如果要用opencv-ocl模块,还是用我自己编译的)用UMat就好了!UMat就是以前的oclMat!
1、UMat(ocl)小例子
按照这个人的介绍 UMat即是ocl,我的设备支持OpenCL,故启动UMat就是启动了GPU运行。 我这个例子应该是在GPU上,但耗时是341 ms。
2、对比原opencv程序
原来的纯CPU的程序:
这个耗时只要19ms!!!
3、对比我自己写的纯OpenCL程序
我自己写了一个纯OpenCL的腐蚀:
当然这个没太多可比性,只是一个参考数据!因为UMat那个参杂了Mat到UMat的转化(需要时间),或者可能这个简单的运算并不适合GPU并行?!
后来看了 https://stackoverflow.com/questions/41688751/understanding-the-usage-of-opencl-in-opencv-mat-umat-objects
又用这个例子试了下:main.cpp
#include
#include
#include
#include
using namespace cv;
using namespace cv::ocl;
using namespace std;
int main()
{
TickMeter tm;
tm.start();
//launch OpenCL environment...
std::vector plats;
cv::ocl::getPlatfomsInfo(plats);
const cv::ocl::PlatformInfo *platform=&plats[0];
// cout<<"Platform name: "<name().c_str()<getDevice(current_device,0);
// cout<<"Device name: "<
结果发现时间还是很慢啊!?个人觉得:这个不适合用OpenCL 这么一点又没什么计算量 时间当然比用纯CPU的API多!
CV_OCL_RUN(_m.dims() <= 2 && _mv.isUMatVector(),
ocl_split(_m, _mv))
说明,OpenCV3.x版本的纯CPU的API中都有了GPU的判断接口,如果判断是UMat,则启动这个API的GPU版本的函数!否则启动以前的老的纯CPU版本的函数!
#include
#include
#include
#include
using namespace cv;
using namespace cv::ocl;
using namespace std;
int main()
{
TickMeter tm;
tm.start();
//launch OpenCL environment...
std::vector plats;
cv::ocl::getPlatfomsInfo(plats);
const cv::ocl::PlatformInfo *platform=&plats[0];
// cout<<"Platform name: "<name().c_str()<getDevice(current_device,0);
// cout<<"Device name: "<
像我这个文件中的灰度转换、阈值化、存图、腐蚀都是在GPU上!
当然等谷歌重新开放时我会再次查证!
我刚刚又看了OpenCV3.1的源码:(只是看了一部分,几个库中)
1、发现图像校正、图像轮廓、ml中的所有函数都没有OpenCL加速版本!
2、只要是#include "opencl_kernels_....hpp" 的都有OpenCL版本的API!如:图像分离与合成、形态学操作、阈值化、平滑滤波、边缘检测、Harris角点检测相关的(比如梯度矩阵的最小特征值cornerMinEigenVal())、特征检测、直方图检测、霍夫直线检测、图像缩放、图像的几何变换、图像金字塔等相关的API都有相应的OpenCL版本!
他还说:
通过Mat::getUMat()之后就获取一个UMat对象,同样在UMat对象操作期间,作为父对象Mat也会被LOCK直到子对象UMat销毁之后才可以继续使用。
OpenCV的官方文档说不鼓励在一个方法和一段代码中同时使用Mat与UMat两种方式,因为这样做真的非常危险。此外Mat与UMat还可以相互拷贝,但是这种方式也不是OpenCV官方提倡与推荐的,所以尽量别用这种方式。
参考了 http://www.cnblogs.com/emouse/archive/2013/02/22/2922940.html