A save of the process needed to build manually OpenCV for Python 3 with CUDA bindings on Windows 10.
The process is based on this tutorial by Anindya for the step-by-step process with CMake GUI and this tutorial by James Bowley for the process with command line CMake and some troubleshooting.
Both of these tutorials should be enough for most people. But in some cases, even if the module was successfully installed in your Python installation, you may end up with this message when importing OpenCV with import cv2
:
ImportError: DLL load failed while importing cv2: The specified module could not be found.
This case is detailed in the troubleshooting section and is almost entirely based on this quite extensive github issue. Basically your whole installation is likely completely successful, it may just be Python failing to read your environment variables.
Tested on a Windows 10 20H2 machine with i7-10700 CPU @ 2.90GHz and GeForce RTX 2080 Ti.
Python 3.8.10, OpenCV 4.5.5, NumPy 1.21.6, CUDA toolkit v11.6, cuDNN v8.3.3, Visual Studio Community 2019 v16.11.13, CMake 3.19.1, all of this in April 2022.
- Visual Studio with C++ build tools
- CUDA according to your GPU
- cuDNN corresponding to CUDA (free account creation needed to download)
- Python 3 install
- NumPy
- OpenCV from source and OpenCV contrib modules from source
- CMake
Check that your GPU is compatible with CUDA: wikipedia.org/wiki/CUDA.
Install a recent Python 3.x however you prefer (Python website, Anaconda, Windows store, create a virtual env...), but if you are here that's probably already done. This "tutorial" is done with a standard Python install, from the Python website with no virtual environment. For the particularities of an Anaconda installation look at James Bowley's tutorial.
Make sure you have NumPy installed or install it with pip install numpy
. Uninstall any OpenCV python module pip uninstall opencv-python
or pip uninstall opencv-contrib-python
. Delete the YOUR_PYTHON_PATH/Lib/site-packages/cv2
folder for cleaning purposes.
Download Visual Studio (2019 version here) and install the build tools for C++ from the Visual Studio Installer.
Download and install the latest CUDA toolkit compatible with your GPU (see here for compatibility as well) or check you already have it installed in C:\Program Files\NVIDIA GPU Computing Toolkit
.
Idem for cuDNN with an intermediary step to create a NVIDIA developer account, fill up their survey etc.
Check in your environment variables that CUDA_PATH
and CUDA_PATH_Vxx_x
are here and pointing to your install path.
Copy the files in the cuDNN folders (under C:\Program Files\NVIDIA\CUDNN\vX.X
) bin, include and lib/x64 to the corresponding folders in your CUDA folder.
Download and extract matching versions of OpenCV and OpenCV-contrib from the links above.
Prepare a "build" folder with your OpenCV extracted folders.
Edit the end of the OpenCVDetectPython.cmake file in opencv-x.x.x/cmake. Move the second elseif above the first to get this:
This will prioritize the use of your Python 3 installation for the build.
Provide the paths to the OpenCV and target build folders:
Hit Configure and select x64 as the Optional platform for generator, then hit finish to start the first round of configuration.
Once this is done edit the following parameters:
Name | Value |
---|---|
ENABLE_FAST_MATH | ✅ |
OPENCV_DNN_CUDA | ✅ |
OPENCV_EXTRA_MODULES_PATH | path of modules directory in extracted opencv_contrib-x.x.x |
OPENCV_PYTHON3_VERSION | ✅ |
WITH_CUDA | ✅ |
Check the PYTHON3_... parameters so that the paths correspond to what you expect. Note that the path separator in OPENCV_EXTRA_MODULES_PATH (or any other parameter value) has to be "/" and not "\".
Hit Configure again.
Edit two more parameters:
Name | Value |
---|---|
CUDA_FAST_MATH | ✅ |
CUDA_ARCH_BIN | x.x |
The CUDA_ARCH_BIN corresponding to your GPU is the value found in the left column of the GPU support table. For instance "7.5" for the RTX 2080 Ti.
Hit Configure for the final configuration round. Once the configuration is done you should not have any parameter left in red. Now hit Generate. When generation is finished we are done with CMake.
Open the OpenCV.sln
just created in the build folder.
Go in "Tools>Options...", then in "Projects and Solutions > Web Projects" uncheck the last parameter. Continue if it was already unchecked, otherwise close Visual Studio and reopen OpenCV.sln
.
N.B. If you are not using Visual Studio in english, this setting may be elsewhere or (from personal experience) somehow simply unfindable. If this is the case change the language to english. While I have no precise idea of why this setting is needed, it actually has an impact.
Change the "Debug" mode to "Release".
In the solution explorer expand CMakeTargets, right-click ALL_BUILD and select Build. This will take about half an hour.
Then repeat the step for INSTALL (right below ALL_BUILD). Check for errors in the two building steps, if everything is fine you are done.
First thing to do open your preferred way of executing some Python code and try this:
import cv2
print(cv2.__version__)
print(cv2.cuda.getCudaEnabledDeviceCount())
If it works, congratulations you are good to go!
If not let's tackle the problem. The problem being ImportError: DLL load failed while importing cv2: The specified module could not be found.
.
For other bugs and problems I refer you to the troubleshooting section of James Bowley's tutorial.
You should have a "cv2" folder in your python installation (under your_python_path/Lib/site-packages
). If not check if you have a "binding" folder in the Visual Studio solution.
Otherwise I suggest trying to change two parameters in the CMake configuration: BUILD_SHARED_LIBS 🔳
and OPENCV_FORCE_PYTHON_LIBS ✅
. Then re-generate and re-build everything.
In an IDE with code suggestion (VS Code for instance) try to type import cv2
, then write cv2.
and see if suggestions appear. If they do your Python installation can successfully access OpenCV.
Check that the libraries installed by your build are not causing the import error. To do this you can add manually the DLL files path to a script:
import os
os.add_dll_directory('C:/path_to_opencv_build_folder/install/x64/vc16/bin')
import cv2
This import should be done by default in the config.py
file in the cv2
folder and should probably not solve the issue by itself.
The problem is most likely linked to other libraries not loaded by Python even if they are in your PATH environment variables. You can troubleshoot this by adding all the PATH variables to the script with os.add_dll_directory()
until it works or use the Dependency walker to find which DLLs you are missing.
Opening the cv2.cp38-win_amd64.pyd
with the dependency walker can get you a list of DLLs it is missing. However it will also list a ton of Microsoft DLLs (starting with API-MS-... or EXT-MS-...) that actually do not impact the import error. Then you can try to add manually the missing libraries and see if it solves the issue.
A solution highlighted in the github issue mentioned in the intro of this README was that using an Anaconda Python install made it work, so having a Python 3.8 Anaconda install I added the C:/Users/username/Anaconda3/Library/bin
path to my script and voilà, it worked.
It turns out the only missing libraries were hdf5.dll
and zlib.dll
out of the >200 DLL files located there. So they are here in this repository if you do not want to install Anaconda to not use it.
Once you have located the folders containing your missing DLLs you have a few options to permanently solve the import error:
- copy the files to your
path_to_opencv_build_folder/install/x64/vc16/bin
folder (easy but not clean) - add the
import os
andos.add_dll_directory('...')
to any script using OpenCV (ok but not convenient) - add all the needed
os.add_dll_directory()
in the__init__.py
file ofcv2
right after the__all__ = []
line (cleanest but make it clear!)
If some part of this solved your ImportError: DLL load failed while importing cv2: The specified module could not be found.
then great! Otherwise I suggest going thoroughly through the github issue for more ideas. Feel free to make any remarks, I will update this page if need be.