Anaconda3 — OpenCV with CUDA GPU support for Windows 10

This article will go through the step-by-step process of how to compile OpenCV to include CUDA GPU support so that it can be used in a Vision-based Machine Learning Project.

Jordan Benge
10 min readMay 16, 2021
OpenCV + CUDA

Pre: I decided to write this up because I found that the existing guides (linked in the credits) were lacking some of the finer details on how to accomplish the monuments task of building OpenCV from the source code with CUDA GPU support so that it could be imported into a Python 3.8 Conda environment. Most of them ended with the build process, but low and behold that is just the first step of many to get OpenCV to work properly in a project.

Prerequisites

Before we begin, we have to download a few files, install some programs and move some things around. I am also going to assume that you are using the Anaconda Package manager environment for Python 3.8 with it set as the default python & environment variables enabled. If not, I’m not sure if the following will work for you without any trouble. I don’t recommend deviation.

1. Visual Studio 2019

Make sure that you have Visual Studio 2019 installed WITH the “Desktop development with C++” package. This is done during the install process of Visual Studio. If you already have VS2019 installed, but aren’t sure if you have the workload installed, this can be done by re-installing (modifying) your installation through the install executable.

Visual Studio 2019 with C++ development

2. OpenCV & OpenCV contrib files

Create a folder somewhere on your computer called “OpenCV_Build”. It doesn’t have to be named this exactly, I just like to know what it is at a glance. You’ll then download both the OpenCV and the OpenCV contrib zips. Once the downloads have finished, extract the zip and move the resulting folders into OpenCV_Build. It should resemble something like:

OpenCV_Build/opencv-4.5.2
OpenCV_Build/opencv_contrib-4.5.2

You want to make sure that they are both the same version (4.5.2 in this case).

I also like to make sure that they’re top-level directories and not nested within a folder that has the same name, but that’s not completely necessary, just a qualm I have with Github zips & makes our env paths a bit leaner.

3. CMake GUI

Download and install the CMake GUI. I’m using version 3.20.2, but it shouldn’t really matter which version you install.

4. The CUDA 11.0 Toolkit

For the next step, you’ll have to register on the Nvidia website in order to download & Install the CUDA toolkit, it’s quick and easy and shouldn’t take you much time at all.

5. cuDNN

This step is very similar to the previous one, but you’ll have to download the cuDNN in order to utilize the DNN CUDA backend. Once you’re registered in the Nvidia developer program, you’ll want to select the version that says:
“for CUDA 11.x”.

6. Extracting cuDNN Files

Once the cuDNN download has finished, extract the zip and open up the resulting folder. Inside, you should see a folder called cuda, open that one up, and then you’ll be left with 3 sub-folders called “bin”, “include”, and “lib”.

You are going to be copying the files from each sub-folder into their corresponding folder within C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3.

downloads/cuda/bin contents to: CUDA/v11.3/bin
downloads/cuda/include contents to: CUDA/v11.3/include
downloads/cuda/lib/x64 contents to: CUDA/v11.3/lib/x64

7. Download Ninja for Faster Build Times

Ninja will immensely speed up the build process for OpenCV. I personally saw a decrease from an hour and 45 minutes to just under 15 mins with Ninja. Extract it, and put Ninja.exe in the “OpenCV_Build” folder that you created before.

Once all of the files have been put into their respective folders, you should be done with the prereqs section. Onto the fun stuff!

Recommended: Set up Conda Env

I recommend that you use Anaconda, to ensure that everything you’re doing is the same as everything I’m doing. You can set up your conda env with the following command: conda create -n py38 anaconda python=3.8

Recommended: Create some .bat Files for Simplicity

In order to make your life easier, I recommend making some .bat files in case something goes wrong in your build process. This way you can quickly make an edit to your cmd, and re-run it without having to go through the process of re-setting all of your environment variables again and again. It also helps break things up into a more manageable state when things are going wrong...and they almost certainly will go wrong…

set_env_paths.bat

Right-click in the OpenCV_Build folder, and create a new text file called set_env_paths.bat. Once you have finished doing that, you’ll want to edit the following example to include your folder locations:

ECHO -- Set these variables below --set "openCvSource=E:/OpenCV_Build/opencv-4.5.2"
set "openCVExtraModules=E:/OpenCV_Build/opencv_contrib-4.5.2/modules"
set "openCvBuild=%openCvSource%/build"
set "toolkitRoot=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.0"
ECHO -- Set this to the location of your Conda Env
set "pathToAnaconda=C:/Users/Benge/anaconda3/envs/py38"
ECHO -- Leave these variables alone --
set "buildType=Release"
set "generator=Ninja"
set "pyVer=38"

An important thing to keep in mind as well is that none of your folder paths should include a backslash (“\”) and should instead be replaced with forward slashes (“/”). This is a weird quark of CMake that I found, and unfortunately, this is the only way to ensure things don’t fail during the build process.

configure_and_build_opencv.bat

