Skip to content

Instantly share code, notes, and snippets.

@Birch-san
Last active June 5, 2024 13:24
Show Gist options
  • Save Birch-san/ce02730e7987a7154b6e74efc06f182a to your computer and use it in GitHub Desktop.
Save Birch-san/ce02730e7987a7154b6e74efc06f182a to your computer and use it in GitHub Desktop.
Building OpenCV with CUDA acceleration

For CUDA 12, see Installing CUDA 12.1.1 + PyTorch nightly + Python 3.10 on Ubuntu 22.10 for how to install Nvidia driver 530, gcc 12 and CUDA 12.1.1 libraries.
If you want CUDA 11.8, then you can use latest Nvidia driver from Production branch, 525, with gcc 11.

Activate your conda environment, if you haven't done so already.

CUDA 11:
Make sure gcc 11 is the default gcc for your OS, or select gcc 11 explicitly.
CUDA 12:
Make sure gcc 12 is the default gcc for your OS, or select gcc 12 explicitly.
Check CUDA_DIR below points to the CUDA installation you wish to use.

Look up your CUDA Architecture, e.g. 4090 has architecture 8.9. Use this to determine the CUDA_ARCH variable below.

git clone --depth 1 --recurse-submodules --shallow-submodules https://github.com/opencv/opencv
-python.git
CUDA_DIR=/usr/local/cuda-12.1
CUDA_ARCH=8.9
CMAKE_OPTS=(
  -DWITH_TBB=1
  -DENABLE_FAST_MATH=1
  -DCUDA_FAST_MATH=1
  -DWITH_CUBLAS=1
  -DWITH_CUDA=1
  -DBUILD_opencv_cudacodec=0
  -DWITH_CUDNN=1
  -DOPENCV_DNN_CUDA=1
  -DCUDA_ARCH_BIN="$CUDA_ARCH"
  -DWITH_V4L=0
  -DWITH_QT=0
  -DWITH_OPENGL=1
  -DWITH_GSTREAMER=0
  -DBUILD_SHARED_LIBS=0
  -DBUILD_TESTS=0
  -DBUILD_PERF_TESTS=0
  -DBUILD_EXAMPLES=0
  -DWITH_OPENEXR=0
)
ENABLE_CONTRIB=1 MAKEFLAGS="-j$((`nproc`+1))" CMAKE_ARGS="${CMAKE_OPTS[@]}" PATH="$CUDA_DIR/bin:$PATH" LD_LIBRARY_PATH="$CUDA_DIR/lib64" pip wheel . --verbose

The build may end with something like this (including a worrying error):

  Building wheel for opencv-contrib-python (pyproject.toml) ... done
  Created wheel for opencv-contrib-python: filename=opencv_contrib_python-4.7.0.6b73d90-cp310-cp310-linux_x86_64.whl size=57531505 sha256=bb83a84e10675be63959286b7fa6c1397ab5d4a35ff053393520cbc2c4d18417
  Stored in directory: /home/birch/.cache/pip/wheels/bd/38/4d/c2b842930212306e78623d4bd39e8d606ea7ba7282c688bbd0
  WARNING: Built wheel for opencv-contrib-python is invalid: Metadata 1.2 mandates PEP 440 version, but '4.7.0.6b73d90' is not
Failed to build opencv-contrib-python
ERROR: Failed to build one or more wheels

Let's ignore the error (it looks like it finished creating the wheel).
Given that filepath: install the wheel like so:

pip install --force-reinstall /home/birch/.cache/pip/wheels/bd/38/4d/c2b842930212306e78623d4bd39e8d606ea7ba7282c688bbd0/opencv_contrib_python-4.7.0.6b73d90-cp310-cp310-linux_x86_64.whl

Check whether it worked, like so:
ensure that you are not inside the opencv-python directory when running this!

python -c 'from cv2.cuda import getCudaEnabledDeviceCount; print(getCudaEnabledDeviceCount())'

If it returns 1: you have done well!

Using it

from numpy.typing import NDArray
import cv2
from cv2.cuda import getCudaEnabledDeviceCount

assert getCudaEnabledDeviceCount() > 0, "No CUDA-enabled devices detected (this is very likely to indicate that OpenCV was compiled without CUDA support)"

img: NDArray = cv2.imread('my-cool-img.jpg')

# allocate an on-GPU buffer
g_img = cv2.cuda.GpuMat()
# transfer our on-CPU image into the GPU buffer
g_img.upload(img)

# resize our on-GPU image
g_resized: cv2.cuda.GpuMat = cv2.cuda.resize(g_img, (512, 512), interpolation=cv2.INTER_AREA)

# transfer the resized on-GPU image back to CPU
resized: NDArray = g_resized.download()
@Birch-san
Copy link
Author

Ubuntu 24.04 update:
I didn't find a way to get it to install on Python 3.12.

I made a Python 3.11 venv instead.
I had to point c++ and cc to g++-12 and gcc-12 respectively:

# register an alternative which points to GCC 12
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-12 10
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 10

# interactive picker to select an alternative (choose GCC 12)
sudo update-alternatives --config cc
sudo update-alternatives --config c++

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment