'OpenCV Python with CUDA on Windows: DLL Load Failed

I am trying to get OpenCV python bindings to work with CUDA, but when I run

import cv2

I get the following error:

OpenCV loader: os.name="nt"  platform.system()="Windows"
OpenCV loader: loading config: C:\opencv\build\python_loader\cv2\config.py
OpenCV loader: loading config: C:\opencv\build\python_loader\cv2\config-3.8.py
OpenCV loader: PYTHON_EXTENSIONS_PATHS=['C:/opencv/build/lib/python3/Release']
OpenCV loader: BINARIES_PATHS=['C:/opencv/build/bin/Release']
OpenCV loader: PATH=C:/opencv/build/bin/Release;C:\Program Files\Python38\Scripts\;C:\Program Files\Python38\;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\libnvvp;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\CCM;C:\WINDOWS\CCM;C:\Perl64\c\bin;C:\Perl64\perl\site\bin;C:\Perl64\perl\bin;C:\WINDOWS\CCM;C:\WINDOWS\CCM;C:\WINDOWS\CCM;C:\Program Files\PuTTY\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Program Files\nodejs\;C:\Program Files (x86)\Yarn\bin\;C:\Program Files\NVIDIA Corporation\Nsight Compute 2019.5.0\;C:\opencv\build\install\x64\vc16\bin\;C:\Users\md249\AppData\Local\Microsoft\WindowsApps;
OpenCV loader: replacing cv2 module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\opencv\build\python_loader\cv2\__init__.py", line 96, in <module>
    bootstrap()
  File "C:\opencv\build\python_loader\cv2\__init__.py", line 86, in bootstrap
    import cv2
ImportError: DLL load failed while importing cv2: The specified module could not be found.

I have the following environment variables set:

OPENCV_DIR: C:\opencv\build\
PATH: $PATH;C:\opencv\build\install\x64\vc16\bin\;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\bin

It seems that OpenCV builds binaries to multiple different directories for reasons I do not understand, so I am unsure where to point PATH and OPENCV_DIR.

Running Dependency Walker against cv2.cp38-win_amd64.pyd does not indicate any missing dependencies from OpenCV or CUDA.

Does the .pyd dynamically load any other dependencies that Dependency Walker might not catch? C++ applications load OpenCV just fine so I imagine the problem has something to do with where the .pyd extension is looking for dependencies.

Hopefully I have included all the relevant information.



Solution 1:[1]

It is probably because you didnt installed OpenCV, you donwloaded it, if you don't want to spend time configuring extra path to make sure python finds the right opencv package you just need to install it using 'pip':

pip install opencv-contrib-python

It will probably solve you problem, and the C++ software can still use the downloaded version without conflict.

Install Reference

Solution 2:[2]

I have got the same error message when importing cv2, but I compiled OpenCV from source including the extra modules from opencv_contrib, because I wanted a Win64 build including cuda* and python3 modules.

Workaround

Even after investing an extended amount of time I cannot offer a satisfying solution. But my functioning workaround is to use dumpbin or Dependency walker to find all the cv2.cp39-win_amd64.pyd dependencies recursively and provide all of them including cv2.cp39-win_amd64.pyd from the same flat directory, which you add to PYTHONPATH.

In my case this meant the following manual steps after compiling OpenCV from source:

  • Make a directory like C:\opencv-py39.
  • Copy cv2.cp39-win_amd64.pyd to C:\opencv-py39.
  • Copy all OpenCV shared libs (${EXECUTABLE_OUTPUT_PATH}\*.dll e.g. opencv_world455.dll) to C:\opencv-py39.
  • Copy all CUDA-relevant shared libs (%CUDA_PATH%\bin\*.dll) to C:\opencv-py39.
  • Copy all Intel TBB shared libs (%ONEAPI_ROOT%\tbb\latest\redist\intel64\vc14\*.dll) to C:\opencv-py39.
  • Set the environment variable PYTHONPATH=C:\opencv-py39.

Depending on the build options you choose this list might be inconclusive.

More details

This workaround bypasses the problems that I experience not having the dependencies of my cv2.cp39-win_amd64.pyd loaded from their specific installation directories even if environment variables are set properly and C++ example progams build and execute as expected. I guess this is specific to the shared library loader of CPython. I have found evidence that this problem might have been introduced in Python 3.8.

Having a closer look using SysInternals procmon utility reveals, that the python interpreter stops using the right module name while probing all the configured DLL search directories. I.e. it starts looking for opencv_world455.dll in the current working directory, then in the Python directory etc. but when it starts to look into the PATH's directories it uses a faulty module name like <stdin> or similar corrupted names. Maybe I should submit a bug report to CPython...

Solution 3:[3]

Adding to @salchint workaround:

I got the same ImportError problem with my installation and solved it thanks to an Anaconda install I had on the side.

It turns out that all the missing DLLs could be found in .../Anaconda3/Library/bin. So including the folder to your script with:

import os
os.add_dll_directory('path_to_Anaconda/Anaconda3/Library/bin')

Solved the error for me. Note that this folder is in my Path and should be discoverable but Python has (or had?) some problems doing it.

A cleaner solution (but still a workaround) is then to add this command to the __init__.py file of the cv2 module in YOUR_PYTHON_PATH/Lib/site-packages

I wrote about it in more detail here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alfredo Neto
Solution 2
Solution 3 chm