This is the bread and butter in our path to configure and build OpenCV. It’s essentially just a bunch of command prompt cmds linked together to make the whole process easier. It essentially initializes the VS2019 build batch file, calls the previous environment variables we set in set_env_paths, calls CMake to generate our configuration with GPU accelerated CUDA and its various settings (easier than doing it individually in CMake in my opinion). Includes the Anaconda build env Python bindings so that we can actually import and utilize the newly built module in our project and then it begins the process of building OpenCV.

ECHO -- Starting OpenCV Configuration --ECHO ---- Opening Visual Studio builder ----call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Auxiliary/Build/vcvars64.bat"ECHO ---- Setting up environment variables ----call set_env_paths.batECHO ---- Running CMake Commands ----call "C:/Program Files/CMake/bin/cmake.exe" -B"%openCvBuild%/" -H"%openCvSource%/" -G"%generator%" -DCMAKE_BUILD_TYPE=%buildType% -DOPENCV_EXTRA_MODULES_PATH="%openCVExtraModules%/" ^
-DINSTALL_TESTS=ON -DINSTALL_C_EXAMPLES=ON -DBUILD_EXAMPLES=ON ^
-DBUILD_opencv_world=ON ^
-DWITH_CUDA=ON -DCUDA_TOOLKIT_ROOT_DIR="%toolkitRoot%" -DCUDA_FAST_MATH=ON -DWITH_CUBLAS=ON -DCUDA_ARCH_BIN=7.5 -DWITH_NVCUVID=ON ^
-DWITH_OPENGL=ON -DENABLE_FAST_MATH=ON ^
-DWITH_MFX=ON ^
-DBUILD_opencv_python3=ON -DPYTHON3_INCLUDE_DIR=%pathToAnaconda%/include -DPYTHON3_LIBRARY=%pathToAnaconda%/libs/python%pyVer%.lib -DPYTHON3_EXECUTABLE=%pathToAnaconda%/python.exe -DPYTHON3_NUMPY_INCLUDE_DIRS=%pathToAnaconda%/lib/site-packages/numpy/core/include -DPYTHON3_PACKAGES_PATH=%pathToAnaconda%/Lib/site-packages/ -DOPENCV_SKIP_PYTHON_LOADER=ON
ECHO -- OpenCV Configuration has finished, proceeding to build phase --call "C:\Program Files\CMake\bin\cmake.exe" --build %openCvBuild% --target install:End
PAUSE

Run the configure_and_build_opencv.bat file

Double click our file, and let the process run. It will take anywhere between 15 mins to an hour depending on your system, and if it doesn’t run into any errors. Occasionally, you’ll see it stop printing to the command prompt. This is a known issue with Windows 10 Command Prompt, so just click within the window and hit enter, it should catch back up.

If it doesn’t continue, it’s probably just processing something large and might take a minute to finish. Let it continue to run for a few minutes, and if it doesn’t continue after that, close the window, and re-run the bat file. CMake is weird on windows like that, I don’t really know why, but it just freezes at times.

Once it finishes, it should pause and ask you to hit enter to close the command prompt. This is just there to ensure that everything built correctly. It might also close itself automatically after the build if it times out.

Verify OpenCV Built correctly

Assuming that the build finished correctly, we can verify that OpenCV is now functional. You’ll want to open up another Command Prompt instance, and cd into your OpenCV_Build folder.

Once you’re in that folder, you’ll want to enter the following lines into the command prompt:
call set_env_paths.bat
set path=%openCvBuild%\install\x64\vc16\bin;%path%
ipython

And then copy-paste the next bit into the command window.

import numpy as np
import cv2 as cv
npTmp = np.random.random((1024, 1024)).astype(np.float32)
npMat1 = npMat2 = npMat3 = npDst = np.stack([npTmp,npTmp],axis=2)
cuMat1 = cuMat2 = cuMat3 = cuDst = cv.cuda_GpuMat(npMat1)
%timeit cv.cuda.gemm(cuMat1, cuMat2,1,cuMat3,1,cuDst,1)

Once you’ve done that, hit enter and you should see something along the lines of: 2.79 ms ± 63.8 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

Okay, cool. So now we know that we have access to the OpenCV Module in Python. Next, let's make sure that we have it in our Conda env.

In the same window, paste:

dir "%USERPROFILE%\Anaconda3\envs\py38\Lib\site-packages\cv2*"

This should output something like: 05/15/2021 | 12:26 PM | 9,133,056 | cv2.cp38-win_amd64.pyd

If it doesn’t, type: dir "%openCvBuild%\lib\python3\cv2.cp38-win_amd64.pyd" into the command prompt to check our Python Bindings. It should locate the file.

If the file was found, you’ll want to make sure that the conda site-packages folder for your env has the cv2.cp38-win_amd64.pyd file. If it doesn’t you can either:

1. Copy/Paste the file manually from: OpenCV_Build\opencv-4.5.2\build\lib\python3 and paste it into the conda folder location: C:\Users\YOUR_NAME\anaconda3\envs\YOUR_ENV_NAME\Lib\site-packages. And then re-run the dir "%USERPROFILE%\Anaconda3\envs\py38\Lib\site-packages\cv2*" command.

