WSL2 + RTX 50 系で OpenCV 4.10 を CUDA 対応ビルドする手順(Blackwell sm_120 対応)

RTX 50 系(Blackwell, sm_120)はリリース直後ということもあり、pip install opencv-python で入る配布バイナリは長らく未対応でした。一方で OpenCV を自前ビルドする情報は英語圏でも断片的で、日本語ではほぼ皆無というのが執筆時点の状況です。

この記事では、Windows 11 + WSL2 (Ubuntu 24.04) を使って、OpenCV 4.10 + opencv_contrib を CUDA 12.8 / cuDNN 9.21 付きでビルドし、cv2.cuda.* API と DNN モジュールの CUDA バックエンドを使えるようにするまでを、コピペで再現可能な形で解説します。

対象読者: GPU で OpenCV を回したい中級〜上級エンジニア。Linux でのビルド作業が初見ではない方。
所要時間: 1〜2 時間(うちビルド本体が 35〜60 分)。
得られるもの: cv2.cuda_GpuMatcv2.cuda.bilateralFiltercv2.dnn.DNN_BACKEND_CUDA などの CUDA API 全般。


1. なぜ Windows ではなく WSL2 でビルドするのか

OpenCV の CUDA 対応ビルドを Windows ネイティブで通すのは、いつの時代もハマりどころが多い作業です。WSL2 を使うと、apt の依存解決と公式想定の構成にそのまま乗れるため、再現性が一気に上がります。

観点 Windows ネイティブ WSL2
ビルドツール VS 2022 Build Tools 必須、CMake と NVCC のバージョン整合でハマる apt の cmake / build-essential で素直に通る
FFMPEG / GStreamer 自前ビルドが必要、配布バイナリの ABI 衝突 apt で完結、依存解決が自動
TBB / Eigen / IPP 各種事情でリンクに失敗しがち 公式ガイド通りで通る
cv2.cuda_* 動作実績 不安定。Issue Tracker でも報告多数 公式が想定している主要環境

結論: GPU 版 OpenCV は WSL2 でビルド・運用するのが現実的です。Windows 側は CPU 版(pip install opencv-python)に留め、両者を venv レベルで分離するのが事故の少ない構成になります。


2. 前提環境

本記事はすでに以下が揃っている前提で進めます。未整備の場合は、NVIDIA 公式ドキュメントを参照してください。

  • Windows 11(WSL2 と WSLg が動く版)
  • WSL2 + Ubuntu 24.04 LTS
  • NVIDIA ドライバ(Windows 側、CUDA 12.8 対応版)
  • WSL 内に CUDA Toolkit 12.8 と cuDNN 9.21(apt から cuda-toolkit-12-8cudnn9-cuda-12 を導入)
  • WSL Ubuntu 内のシステム Python 3.12(Ubuntu 24.04 既定)

CUDA バージョンは 12.8 以上必須: Blackwell(sm_120)は CUDA Toolkit 12.7 以下では Unsupported gpu architecture 'compute_120' で失敗します。Ada Lovelace(RTX 40 系, sm_89)以下なら CUDA 12.4 系でも通ります。

GPU の Compute Capability 早見表:

GPU 世代 代表モデル Compute Capability
Ampere RTX 30 系, A100 8.6 / 8.0
Ada Lovelace RTX 40 系 8.9
Hopper H100 9.0
Blackwell RTX 50 系 12.0

3. 全体フロー

  1. ビルド依存パッケージのインストール(apt)
  2. OpenCV / opencv_contrib ソースの取得
  3. Python 用 venv の準備(cv2 の出力先となる)
  4. CMake configure(CUDA / cuDNN / Python venv を指定)
  5. ninja でビルド(35〜60 分)
  6. ninja install(システム + venv の site-packages)
  7. 動作確認(cv2.cuda.getCudaEnabledDeviceCount() など)

4. ビルド依存パッケージのインストール

WSL Ubuntu のターミナルで以下を実行します。

sudo apt-get update
sudo apt-get install -y \
    cmake ninja-build pkg-config build-essential git unzip \
    libgtk-3-dev \
    libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libavfilter-dev \
    libv4l-dev libxvidcore-dev libx264-dev \
    libjpeg-dev libpng-dev libtiff-dev libopenexr-dev libwebp-dev \
    libtbb-dev libatlas-base-dev gfortran libeigen3-dev \
    libgflags-dev libgoogle-glog-dev \
    libfreetype-dev libharfbuzz-dev \
    python3-dev python3-numpy

合計約 500 MB のダウンロード、3〜5 分程度です。


5. OpenCV / opencv_contrib のソース取得

ビルド作業用ディレクトリは ~/opencv-build/ を例にしていますが、好きな場所で構いません。

