赞
踩
opencv在4.2.0版本正式发布,DNN深度神经网络模块集成Google Summer of Code的项目CUDA后端支持。(详细changelog)
常规编译过程,这里使用软硬件环境如下:
这里建议使用高版本的vs,vs2015编译源码会有cuda设备相关代码的错误,作者已经修复,在下版本可正常使用。后面会给出在vs2015使用的解决办法。
确保勾选 WITH_CUDA
,WITH_CUDNN
,以及OPENCV_DNN_CUDA
等选项。
若cuda、cndnn等环境安装正常,点击config后会自动填入相关cuda、dnn的环境包括头文件、库的路径。
如下:
之后点击generate,等待下载相关依赖第三方的包完成。
若下载缓慢,可以查看build目录下的CMakeDownloadLog.txt文件,找到路径手动下载,按照文件提示放入指定目录,一般在source/.cache中。
(若提示cuda_arch_bin的版本要求,根据自己显卡算力填写相应的值,我使用gtx 1080ti,设置“6.1 7.0 7.5”)
linux下可以使用:
cmake -BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/home/opencv/opencv-4.2.0/build/install -DOPENCV_EXTRA_MODULES_PATH=/home/opencv/opencv-4.2.0/opencv_contrib-4.2.0/modules -DOPENCV_DNN_CUDA=True -DWITH_CUDA=True -DCUDA_ARCH_BIN=“6.1 7.0 7.5” -DBUILD_TESTS=False
generate成功后,打开项目,编译即可。
使用vs2015编译,唯独opencv_dnn模块的库会生成失败,其他正常。
查看报错问题,如下:
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(16): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getGridDim<0>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(17): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getGridDim<1>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(18): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getGridDim<2>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(21): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockDim<0>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(22): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockDim<1>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(23): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockDim<2>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(26): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockIdx<0>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(27): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockIdx<1>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(28): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getBlockIdx<2>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(31): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getThreadIdx<0>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(32): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getThreadIdx<1>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda\grid_stride_range.hpp(33): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getThreadIdx<2>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda4dnn\csl\cudnn/cudnn.hpp(41): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷cudnnDataType_t cv::dnn::cuda4dnn::csl::cudnn::detail::get_data_type<__half>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
4>d:\opencv\opencv4.2.0\sources\modules\dnn\src\cuda4dnn\csl\cudnn/cudnn.hpp(42): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷cudnnDataType_t cv::dnn::cuda4dnn::csl::cudnn::detail::get_data_type(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
对应错误代码位置为
解决方案:
(1)修改sources\modules\dnn\src\cuda\grid_stride_range.hpp文件
替换15-33行为:
using dim3_member_type = decltype(dim3::x);
template <int> __device__ dim3_member_type getGridDim();
template <> inline __device__ dim3_member_type getGridDim<0>() { return gridDim.x; }
template <> inline __device__ dim3_member_type getGridDim<1>() { return gridDim.y; }
template <> inline __device__ dim3_member_type getGridDim<2>() { return gridDim.z; }
template <int> __device__ dim3_member_type getBlockDim();
template <> inline __device__ dim3_member_type getBlockDim<0>() { return blockDim.x; }
template <> inline __device__ dim3_member_type getBlockDim<1>() { return blockDim.y; }
template <> inline __device__ dim3_member_type getBlockDim<2>() { return blockDim.z; }
using uint3_member_type = decltype(uint3::x);
template <int> __device__ uint3_member_type getBlockIdx();
template <> inline __device__ uint3_member_type getBlockIdx<0>() { return blockIdx.x; }
template <> inline __device__ uint3_member_type getBlockIdx<1>() { return blockIdx.y; }
template <> inline __device__ uint3_member_type getBlockIdx<2>() { return blockIdx.z; }
template <int> __device__ uint3_member_type getThreadIdx();
template <> inline __device__ uint3_member_type getThreadIdx<0>() { return threadIdx.x; }
template <> inline __device__ uint3_member_type getThreadIdx<1>() { return threadIdx.y; }
template <> inline __device__ uint3_member_type getThreadIdx<2>() { return threadIdx.z; }
(2) 修改sources\modules\dnn\src\cuda4dnn\csl\cudnn\cudnn.hpp文件
替换40-42行为:
using cudnn_data_enum_type = decltype(CUDNN_DATA_FLOAT);
template <class> cudnn_data_enum_type get_data_type();
template <> inline cudnn_data_enum_type get_data_type<half>() { return CUDNN_DATA_HALF; }
template <> inline cudnn_data_enum_type get_data_type<float>() { return CUDNN_DATA_FLOAT; }
之后保存,重新编译即可成功。
详细的性能提升说明见 https://github.com/opencv/opencv/pull/14827,这里给出几张相关截图。
(1)dnn支持cuda加速的层
(2)常见模型执行效率
这里测试使用的NVIDIA GTX 1080ti显卡
(3)opencv cuda 和Tensorflow duda执行效率
(4)yolo3效率对比
这里使用的是 NVIDIA RTX 2080ti显卡。
这里的对比测试和opencv dnn模块 示例(3) 目标检测 object_detection (2) YOLO object 进行对比。使用相同场景,相同模型,相同的代码。
这里使用opencv4.2时,需要修改上述文章中34.35两行代码
//int backendId = cv::dnn::DNN_BACKEND_OPENCV;
//int targetId = cv::dnn::DNN_TARGET_CPU;
int backendId = cv::dnn::DNN_BACKEND_CUDA;
int targetId = cv::dnn::DNN_TARGET_CUDA;
使用opencv作为后端,执行效率在360ms左右。
这里使用cuda作为后端,执行效率在16ms左右,提升效率近22倍。
资源占用如下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。