2. Use the following cmd:

copy "%openCvBuild%/lib/python3/cv2.cp38-win_amd64.pyd" "%USERPROFILE%/Anaconda3/envs/py38/Lib/site-packages/cv2.cp38-win_amd64.pyd"

Test OpenCV Version

In the same cmd prompt, type:

set path=%openCvBuild%\install\x64\vc16\bin;%path%python -c "import cv2; print(f'OpenCV: {cv2.__version__} for python installed and working')"

It should output something like: OpenCV: 4.5.2 for python installed and working.

Confirm CUDA is configured correctly

Lastly, if everything else passed with flying colors, you should also confirm that CUDA is properly configured with:

"%openCvBuild%\install\x64\vc16\bin\opencv_perf_cudaarithm.exe" --gtest_filter=Sz_Type_Flags_GEMM.GEMM/29

At the bottom of the output, you should see something in green that says:
[ PASSED ] 1 test.

If you are still running into trouble, check out the Credits Section below, and look at JamesBowley’s article. He goes into more depth when it comes to troubleshooting than I have.

PyCharm Troubleshooting

If you’re like me and use PyCharm, you’ll find that while OpenCV now works outside of PyCharm, it doesn’t when opening a project in PyCharm…

There are a number of reasons for this, but the solution that I found actually worked was a combination of answers off of Stackoverflow and Github issue trackers…

1. Add OpenCV_Build to your env paths

Hit the Windows key, and type env, it should pop up with the option to edit your system environment variables. Open the window, and click “Environment Variables” in the bottom right.

There are two sections within that window. One is titled “User variables for Username” and the other is called “System Variables”. In the “User variables for username” section, double click the variable called “Path”.

Then click “New” to add a new entry.

Then copy and paste the opencv-4.5.2\build\install\x64\vc16\bin\ folder location. It should be located in your OpenCV_Build folder. Unlike before, make sure that you use backslashes (“\”) here instead of front slashes (“/”).

Do the same in the System Variables section.

Check to see if PyCharm now runs, if not continue to the next step.

2. Add anaconda symlink folder to Anaconda3

While this apparently isn’t a necessary step, PyCharm still has some bugs with it looking for a non-existent folder called anaconda instead of anaconda3… so we’ll go ahead and symlink the two together.

mklink /D C:\Users\Benge\anaconda C:\Users\Benge\Anaconda3

Double-check PyCharm (probably still doesn’t work). And if not, continue to the next step.

3. Add Build Folder SymLink to Conda Site-Packages

You’ll want to create another symlink, but instead of anaconda, you’re going to be linking the opencv-4.5.2\build\install\x64\vc16\bin\ folder to the anaconda3 site-packages folder.

mklink /D E:\OpenCV_Build\opencv-4.5.2\build\install\x64\vc16\bin C:\Users\Benge\anaconda3\envs\py38\lib\site-packages

Obviously, change it up to whatever your conda env is called & located instead of mine which is uncreatively called py38.

PyCharm Caveat

After all of that, your project should run just fine with your custom CUDA-enabled OpenCV, but you’ll probably notice that PyCharm still shows a red squiggle under the import cv2 line. I don’t know why it insists that it cannot find the package despite the fact that it is there and it runs correctly… It’s just an annoying bug in PyCharm, and there isn’t anything I’ve found that can fix it.

Credits:

A large part of the reason I was able to get OpenCV up and running is because of JameBowley’s guide on it. While it was extremely helpful, I found that it was a little disorganized & did not include some of the steps that I found were necessary to get the OpenCV build up and running within a Conda env in PyCharm.

Shout out to M. Haroon Shakeel for a concise (but unfortunately not complete) guide on building OpenCV with CUDA. His was the first actual guide that went into depths on building OpenCV on Windows and didn’t simply say to use Linux.

Shout out to Miki on Stackoverflow for helping me out, and eventually pointing me to JameBowley’s guide.

Final Thoughts

Building OpenCV from the source code was definitely a rollercoaster of emotions for me and not something I’d like to do again if I could avoid it… that being said, I feel like I learned a lot, and am very grateful for the people who have taken the time and energy to provide resources to make it possible.

Questions?

You can find me on:
- GitHub: https://github.com/bengejd/
- Medium: https://medium.com/@JordanBenge
- Twitter: https://twitter.com/J_Benge13

Who am I? My name is Jordan Benge, I am a Software Developer who loves helping others and contributing to Open-Source whenever possible. I like to write up guides on how to do things that interest me that aren’t completely covered elsewhere.

If you enjoyed this story, please click the 👏 button and share to help others find it! Feel free to leave a comment below if you need any help, and I’ll try to answer your questions as best as I can.

--

--

Jordan Benge
Jordan Benge

Written by Jordan Benge

My name is Jordan Benge, I’m a freelance developer, who sometimes likes to write helpful articles on Medium for people who want to do things but don’t know how.

No responses yet