Linux编译OpenCV3.2.0-OCL模块并使用
2017-10-12 09:52
477 查看
之前老板已经编译好了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 下载。
类似这个目录下。
b.终端下打开cmake-gui 点击configure 就会接着之前失败的地方进行(这次速度很快):
发现那个WITH_OPENCL竟然是自动选上的。
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
四、运行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的腐蚀:
我这个耗时是129 ms!!!
当然这个没太多可比性,只是一个参考数据!因为UMat那个参杂了Mat到UMat的转化(需要时间),或者可能这个简单的运算并不适合GPU并行?!
后来看了 https://stackoverflow.com/questions/41688751/understanding-the-usage-of-opencl-in-opencv-mat-umat-objects
又用这个例子试了下:main.cpp
就相当于 杀鸡用牛刀和水果刀的区别 : 牛刀切开鸡脖子比水果刀快 但牛刀重 ,举起来就要花很久 而水果刀轻方便拿!!!
五、总结
刚刚在windows下查看了OpenCV3.1的源码,发现opencv_core和opencv_highgui库下有很多核函数即cl文件:
图中这个cv::split()就是我们以前常用的纯opencv函数纯CPU的!
然后再看下面这个:这个opencv的gpu版本即ocl版本的split()函数,即这个函数启动时会在GPU上运行!看这里有核函数、globalsize及run等
而第一个图的这句话:
所以:只要是硬件条件支持OpenCL、为工程添加所需的OpenCL库及头文件、在main中添加进ocl命名空间、使用UMat ,只要满足这4个条件那么就是在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
所以我想应该是他当初编译的时候没有选择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 就会接着之前失败的地方进行(这次速度很快):
发现那个WITH_OPENCL竟然是自动选上的。
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的腐蚀:
我这个耗时是129 ms!!!
当然这个没太多可比性,只是一个参考数据!因为UMat那个参杂了Mat到UMat的转化(需要时间),或者可能这个简单的运算并不适合GPU并行?!
后来看了 https://stackoverflow.com/questions/41688751/understanding-the-usage-of-opencl-in-opencv-mat-umat-objects
又用这个例子试了下:main.cpp
#include <opencv2/core/ocl.hpp> #include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> using namespace cv; using namespace cv::ocl; using namespace std; int main() { TickMeter tm; tm.start(); //launch OpenCL environment... std::vector<cv::ocl::PlatformInfo> plats; cv::ocl::getPlatfomsInfo(plats); const cv::ocl::PlatformInfo *platform=&plats[0]; // cout<<"Platform name: "<<platform->name().c_str()<<endl; cv::ocl::Device current_device; platform->getDevice(current_device,0); // cout<<"Device name: "<<current_device.name().c_str()<<endl; current_device.set(0); ocl::setUseOpenCL(true); cv::UMat test_ocl_img; imread("/home/jumper/Ecology_OpenCL/erodecontrasttest/test.bmp").copyTo(test_ocl_img); cv::UMat test_gray_img(test_ocl_img.rows,test_ocl_img.cols,CV_8UC1); cvtColor(test_ocl_img, test_gray_img, CV_BGR2GRAY); threshold(test_gray_img, test_gray_img, 40, 255, 0); imwrite("ocltemp.bmp",test_gray_img); cv::UMat element_img; getStructuringElement(MORPH_RECT, Size(2, 2)).copyTo(element_img); erode(test_gray_img, test_gray_img, element_img); tm.stop(); std::cout<<"count="<<tm.getCounter()<<" ,process time="<<tm.getTimeMilli()<<" ms."<<std::endl; return 0; }结果发现时间还是很慢啊!?个人觉得:这个不适合用OpenCL 这么一点又没什么计算量 时间当然比用纯CPU的API多!
就相当于 杀鸡用牛刀和水果刀的区别 : 牛刀切开鸡脖子比水果刀快 但牛刀重 ,举起来就要花很久 而水果刀轻方便拿!!!
五、总结
刚刚在windows下查看了OpenCV3.1的源码,发现opencv_core和opencv_highgui库下有很多核函数即cl文件:
图中这个cv::split()就是我们以前常用的纯opencv函数纯CPU的!
然后再看下面这个:这个opencv的gpu版本即ocl版本的split()函数,即这个函数启动时会在GPU上运行!看这里有核函数、globalsize及run等
而第一个图的这句话:
CV_OCL_RUN(_m.dims() <= 2 && _mv.isUMatVector(), ocl_split(_m, _mv))说明,OpenCV3.x版本的纯CPU的API中都有了GPU的判断接口,如果判断是UMat,则启动这个API的GPU版本的函数!否则启动以前的老的纯CPU版本的函数!
所以:只要是硬件条件支持OpenCL、为工程添加所需的OpenCL库及头文件、在main中添加进ocl命名空间、使用UMat ,只要满足这4个条件那么就是在GPU上运行的!!!
#include <opencv2/core/ocl.hpp> #include <opencv2/opencv.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> using namespace cv; using namespace cv::ocl; using namespace std; int main() { TickMeter tm; tm.start(); //launch OpenCL environment... std::vector<cv::ocl::PlatformInfo> plats; cv::ocl::getPlatfomsInfo(plats); const cv::ocl::PlatformInfo *platform=&plats[0]; // cout<<"Platform name: "<<platform->name().c_str()<<endl; cv::ocl::Device current_device; platform->getDevice(current_device,0); // cout<<"Device name: "<<current_device.name().c_str()<<endl; current_device.set(0); ocl::setUseOpenCL(true); cv::UMat test_ocl_img; imread("/home/jumper/Ecology_OpenCL/erodecontrasttest/test.bmp").copyTo(test_ocl_img); cv::UMat test_gray_img(test_ocl_img.rows,test_ocl_img.cols,CV_8UC1); cvtColor(test_ocl_img, test_gray_img, CV_BGR2GRAY); threshold(test_gray_img, test_gray_img, 40, 255, 0); imwrite("ocltemp.bmp",test_gray_img); cv::UMat element_img; getStructuringElement(MORPH_RECT, Size(2, 2)).copyTo(element_img); erode(test_gray_img, test_gray_img, element_img); tm.stop(); std::cout<<"count="<<tm.getCounter()<<" ,process time="<<tm.getTimeMilli()<<" ms."<<std::endl; return 0; }像我这个文件中的灰度转换、阈值化、存图、腐蚀都是在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
相关文章推荐
- 使用OpenCV的OpenCL(ocl)模块
- 使用OpenCV的OpenCL(ocl)模块
- Linux下使用内核源码单独编译某一模块
- 编译并使用带有OpenCL模块的OpenCV for android SDK
- Opencv中使用ocl模块遇到的问题
- 使用OpenCV的OpenCL(ocl)模块
- 使用OpenCV的OpenCL(ocl)模块
- Ubuntu/Linux编译Opencv3.2(包括使用)//有问题欢迎留言交流
- 【ZYNQ_LINUX】使用ubuntu 编译opencv 代码
- linux下gcc编译使用opencv的源文件时报错的处理:undefined reference to symbol '_ZNSsD1Ev@@GLIBCXX_3.4'
- opencv3.2.0+opencv_contrib扩展模块+VS2015+CMake 编译opencv(完美解决编译错误)
- linux python 视频设备控制模块 openCV 编译安装与测试
- Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9
- 在android上使用opencv的ocl模块遇到的问题(一)
- OpenCV在linux平台的编译、安装和使用
- OpenCV contrib 3.2.0扩展模块添加与编译(VS2017+OpenCV3.2.0)详解与排坑
- 如何编译OpenCV里面的ocl模块
- OpenCV 及 OpenCV Samples 在 Window, Linux上的编译及使用
- linux下如何不编译opencv的某些模块
- VS2010上单独编译ocl模块(opencv248)