cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第1张图片

之前编译过很多次opencv,但第一次为python编译,中间走了不少弯路。

一、准备环境

  1. 安装vs2015,或更新版本的
  2. 安装anaconda或miniconda
  3. 安装numpy(python库必须)
  4. 安装cuda和cudnn(可选)
  5. 下载源码opencv-4.2.0.zip,或者win预编译opencv-4.2.0-vc14_vc15.exe包含源码
  6. 下载opencv_contrib_4.2.0.zip(cuda必须)

在百度网盘共享了:
opencv-4.2.0-vc14_vc15.exe
opencv_contrib_4.2.0.zip
opencv42_cache.7z(cmake需要下载的部分)
链接:https://pan.baidu.com/s/1E-FmVbnwv2gjuL9UAiMDkQ 提取码:mf0f

二、配置cmake

  1. 在conda环境中运行cmake-gui

因为python和numpy是安装在conda中的,所以cmake必须在conda环境中运行。不然没法自动检测到numpy,即使手动指定,仍然没法通过检测。这里走了不少弯路。。。

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第2张图片

2. cmake下载文件

点击Configure,这时会检测计算的配置,下载需要的组件。

第一次Configure会提示Warning说找到的python.exe不是python2。没有问题,那是python3,不用处理,以后configure就没有警告了。

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第3张图片

这时会出现很多配置选项,将OPENCV_EXTRA_MODULES_PATH设置为opencv_contrib_4.2.0.zip解包后的modules文件夹。再次Configure,又需要下载几个文件。

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第4张图片

由于服务器大都在国外,速度非常慢,而opencv默认的下载超时只有10分钟,又不支持断点续传,于是不管下载多少次也不行。

修改代码sourcescmakeOpenCVDownload.cmake中第26行:
“TIMEOUT 600”改为“TIMEOUT 6000”,100分钟应该足够了。

set(OPENCV_DOWNLOAD_PARAMS INACTIVITY_TIMEOUT 60 TIMEOUT 600 CACHE STRING "Download parameters to be passed to file(DOWNLAOD ...)")

如果网络实在不好,不仅慢而且掉线,就需要使用下载工具(aria2、IDM等)来下载这些链接,即使掉线,可以接着下,总有下载完的一天。去cmake的build目录下打开CMakeDownloadLog.txt

#do_unpack "v0.1.1f.zip" "b624b995ec9c439cbc2e9e6ee940d3a2" "https://github.com/opencv/ade/archive/v0.1.1f.zip" "C:/opencv/opencv42_build2/3rdparty/ade"
#cmake_download "C:/opencv/opencv42/sources/.cache/ade/b624b995ec9c439cbc2e9e6ee940d3a2-v0.1.1f.zip" "https://github.com/opencv/ade/archive/v0.1.1f.zip"
#try 1
# timeout on name lookup is not supported
#   Trying 151.101.228.133...

其中cmake_download 后面跟着的就是要下载的文件路径,和url。用下载工具下载好url后,放入前面的路径,并改成需要的名字。名字前面那串是文件的md5值,cmake会自动校验的。

3. cmake配置参数

几个常用的配置:

BUILD_SHARED_LIBS:勾选则编译动态库DLL,反之静态库|
BUILD_opencv_world:编译成单一的动态库
WITH_CUDA:使用cuda加速,需要opencv_contrib 4.2.0.zip
OPENCV_DNN_CUDA:使用cuDNN,要求CUDA_ARCH_BIN大于5.3,去掉小于5.2的。
OPENCV_ENABLE_NOFREE:编译不免费的代码(有版权问题),比如SIFT、SURF算法

可以去掉TEST,减少编译时间。编译TEST可以运行测试判断编译是否成功,运行Test还需要下载opencv_extra_4.2.0.zip,不然大部分测试会失败。说到时间,cuda编译器是单线程的,优化太差了。

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第5张图片

如果用不到JAVA,可以不选

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第6张图片

cmake能够自动检测Python的配置

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第7张图片

如果没有BUILD_opencv_python3选项,需要再次检测环境,python和numpy是否安装正确。

这时会有一条警告:

CMake Warning at cmake/OpenCVGenSetupVars.cmake:54 (message):
CONFIGURATION IS NOT SUPPORTED: validate setupvars script in install
directory: C:/ProgramData/Miniconda3/Lib/site-packages

实际上就是PYTHON3_PACKAGES_PATH是绝对路径,直接就生成到python3的库里面去了,于是setup_vars_opencv4.cmd无法配置python库路径。当然也不再需要配置python库路径,直接import就可以。如果计算机中有多个python环境,如果将PYTHON3_PACKAGES_PATH添加到其他python中,就可能引起其他问题。将PYTHON3_PACKAGES_PATH改为python就可以了。需要使用时,先运行setup_vars_opencv4.cmd就可以了。也可以用build目录下的python_loadersetup.py手动安装到ptrhon库中。

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第8张图片