mkdir -p ~/opencv-build && cd ~/opencv-build
wget -q -O opencv.zip         https://github.com/opencv/opencv/archive/refs/tags/4.10.0.zip
wget -q -O opencv_contrib.zip https://github.com/opencv/opencv_contrib/archive/refs/tags/4.10.0.zip
unzip -q -o opencv.zip
unzip -q -o opencv_contrib.zip

opencv-4.10.0/opencv_contrib-4.10.0/ が並ぶことを確認してください。zip は削除してかまいません。


6. cv2 専用 venv を作る

OpenCV の Python バインディングは、ビルド時の Python マイナーバージョンnumpy ヘッダ に強く紐付きます。普段のプロジェクト venv とは分離した、cv2 専用の venv を用意するのが安全です。本記事では ~/cv-env/.venv を例にしますが、パスは任意です。

mkdir -p ~/cv-env && cd ~/cv-env
echo "3.12" > .python-version
uv venv --python /usr/bin/python3.12 .venv
uv pip install --python ~/cv-env/.venv/bin/python numpy

ポイントは、uv 管理ではなく システム Python(/usr/bin/python3.12)を venv の元にする ことです。理由は、後続の CMake が /usr/include/python3.12/usr/lib/x86_64-linux-gnu/libpython3.12.so を参照するため、システム Python と venv の Python が同じ系列であるとリンクで事故りにくいからです。

確認:

~/cv-env/.venv/bin/python -c "import sys, numpy; print(sys.version); print(numpy.__version__)"
# 例: 3.12.3 ... / 2.4.4

7. CMake configure

~/opencv-build/configure.sh を作成します。

#!/usr/bin/env bash
set -euo pipefail

export PATH=/usr/local/cuda-12.8/bin:/usr/bin:/bin
export CUDACXX=/usr/local/cuda-12.8/bin/nvcc
export LD_LIBRARY_PATH=/usr/local/cuda-12.8/lib64:${LD_LIBRARY_PATH:-}

cd "$HOME/opencv-build"
rm -rf build && mkdir build && cd build

cmake -G Ninja \
  -D CMAKE_BUILD_TYPE=Release \
  -D CMAKE_INSTALL_PREFIX=/usr/local \
  -D OPENCV_EXTRA_MODULES_PATH="$HOME/opencv-build/opencv_contrib-4.10.0/modules" \
  -D OPENCV_GENERATE_PKGCONFIG=ON \
  -D BUILD_opencv_python2=OFF \
  -D BUILD_opencv_python3=ON \
  -D PYTHON3_EXECUTABLE="$HOME/cv-env/.venv/bin/python" \
  -D PYTHON3_INCLUDE_DIR=/usr/include/python3.12 \
  -D PYTHON3_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.12.so \
  -D PYTHON3_NUMPY_INCLUDE_DIRS="$HOME/cv-env/.venv/lib/python3.12/site-packages/numpy/_core/include" \
  -D OPENCV_PYTHON3_INSTALL_PATH="$HOME/cv-env/.venv/lib/python3.12/site-packages" \
  -D WITH_CUDA=ON \
  -D WITH_CUDNN=ON \
  -D OPENCV_DNN_CUDA=ON \
  -D ENABLE_FAST_MATH=ON \
  -D CUDA_FAST_MATH=ON \
  -D WITH_CUBLAS=ON \
  -D CUDA_ARCH_BIN="8.6;8.9;12.0" \
  -D CUDA_ARCH_PTX="" \
  -D CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-12.8 \
  -D WITH_TBB=ON \
  -D WITH_FFMPEG=ON \
  -D WITH_GTK=ON \
  -D WITH_QT=OFF \
  -D WITH_OPENGL=ON \
  -D WITH_V4L=ON \
  -D BUILD_TESTS=OFF \
  -D BUILD_PERF_TESTS=OFF \
  -D BUILD_EXAMPLES=OFF \
  -D BUILD_DOCS=OFF \
  -D INSTALL_C_EXAMPLES=OFF \
  -D INSTALL_PYTHON_EXAMPLES=OFF \
  -D BUILD_opencv_world=OFF \
  ../opencv-4.10.0

実行:

chmod +x ~/opencv-build/configure.sh
~/opencv-build/configure.sh

7.1 CUDA_ARCH_BIN の指定方針

複数世代をサポートしたいなら 8.6;8.9;12.0 を指定し、自分のマシンが Blackwell だけで動けばよいなら 12.0 単独で指定するとビルドが約 30% 速くなります。Ampere/Ada/Blackwell 混在環境なら 3 つ全部入れておくのが無難です。

7.2 configure 出力で確認すべきこと

最後の数十行に以下が出ているか必ず確認します。

NVIDIA CUDA:                   YES (ver 12.8, CUFFT CUBLAS FAST_MATH)
  NVIDIA GPU arch:             86 89 120
