环境
Windows10
Visual Studio 2022
opencv 4.7.0 + opencv_contrib-4.7.0
cmake-3.25.3-windows-x86_64
python 3.9.15
注意!!!
如果通过cmake-gui编译时,无法显示BUILD_opencv_python3选项,则不要在尝试使用gui方式编译了,否则是无法编译出python的安装文件的。(尝试了几天的心酸泪)。请采用脚本编译方式。
!!! 通过cmake-gui的“Add Entry”方式手动添加找不到的选项,生成后在vs中任然找不到python的binding项。
脚本编译
# 第一步:配置
cmake -B"E:\opencv\opencv-4.7.0\build" ^
-H"E:\opencv\opencv-4.7.0\sources" ^
-G"Visual Studio 17 2022" ^
-DBUILD_opencv_world=ON ^
-DBUILD_opencv_python2=OFF ^
-DBUILD_opencv_python3=ON ^
-DBUILD_opencv_python_bindings_generator=ON ^
-DBUILD_PYTHON3_VERSION=ON ^
-DBUILD_FORCE_PYTHON_LIBS=ON ^
-DOPENCV_ENABLE_NONFREE=ON ^
-DOPENCV_EXTRA_MODULES_PATH="E:\opencv\opencv-4.7.0\opencv_contrib-4.7.0\modules" ^
-DPYTHON3_INCLUDE_DIR=D:/Anaconda3/include ^
-DPYTHON3_LIBRARY=D:/Anaconda3/libs/python39.lib ^
-DPYTHON3_EXECUTABLE=D:/Anaconda3/python.exe ^
-DPYTHON3_NUMPY_INCLUDE_DIRS=D:/Anaconda3/lib/site-packages/numpy/core/include ^
-DPYTHON3_PACKAGES_PATH=D:/Anaconda3/Lib/site-packages ^
-DBUILD_opencv_python_tests=OFF ^
-DBUILD_PERF_TESTS=OFF ^
-DBUILD_TESTS=OFF ^
-DINSTALL_TESTS=OFF ^
-DOPENCV_TEST_DNN_CANN=OFF ^
-DOPENCV_TEST_DNN_OPENVINO=OFF
# 第二步:build
cmake --build "E:\opencv\opencv-4.7.0\build" --target INSTALL --config Release
- 配置说明
-B"E:\opencv\opencv-4.7.0\build" :指编译生成到的文件夹路径
-H"E:\opencv\opencv-4.7.0\sources" : opencv源码路径
-DBUILD_opencv_world=ON : 将所有的动态库融合为一个
-DBUILD_opencv_python3=ON : 启用python3编译,GUI编译时找不到这个选项,折腾了几天。
-DOPENCV_EXTRA_MODULES_PATH: contrib包的源码路径
-DOPENCV_ENABLE_NONFREE=ON: 启用才能使用SIFT等算法
………… - 第一步构建完后生成“OpenCV.sln”,可以通过vs打开并编译;也可以直径cmake编译,编译完成后会安装到指定的python目录下。
使用
代码提示问题:安装完后,在pycharm等IDE中无法智能提示。
解决办法:将python-3.9中的cv2.cp39-win_amd64.pyd文件copy到sit-packages目录下,并修改文件名为cv2.pyd,则能提示啦。 参考
填坑
通过上述方式成功的在anaconda默认的环境下安装好了自己编译的opencv库,使用也正常。但是如果切换到conda创建的虚拟环境,就无法正常使用,尝试了各种方法,始终报错:ImportError: DLL load failed while importing cv2: 找不到指定的模块。
解决方法,参考
1、在导入cv2包之前手动指定依赖的dll路径,如:
import os
os.add_dll_directory("D:\\build\\opencv\\4_7_0\\cuda_12_D\\bin")
import cv2
2、如果还是报错,找不到dll,则可以使用
ProcessMonitor排查缺少哪个dll,缺少的手动引用进来就可以了。
使用PorcessMonitor筛选方法:
Process Name -> is -> python.exe
Operation -> is -> CreateFile
Result -> is -> NAME NOT FOUND
Result -> is -> SUCCESS
Path -> contains -> .dll
Path -> contains -> .pyd (not striclty necessary, if this was missing the error would be “ModuleNotFoundError: No module named ‘cv2’” but its a shared library so why not)
例如:
经过排查,我这边缺少了两个dll,在其他地方copy过来就ok了: