import cv2
ImportError: DLL load failed while importing cv2: The specified module could not be found.
May 12, 2023
June 27, 2024
OpenCV, Python, ImportError, cv2, importing, failed, module, CUDA, cuDNN
If you’re using Windows with Python >= 3.8, have built OpenCV >= 4.6 from source, and are encountering the “ImportError: DLL load failed while importing cv2: The specified module could not be found” error when calling import cv2
, this short guide should help solve your problem.
This guide assumes that you have either installed the Python bindings during the build process or manually copied cv2.cpxx-win_amd64.pyd to your distribution’s site-packages directory (e.g., C:\Users\<USER>\miniforge3\Lib\site-packages).
So, what’s the issue? Although the error message is quite explicit about the cause, it doesn’t really help with finding a solution. In a nutshell, Python has found cv2.cpxx-win_amd64.pyd tried to load it, and then failed because it can’t find a dependent shared library.
The advice I’ve seen online regarding this issue is to use Dependency Walker, load the cv2.cpxx-win_amd64.pyd, and identify which dependencies the system can’t find. This is solid advice if you have a C++ application, are using Python < 3.8 (which uses the system/user path for DLL resolution), or are not using a Python distribution that performs path manipulation under the hood (e.g., Anaconda). However, if the above does not apply, even if Dependency Walker doesn’t detect any problems, we may still face the above error.
The good news is that there’s an easy fix if you know where the missing DLLs are, and it’s only slightly more involved if you don’t, as long as you have access to the missing DLLs on your system.
To demonstrate the fix, I have built OpenCV as a shared library (opencv_world410.dll) with its corresponding Python bindings (cv2.cpxx-win_amd64.pyd). To enable them to be loaded (import cv2
) without any extra configuration, I have manually copied them to the site-packages directory inside my Python distribution (C:\Users\b\miniforge3\Lib\site-packages).
As I have built a shared library, the Python bindings are dependent on opencv_world410.dll, which contains all of OpenCV’s executable code. If I had built a static library, all of OpenCV’s executable code would be contained inside cv2.cpxx-win_amd64.pyd. Since I haven’t told Python where the DLL is located, I get the following error when trying to import the bindings:
ImportError: DLL load failed while importing cv2: The specified module could not be found.
Given that I know the path to OpenCV’s shared libraries is required and I haven’t told Python about it, the first thing to try is to add it to Pythons DLL search path with os.add_dll_directory()
as we are using Python >= 3.8 and see if that solves the problem.
ImportError: DLL load failed while importing cv2: The specified module could not be found.
Ahh the same error, what’s going on.
In this case I also built OpenCV against the CUDA SDK so there is a good chance its missing DLL’s from there as well. I can try to fix the issue by simply adding the location of the CUDA SDK binaries to the python DLL search path as shown below.
This appears to have solved the issue, but its a good idea to examine the build information by calling print(cv2.getBuildInformation())
just to double check I have loaded the right version of OpenCV.
print(cv2.getBuildInformation())
General configuration for OpenCV 4.10.0-dev =====================================
Version control: 4.10.0-49-g11c69bb171
Extra modules:
Location (extra): D:/repos/opencv/contrib/modules
Version control (extra): 4.10.0-2-ga886fa5c
Platform:
Timestamp: 2024-06-25T15:14:43Z
Host: Windows 10.0.22631 AMD64
CMake: 3.29.5
CMake generator: Ninja Multi-Config
CMake build tool: D:/bin/ninja/ninja.exe
MSVC: 1940
Configuration: Debug Release
CPU/HW features:
Baseline: SSE SSE2 SSE3
requested: SSE3
Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX
requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
SSE4_1 (18 files): + SSSE3 SSE4_1
SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2
FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
AVX (9 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
AVX2 (38 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
AVX512_SKX (8 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX
C/C++:
Built as dynamic libs?: YES
C++ standard: 11
C++ Compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe (ver 19.40.33811.0)
C++ flags (Release): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /FS /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /wd4819 /O2 /Ob2 /DNDEBUG /Zi
C++ flags (Debug): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /FS /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /wd4819 /Zi /Ob0 /Od /RTC1
C Compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe
C flags (Release): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /FS /O2 /Ob2 /DNDEBUG /Zi
C flags (Debug): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /FS /Zi /Ob0 /Od /RTC1
Linker flags (Release): /machine:x64 /INCREMENTAL:NO /debug
Linker flags (Debug): /machine:x64 /debug /INCREMENTAL
ccache: NO
Precompiled headers: NO
Extra dependencies: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/cudart_static.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppial.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppc.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppitc.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppig.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppist.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppidei.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/cublas.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/cublasLt.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/cufft.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppif.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppim.lib C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.5/lib/x64/nppicc.lib
3rdparty dependencies:
OpenCV modules:
To be built: aruco bgsegm bioinspired calib3d ccalib core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev datasets dnn dnn_objdetect dnn_superres dpm face features2d flann fuzzy gapi hfs highgui img_hash imgcodecs imgproc intensity_transform line_descriptor mcc ml objdetect optflow phase_unwrapping photo plot python3 quality rapid reg rgbd saliency shape signal stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab wechat_qrcode world xfeatures2d ximgproc xobjdetect xphoto
Disabled: -
Disabled by dependency: -
Unavailable: alphamat cannops cvv freetype hdf java julia matlab ovis python2 python2 sfm viz
Applications: tests perf_tests examples apps
Documentation: doxygen python
Non-free algorithms: NO
Windows RT support: NO
GUI:
Win32 UI: YES
VTK support: NO
Media I/O:
ZLib: build (ver 1.3.1)
JPEG: build-libjpeg-turbo (ver 3.0.3-70)
SIMD Support Request: YES
SIMD Support: NO
WEBP: build (ver encoder: 0x020f)
PNG: build (ver 1.6.43)
SIMD Support Request: YES
SIMD Support: YES (Intel SSE)
TIFF: build (ver 42 - 4.6.0)
JPEG 2000: build (ver 2.5.0)
OpenEXR: build (ver 2.3.0)
HDR: YES
SUNRASTER: YES
PXM: YES
PFM: YES
Video I/O:
DC1394: NO
FFMPEG: YES (prebuilt binaries)
avcodec: YES (58.134.100)
avformat: YES (58.76.100)
avutil: YES (56.70.100)
swscale: YES (5.9.100)
avresample: YES (4.0.0)
GStreamer: NO
DirectShow: YES
Media Foundation: YES
DXVA: YES
Parallel framework: Concurrency
Trace: YES (with Intel ITT)
Other third-party libraries:
Intel IPP: 2021.11.0 [2021.11.0]
at: D:/build/opencv/4_10/3rdparty/ippicv/ippicv_win/icv
Intel IPP IW: sources (2021.11.0)
at: D:/build/opencv/4_10/3rdparty/ippicv/ippicv_win/iw
Lapack: NO
Eigen: NO
Custom HAL: NO
Protobuf: build (3.19.1)
Flatbuffers: builtin/3rdparty (23.5.9)
NVIDIA CUDA: YES (ver 12.5.40, CUFFT CUBLAS NVCUVID NVCUVENC)
NVIDIA GPU arch: 86
NVIDIA PTX archs:
cuDNN: YES (ver 9.2.0)
OpenCL: YES (NVD3D11)
Include path: D:/repos/opencv/opencv/3rdparty/include/opencl/1.2
Link libraries: Dynamic load
Python 3:
Interpreter: C:/Users/b/miniforge3/python.exe (ver 3.10.14)
Libraries: C:/Users/b/miniforge3/libs/python310.lib (ver 3.10.14)
Limited API: NO
numpy: C:/Users/b/miniforge3/Lib/site-packages/numpy/core/include (ver 1.26.4)
install path: C:/Users/b/miniforge3/Lib/site-packages//cv2/python-3.10
Python (for build): C:/Users/b/miniforge3/python.exe
Java:
ant: NO
Java: NO
JNI: NO
Java wrappers: NO
Java tests: NO
Install to: D:/build/opencv/4_10/install
-----------------------------------------------------------------
That was easy but what can I do if I’m not as good at guessing what’s missing. Next I will use the same example again to demonstrate how to find out which DLLs Python is searching for.
To find which DLLs are missing, we can use Process Monitor, a process monitoring tool for Windows. This tool enables us to see the names of the DLLs that Python is trying to load and the locations it’s searching at runtime.
Process Monitor produces a significant amount of output by default, so it’s a good idea to filter out as much of this noise as you can. To do this, you can either:
Since we only want to view shared libraries accessed by the python.exe process, we can add the following filters to make our task easier:
Your filter should now resemble the one in the screenshot below:
Before continuing, it is advisable to close any other Python processes, as the output from these will pollute the main window of Process Monitor.
Now, follow these steps:
import cv2
)To demonstrate how this works I have restarted Pyton to reset the paths we manually added with the above calls to os.add_dll_directory()
and again run import cv2
, resulting in the same error with the additional output from Process Monitor shown in the screen shot below:
ImportError: DLL load failed while importing cv2: The specified module could not be found.
This output shows that we successfully found cv2.cp310-win_amd64.pyd (otherwise we would see the “ModuleNotFoundError: No module named ‘cv2’” error). However, it also reveals several unsuccessful attempts to locate opencv_world4100.dll and opencv_img_hash_4100.dll in different directories.
Because there is a lot of output to sift through, if you can’t immediately see which DLLs are missing, I recommend exporting and parsing the output from Process Monitor as described in the “Automatically search Process Monitor log for missing DLL” section below.
As before, we need to add the directory containing these missing DLLs to the Python DLL search path shown below:
ImportError: DLL load failed while importing cv2: The specified module could not be found.
After adding the previously missing DLLs to the search path, Process Monitor now shows that opencv_world4100.dll and opencv_img_hash_4100.dll were located successfully after a few attempts. However, we’re now missing nppial64_12.dll and nppc64_12.dll, which are part of the CUDA SDK. To resolve this, we need to add the CUDA SDK binary directory to the Python DLL search path. Once we do this, the call to import cv2
will be successful.
If we were still seeing the same error after this step, we would simply repeat the process:
The output from Process Monitor can be difficult to sift through. To help with this, we can export the output to a .csv file and then parse it using the helper function below.
To export the log:
Below is an examaple of a Python function which will parse the exported CSV and print the names of missing DLLs:
import csv
from pathlib import Path
import re
def print_missing_libs(process_mon_export_file_path):
shared_libs = {}
with open(process_mon_export_file_path, mode='r') as file:
csv_reader = csv.reader(file, delimiter=',')
for row in csv_reader:
key = Path(row[3]).name.lower()
val = row[4]
if (key not in shared_libs or key in shared_libs and shared_libs[key] != 'SUCCESS'):
shared_libs[key] = val
pattern = re.compile(r"__init__")
for entry, status in shared_libs.items():
if(status == 'NAME NOT FOUND' and not re.search(pattern, entry)):
print(entry)
Example usage and output when Python cannot locate the CUDA SDK :