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_GpuMat、cv2.cuda.bilateralFilter、cv2.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-8とcudnn9-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. 全体フロー
- ビルド依存パッケージのインストール(apt)
- OpenCV / opencv_contrib ソースの取得
- Python 用 venv の準備(cv2 の出力先となる)
- CMake configure(CUDA / cuDNN / Python venv を指定)
- ninja でビルド(35〜60 分)
- ninja install(システム + venv の site-packages)
- 動作確認(
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: NO や NVIDIA 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 cv2 で numpy.core.multiarray failed to import
- ビルド時の numpy バージョンと、実行時の numpy バージョンが違う場合に出る。venv の numpy をうっかり上げ下げした疑い。
- 対処: ビルド時のバージョンに戻す(例:
~/cv-env/.venv/bin/pip install "numpy==2.4.4")。
11.4 import cv2 で version 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.imshow で cannot 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 つ持つ運用 にしておくと事故が起きにくくなります。
