opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速

目录

前言:

一、环境准备:

1、基本环境:

2、下载opencv源码

3、下载opencv_contrib模块

二、cmake 编译:

1、第一次"configure" 与缺失文件

2、编译项设置:

3、再次"configure"错误与缺失文件

三、工程编译

四、错误解决方法:

1、文件download失败解决方法:

2、错误        identifier "LINE_8" is undefined   

3、乱码+“cv::dnn::cuda4dnn::csl::device::detail::getBlockDim” 错误

4、错误未定义标识符 "blockDim"  等   


前言:

2019年12月23日,OpenCV 4.2.0版本官方发布并开放下载,这次更新的特性并不多,但非常重要的是:DNN终于支持CUDA啦!!

得知发布后,看到一直心心念的DNN模块终于支持CUDA了,再也按捺不住躁动的心,就开始下载编译了。

 

一、环境准备:

1、基本环境:

windows7 + VS2015+ CUDA 10.0+CUDNN 7.6.5

CUDNN版本要求不低于7.5

2、下载opencv源码

opencv官网https://opencv.org/releases/

下载方式有多种,可以直接下载源码,windows安装exe,或者去opencv的github主页下载。

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第1张图片

我这里直接下载windows安装文件,

https://sourceforge.net/projects/opencvlibrary/files/4.2.0/opencv-4.2.0-vc14_vc15.exe/download

下载后双击解压到"E:\opencv4.2"路径,解压后包含build和sources两部分。

3、下载opencv_contrib模块

github主页,直接下载源码,或者下载压缩包,下载后解压到了"E:\opencv4.2"路径。

 

二、cmake 编译:

1、第一次"configure" 与缺失文件

cmake安装可参考之前博客

打开cmake-gui.exe,选择源码路径和生成二进制路径,如下图

然后点一下config按钮,选择“Visual Studio 14 2015 Win64”

然后开始等待,config过程中会下载一些文件,包含下列文件

ippicv_2019_win_intel64_20180723_general.zip

opencv_videoio_ffmpeg.dll

opencv_videoio_ffmpeg_64.dll

ffmpeg_version.cmake

如果在下载过程中没有出错,恭喜你已经成功跳开了一个大坑。如果文件下载失败了,处理起来相对复杂,请参考本文本第四部分的解决方法。

等手动下载工作完成后,再次点击config, 保证日志内没有红色的下载失败信息

最后剩余了一个红色警告: 不用管它

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第2张图片

2、编译项设置:

这里主要关注CUDA编译,一些暂时用不到的测试模块及PYTHON模块去掉。

1、cuda

OPENCV_DNN_CUDA     选中

WITH_CUDA                       选中

2、BUILD_opencv_world        选中

3、test选项  不选

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第3张图片

4、BUILD_opencv_python.. 三个选项   不选

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第4张图片

5、OPENCV_EXTRA_MODULES_PATH 设置为“E:\opencv4.2\opencv_contrib-master\modules”

3、再次"configure"错误与缺失文件

有可能会出现错误:

CMake Error at modules/dnn/CMakeLists.txt:99 (message):
  CUDA backend for DNN module requires CC 5.3 or higher.  Please remove
  unsupported architectures from CUDA_ARCH_BIN option.
Call Stack (most recent call first):
  modules/world/CMakeLists.txt:13 (include)
  modules/world/CMakeLists.txt:32 (include_one_module)

只需将CUDA_ARCH_BIN中小于5.3的选项去掉

再次点击"configure"

如果之前出现文件下载失败,这次同样可能会出现类似下面的错误

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第5张图片

同样参考第四部分的解决方法

“configure”不再有下载错误后,依次点击“Generate”,“Open Project”按钮,用VS2015开工程

三、工程编译

用VS2015打开后,选择“release”模式,

选择ALL_BUILD 生成。

如果出现   错误        identifier "LINE_8" is undefined 请参考下面解决方法。

如果出现   错误:乱码+unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockDim等错误,参考下面解决方法。    

编译完成后,选择INSTALL 生成。

生成的文件就保存到“e:\opencv4.2\opencv\sources\buildnew\install”文件夹内

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第6张图片

e:\opencv4.2\opencv\sources\buildnew\install\x64\vc14\bin 目录里有生成的DLL

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第7张图片

可以看到,编译的DLL比原来的大不少。

四、错误解决方法:

1、文件download失败解决方法:

文件下载失败和网络有关系,而且一旦失败就会有多个文件下载失败,下面以第一个下载失败文件为例,进行说明,日志如下

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第8张图片

从上面可以看出,下载日志在保存在“E:\opencv4.2\opencv\sources\build\CMakeDownloadLog.txt”文件内,打开文件,搜索"ippicv",  第三行即为本文件信息

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第9张图片

其中上面为本地缓存路径,下面为下载网址,直接复制网址到浏览器下载,如果浏览器也下载失败,可以尝试将地址复制到迅雷进行下载,

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第10张图片

下载后保存到“E:/opencv4.2/opencv/sources/.cache/ippicv/”目录,删除目录内大小0KB的文件(如果有), 并按照d222685246896fe089f88b8858e4b2f-ippicv_2019_win_intel64_20180723_general.zip重命名

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第11张图片