4. 编译

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第9张图片

先编译ALL_BUILD,编译工程。等待漫长的时间。。。

如果启用了OPENCV_DNN_CUDA,在VS2015上会出错,VS2017和VS2019正常编译。原因都是VS2015对c++新语法支持的不好。

16>c:opencvopencv42sourcesmodulesdnnsrccudagrid_stride_range.hpp(16): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷unsigned int cv::dnn::cuda4dnn::csl::device::detail::getGridDim<0>(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?
。。。
16>c:opencvopencv42sourcesmodulesdnnsrccuda4dnncslcudnn/cudnn.hpp(42): error C2912: 锟斤拷式专锟矫伙拷锟斤拷锟斤拷cudnnDataType_t cv::dnn::cuda4dnn::csl::cudnn::detail::get_data_type(void)锟斤拷锟斤拷锟角猴拷锟斤拷模锟斤拷锟阶拷没锟?

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第10张图片

cmake 多次编译_win10编译opencv4.2+conda+python3.7+cuda_第11张图片

搜索给该问题,得到解决方案https://blog.csdn.net/wanggao_1990/article/details/103779760
使用using代替拖尾返回类型。

(1)修改sourcesmodulesdnnsrccudagrid_stride_range.hpp文件
替换15-33行为

using dim3_member_type = decltype(dim3::x);

template   __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  __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  __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  __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) 修改sourcesmodulesdnnsrccuda4dnncslcudnncudnn.hpp文件
替换40-42行为:

using cudnn_data_enum_type = decltype(CUDNN_DATA_FLOAT);
template  cudnn_data_enum_type get_data_type();
template <> inline cudnn_data_enum_type get_data_type() { return CUDNN_DATA_HALF; }
template <> inline cudnn_data_enum_type get_data_type() { return CUDNN_DATA_FLOAT; }

再次编译ALL_BUILD,提示:

2>window.obj : error LNK2019: 无法解析的外部符号 cvStartWindowThread
2>window.obj : error LNK2019: 无法解析的外部符号 cvNamedWindow
2>window.obj : error LNK2019: 无法解析的外部符号 cvShowImage
cvResizeWindow,cvMoveWindow,cvDestroyWindow,cvDestroyAllWindows, cvCreateTrackbar2,cvGetTrackbarPos,cvSetTrackbarPos,cvSetTrackbarMax,cvSetTrackbarMin,cvSetMouseCallback,cvWaitKey,cvSetModeWindow_W32,cvGetWindowRect_W32,cvGetModeWindow_W32,cvGetPropWindowAutoSize_W32,cvGetRatioWindow_W32,cvGetOpenGlProp_W32,cvGetPropVisible_W32,cvGetPropTopmost_W32,cvSetPropTopmost_W32
2>C:opencvopencv42_buildbinReleaseopencv_world420.dll : fatal error LNK1120: 23 个无法解析的外部命令

什么也没改,再次编译ALL_BUILD

========== 生成: 成功 70 个,失败 0 个,最新 15 个,跳过 0 个 ==========

编译INSTALL,生成install文件夹,就可以将install复制到其他的计算机使用了。其他计算机需要安装相同版本的cuda,cudnn。

5. 编译debug版

如果需要调试,那么就需要编译debug版。编译时遇到错误:

fatal error LNK1210: 已超过内部 ILK 大小限制;链接时使用 /INCREMENTAL:NO

搜索/INCREMENTAL

https://www.cnblogs.com/Dahaka/archive/2011/08/01/2124256.html

原来时因为函数太多了,incremental linking(增量链接)的ILT表(Incremental Linking Table)超过了大小限制,opencv的debug库是为了被我们的debug程序调用,而不是修改opencv,所以并不需要增量链接。

把Project Properties -> Configuration Properties -> Linker (General) -> Enable Incremental Linking中的Yes (/INCREMENTAL)改成No (/INCREMENTAL:NO)

再次编译ALL_BUILD,由于只剩下链接处理,很短时间就编译成功。

编译INSTALL,生成install文件夹。

6. 运行Test

设置环境变量。如果不设置OPENCV_SAMPLES_DATA_PATH_HINT,测试Samples.findFile会失败

set OPENCV_TEST_DATA_PATH=C:opencvopencv_extra-4.2.0testdata
set OPENCV_SAMPLES_DATA_PATH_HINT=C:opencvopencv42sourcessamplesdata

运行opencv_extra-4.2.0testdatadnndownload_models.py下载模型数据。

编译RUN_TESTS,运行测试。在输出窗口里没有详细的失败信息,可以在命令行里运行对应的opencv_test_******。

你可能感兴趣的:(cmake,多次编译)