ImportError: DLL load failed while importing cv2: The specified module could not be found.
Definitive guide to fixing the ‘ImportError: DLL load failed while importing cv2: The specified module could not be found.’ error when trying to import the OpenCV python module.
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.
Fix when path to missing DLL’s is known
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:
import cv2
---------------------------------------------------------------------------ImportError Traceback (most recent call last)
Cell In[1], line 1----> 1importcv2ImportError: 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 Traceback (most recent call last)
Cell In[2], line 3 1importos 2 os.add_dll_directory(r'D:\build\opencv\4_10\install\x64\vc17\bin')
----> 3importcv2ImportError: 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())
Expand to see an example of the output from print(cv2.getBuildInformation())
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.
Fix when path to missing DLL’s is not known
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:
Manually add filter entries in the “Process Monitor Filter” window, which opens by default every time you launch the application.
Manually Adding Filter Entries
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:
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’” however for completeness we’ll include it)
Your filter should now resemble the one in the screenshot below:
Process Monitor Filter
Using Process Monitor to find the missin DLLs
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:
Start Python.
Press the clear button (red trash can icon) in Process Monitor to clear any output generated during Python’s initialization.
Import OpenCV (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:
import cv2
---------------------------------------------------------------------------ImportError Traceback (most recent call last)
Cell In[1], line 1----> 1importcv2ImportError: DLL load failed while importing cv2: The specified module could not be found.
Process Monitor failed to locate opencv_world4100.dll and opencv_img_hash_4100.dll
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.
Note
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 Traceback (most recent call last)
Cell In[2], line 3 1importos 2 os.add_dll_directory(r'D:\build\opencv\4_10\install\x64\vc17\bin')
----> 3importcv2ImportError: DLL load failed while importing cv2: The specified module could not be found.
Process Monitor failed to locate nppial64_12.dll and nppc64_12.dll
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:
Examine the output in Process Monitor
Identify any remaining missing DLLs
Add the directories containing these missing DLLs to the Python DLL search path
Automatically search Process Monitor log for missing DLL
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:
Go to File -> Save
Select Format -> Comma-Separated Values (CSV)
Enter the desired location for the exported file under Path
Click Save
Below is an examaple of a Python function which will parse the exported CSV and print the names of missing DLLs:
import csvfrom pathlib import Pathimport redef print_missing_libs(process_mon_export_file_path): shared_libs = {}withopen(process_mon_export_file_path, mode='r') asfile: csv_reader = csv.reader(file, delimiter=',')for row in csv_reader: key = Path(row[3]).name.lower() val = row[4]if (key notin 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'andnot re.search(pattern, entry)):print(entry)
Example usage and output when Python cannot locate the CUDA SDK :