cuDNN:                         YES (ver 9.21.1)
Python 3:
  Interpreter:                 .../cv-env/.venv/bin/python (ver 3.12.3)
  numpy:                       .../cv-env/.venv/lib/python3.12/site-packages/numpy/_core/include
  install path:                .../cv-env/.venv/lib/python3.12/site-packages/cv2/python-3.12

ここで cuDNN: NONVIDIA CUDA: NO が出るとビルドしても cv2.cuda.* が空っぽになります。先に進まず、トラブルシュート(§11)を当ててから次へ。

7.3 OpenCV モジュール一覧(出るはず)

alphamat 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 freetype 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 sfm shape signal stereo stitching structured_light superres surface_matching text tracking video videoio videostab wechat_qrcode xfeatures2d ximgproc xobjdetect xphoto

cuda* 系がすべて含まれていれば正常です。


8. ビルド

cd ~/opencv-build/build
PATH=/usr/local/cuda-12.8/bin:$PATH \
LD_LIBRARY_PATH=/usr/local/cuda-12.8/lib64 \
ninja -j 12 2>&1 | tee ~/opencv-build/build.log
  • -j 12 は並列度。nproc の 75% 程度を目安に。RAM 30 GB に対して 16 並列だと一時的に逼迫することがあるため、12 程度に抑えるのが安定。
  • 進捗は [N/1678] 形式で表示されます(contrib 込みでおよそ 1678 タスク)。
  • 実測ビルド時間: RTX 50 系ホストで -j 12 指定時に約 35〜50 分。

別ターミナルで進捗を眺める例:

tail -f ~/opencv-build/build.log | grep -E "^\["

9. インストールと動作確認

cd ~/opencv-build/build
sudo ninja install
sudo ldconfig

これで以下が配置されます。

配置先 内容
/usr/local/lib/libopencv_*.so.4.10 OpenCV 共有ライブラリ
/usr/local/include/opencv4/ C++ ヘッダ
/usr/local/lib/pkgconfig/opencv4.pc pkg-config 用
~/cv-env/.venv/lib/python3.12/site-packages/cv2/ Python バインディング

動作確認:

~/cv-env/.venv/bin/python <<'EOF'
import cv2
print("OpenCV:", cv2.__version__)
print("CUDA devices:", cv2.cuda.getCudaEnabledDeviceCount())
for line in cv2.getBuildInformation().splitlines():
    if any(k in line for k in ("CUDA", "cuDNN", "NVIDIA")):
        print(" ", line)

import numpy as np
gpu_mat = cv2.cuda_GpuMat()
host = (np.random.rand(2048, 2048) * 255).astype(np.uint8)
gpu_mat.upload(host)
gpu_blur = cv2.cuda.bilateralFilter(gpu_mat, 9, 75, 75)
out = gpu_blur.download()
print("GPU bilateralFilter ok, output shape:", out.shape)
EOF

期待される出力(抜粋):

OpenCV: 4.10.0
CUDA devices: 1
   NVIDIA CUDA:                 YES (ver 12.8, CUFFT CUBLAS FAST_MATH)
   cuDNN:                       YES (ver 9.21.1)
   NVIDIA GPU arch:             86 89 120
GPU bilateralFilter ok, output shape: (2048, 2048)

CUDA devices: 0 が返ってきたら、§7 の WITH_CUDA=ON が効いていないか、別の cv2 が import されている疑いが濃厚です。§11 で対処してください。


10. 他プロジェクトから cv-env を使う

~/cv-env/.venv をそのまま GPU OpenCV 専用 venv として使い回す運用が一番事故が少ないです。

~/cv-env/.venv/bin/python my_script.py
# または
source ~/cv-env/.venv/bin/activate
python my_script.py
deactivate

pip install opencv-python を絶対に実行しないこと。pip 配布版の cv2 がインストールされた瞬間、自前ビルドの CUDA 版が壊れます。uv add opencv-python も同様。

uv で管理している別プロジェクトから使いたい場合は、シンボリックリンクで cv2 だけを貸す手があります。

cd path/to/your/uv-project
uv venv .venv
ln -s ~/cv-env/.venv/lib/python3.12/site-packages/cv2 \
      .venv/lib/python3.12/site-packages/cv2
.venv/bin/python -c "import cv2; print(cv2.__version__)"

11. トラブルシュート

ビルド作業中に実際に遭遇する確率が高い順に並べています。

11.1 configure で cuDNN: NO

  • dpkg -l | grep cudnn9-cuda-12 で入っているか確認。
  • 入っているのに認識されないときは find / -name "cudnn.h" 2>/dev/null でヘッダ位置を確認し、-D CUDNN_INCLUDE_DIR=/usr/include-D CUDNN_LIBRARY=/usr/lib/x86_64-linux-gnu/libcudnn.so を CMake 引数に明示する。