其它下载失败的文件可以用同样的方法进行处理。

如果迅雷仍然下载失败,可直接访问 //download.csdn.net/download/length85/12066165 下载,我已将下载可能失败的文件都打包在一起了, 下载设置了1分,没分的朋友可直接私信我。

2、错误        identifier "LINE_8" is undefined   

 

点开错误,我震惊了,发现"imgproc.hpp"竟然链接到了anconda安装环境中, "C:\Users\kc\Anaconda3\Library\include\opencv2", 猜测是安装环境添加到了系统变量,由于我电脑安装东西比较多,暂时把该目录下的opencv2重命名为opencv2_,opencv重命名为opencv_, 再重新编译,错误消失。

注:编译结束后重新把文件夹名修改回去,以免影响其它功能。

同样,如果出现GOOGLE_PROTOBUF_VERSION版本错误,且错误定位到了下面位置

opencv4.2.0 源码编译,win7+VS2015,DNN模块支持cuda加速_第12张图片

将C:\Users\kc\Anaconda3\Library\include目录下的google重命名为google_

3、乱码+“cv::dnn::cuda4dnn::csl::device::detail::getBlockDim” 错误

错误如下图:

中文显示乱码,搜索微软C2912错误描述为:显式专用化“declaration”不是函数模板的专用化,无法特化非模板函数。

这里采用修改方法:

cudnn.hpp文件,将报错行的decltype部分去掉

#if 0
        template  auto get_data_type()->decltype(CUDNN_DATA_FLOAT);
        template <> inline auto get_data_type()->decltype(CUDNN_DATA_HALF) { return CUDNN_DATA_HALF; }
        template <> inline auto get_data_type()->decltype(CUDNN_DATA_FLOAT) { return CUDNN_DATA_FLOAT; }
#else
	template  auto get_data_type();
	template <> inline auto get_data_type() { return CUDNN_DATA_HALF; }
	template <> inline auto get_data_type() { return CUDNN_DATA_FLOAT; }
#endif

grid_stride_range.hpp 文件,同样方法修改

#if 0
        template   __device__ auto getGridDim()->decltype(dim3::x);
        template <> inline __device__ auto getGridDim<0>()->decltype(dim3::x) { return gridDim.x; }
        template <> inline __device__ auto getGridDim<1>()->decltype(dim3::x) { return gridDim.y; }
        template <> inline __device__ auto getGridDim<2>()->decltype(dim3::x) { return gridDim.z; }

        template  __device__ auto getBlockDim()->decltype(dim3::x);
        template <> inline __device__ auto getBlockDim<0>()->decltype(dim3::x) { return blockDim.x; }
        template <> inline __device__ auto getBlockDim<1>()->decltype(dim3::x) { return blockDim.y; }
        template <> inline __device__ auto getBlockDim<2>()->decltype(dim3::x) { return blockDim.z; }

        template  __device__ auto getBlockIdx()->decltype(uint3::x);
        template <> inline __device__ auto getBlockIdx<0>()->decltype(uint3::x) { return blockIdx.x; }
        template <> inline __device__ auto getBlockIdx<1>()->decltype(uint3::x) { return blockIdx.y; }
        template <> inline __device__ auto getBlockIdx<2>()->decltype(uint3::x) { return blockIdx.z; }

        template  __device__ auto getThreadIdx()->decltype(uint3::x);
        template <> inline __device__ auto getThreadIdx<0>()->decltype(uint3::x) { return threadIdx.x; }
        template <> inline __device__ auto getThreadIdx<1>()->decltype(uint3::x) { return threadIdx.y; }
        template <> inline __device__ auto getThreadIdx<2>()->decltype(uint3::x) { return threadIdx.z; }
#else 
	template   __device__ auto getGridDim();
	template <> inline __device__ auto getGridDim<0>() { return gridDim.x; }
	template <> inline __device__ auto getGridDim<1>() { return gridDim.y; }
	template <> inline __device__ auto getGridDim<2>() { return gridDim.z; }

	template  __device__ auto getBlockDim();
	template <> inline __device__ auto getBlockDim<0>() { return blockDim.x; }
	template <> inline __device__ auto getBlockDim<1>() { return blockDim.y; }
	template <> inline __device__ auto getBlockDim<2>() { return blockDim.z; }

	template  __device__ auto getBlockIdx();
	template <> inline __device__ auto getBlockIdx<0>() { return blockIdx.x; }
	template <> inline __device__ auto getBlockIdx<1>() { return blockIdx.y; }
	template <> inline __device__ auto getBlockIdx<2>() { return blockIdx.z; }

	template  __device__ auto getThreadIdx();
	template <> inline __device__ auto getThreadIdx<0>() { return threadIdx.x; }
	template <> inline __device__ auto getThreadIdx<1>() { return threadIdx.y; }
	template <> inline __device__ auto getThreadIdx<2>() { return threadIdx.z; }
#endif


4、错误未定义标识符 "blockDim"  等   

在grid_stride_range.hpp文件内添加头文件包含,

#include 

总结:我在两台电脑上测试,遇到的情况不一样,可能跟GPU的型号配置有关,也可能有些编译我没遇到,欢迎留言讨论。    


 

你可能感兴趣的:(opencv)