11.2 nvcc fatal: Unsupported gpu architecture 'compute_120'

  • CUDA Toolkit 12.7 以下は Blackwell(sm_120)未対応。12.8 以上 が必須。
  • nvcc --version でバージョンを確認すること。

11.3 import cv2numpy.core.multiarray failed to import

  • ビルド時の numpy バージョンと、実行時の numpy バージョンが違う場合に出る。venv の numpy をうっかり上げ下げした疑い。
  • 対処: ビルド時のバージョンに戻す(例: ~/cv-env/.venv/bin/pip install "numpy==2.4.4")。

11.4 import cv2version GLIBCXX_3.4.32 not found

  • Conda 環境の libstdc++LD_LIBRARY_PATH 経由で割り込んでいるパターン。
  • 対処: conda deactivate で抜けてから、unset CONDA_PREFIX した状態で Python を起動。

11.5 ビルド中に c++: fatal error: Killed signal terminated program cc1plus

  • メモリ不足。並列度を下げる(ninja -j 8-j 4)。
  • WSL の .wslconfig%USERPROFILE%\.wslconfig)でメモリを絞っているなら、memory=24GB など増量を検討。

11.6 cv2.cuda.getCudaEnabledDeviceCount() が 0

  • WITH_CUDA=ON で configure できているのに 0 → 別の cv2 が import されている。
  • python -c "import cv2; print(cv2.__file__)"~/cv-env/.venv/.../cv2/ 配下を指しているか確認。
  • pip 版が混入していたら pip uninstall opencv-python opencv-contrib-python opencv-python-headless

11.7 cv2.imshowcannot connect to display

  • WSL2 の GUI(WSLg)は最近の Windows 11 に標準で入っている。echo $DISPLAY が空なら wsl --shutdown してから再起動。
  • それでもダメなら cv2.imshow を諦めて cv2.imwrite でファイルに落とし、Windows 側で開く運用が一番速い。

12. この環境でできるようになること

  • cv2.cuda 系 API: cv2.cuda_GpuMat, cv2.cuda.bilateralFilter, cv2.cuda.HoughLinesDetector, cv2.cuda.SURF_CUDA など contrib 含む全 CUDA 関数。
  • DNN モジュールの CUDA バックエンド: net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) で YOLO / SSD / ResNet 等を GPU 推論。
  • opencv_contrib の追加機能: ArUco マーカ、SfM、Tracking、Optical Flow 拡張、Stereo、Structured Light、ximgproc 等。
  • FFmpeg ベースの動画 I/O: H.264 / H.265 / AV1 のデコード(CPU 経由。GPU デコードを使うには別途 NVDEC を組み込むビルド構成が必要)。
  • PyTorch との同居: PyTorch 用 venv を別に持っておけば、CUDA Stream を介して PyTorch テンソルと cv2 GpuMat を併用するパイプラインが組めます。
  • 自作 CUDA カーネルとの連携: Toolkit 整合の nvcc ビルドが通った状態なので、自前カーネルから cv2::cuda::Stream を渡して連携する開発が可能。

13. ライセンス・商用利用上の注意

  • OpenCV 本体および contrib のうち多くは Apache License 2.0 で再配布可能ですが、xfeatures2d の SIFT/SURF など一部のアルゴリズムは特許や別ライセンスが絡みます。商用利用前にモジュール単位で確認してください(OpenCV のライセンス FAQ にまとまっています)。
  • cuDNN は NVIDIA の EULA に従います。再配布や派生物の扱いに制限があるため、業務で使う場合はライセンス条項を確認してから配布物に含めてください。
  • 上記は一般情報であり法的助言ではありません。商用展開前に必ず社内法務・利用規約原文を確認してください。

14. 確認済みバージョン(執筆時点)

ソフトウェア バージョン
Ubuntu (WSL) 24.04 LTS
GCC 13.3
CMake apt 既定(3.28 系)
Ninja apt 既定(1.11 系)
CUDA Toolkit 12.8.93
cuDNN 9.21.1
FFmpeg (avcodec) 60.31
Python 3.12.3 (system)
numpy 2.4.4
OpenCV / opencv_contrib 4.10.0
GPU NVIDIA RTX 50 系 (sm_120)
ビルド時間 約 35〜50 分 (-j 12)

まとめ

WSL2 上で OpenCV 4.10 を CUDA 12.8 + cuDNN 9.21 でビルドする一連の流れを通すと、Blackwell 世代でも cv2.cuda.* と DNN の CUDA バックエンドが手元で動かせるようになります。CPU 版の pip install opencv-python と取り違えると環境が壊れやすいため、専用 venv を 1 つ持つ運用 にしておくと事故が起きにくくなります。