1.OpenCVでの画像処理を早くしたかった。
OpenCVを試してみると、思っていたより簡単に画像処理ができて、これはすごい!簡単!と感心しました!
動画のフレームを読みだして、画像処理して、動画に戻すという例もQiitaにあったので、早速試してみたのですが、なんか遅い。
NvidiaのCUDA使ったら早いんじゃないん?と思いましたが、OpenCVのCUDAの機能はpipではインストールできず、ソースからビルドしないといけないらしい。(pipでバイナリをダウンロードしないオプションも試してみたのですが、なんかうまくいかず)
ビルドを解説したサイトもQiitaをはじめ多数あるので、きっとできるだろう、と気楽に始めてみたのですが、いろいろつまづきずつも、最終的にはビルド、環境構築、OpneCVでCUDA利用ができたので、共有するものです。
2.環境紹介
Windows11
Python 3.11 (Microsoft Storeからインストール)
OpenCV 4.9
OpenCV contrib
CUDA SDK 12.32
NVIDIA Video Codec SDK 12.2.72
VisualStudio 2022
Cmake 3.29.2
3.ビルド
基本的には以下のサイトを参考にし何度もビルドしてました。
何度もビルド、セットアップする中で得たノウハウをメモ的に記載しておきます。
- 古いバージョンのCUDA SDKのセットアップでは、何も考えず次へ次へとセットアップしていると、Geforceのドライバが古くなってしまいます。セットアップではカスタムを選択し、CUDAだけセットアップし、ドライバやGeforceエクスペリエンスなどはチェックを外しておきましょう。
- Cmakeで、OpenCVのCUDAオプションにチェックを入れると、CUDAを認識しようとしますが、その時、システム変数の
CUDA_PATH
の参照先からCUDAのバージョンを確認します。私のようにゲーム用マシンで最新を維持したいが、ビルドでは古いCUDAを使いたいという場合には、CUDA_PATH
で古いCUDAへのパスを指定しましょう
(下図。図はいろいろ試行錯誤していた時のもので、最終的にはCUDA12.32にしています。ただ12.4でも良かったのではないかとも思って微妙に後悔しています・・・)
- システム変数を変更したり、追加した際は、再起動してシステム変数の読み直しをしましょう
- CmakeのConfigureで、NVIDIA Video Codec SDKがない、とワーニング?が出るので、Nvidia Developer Memberに登録して、ダウンロードして一緒にコンパイルしています。Interfaceの中身をIncludeに、LibをLibに入れたと思います。(必要なのかよくわかりません)
-
CUDA_ARCH_BIN
で、対象とするバージョンを減らすと、ビルド時間の短縮が可能です。そのPCだけでよければ、CUDA_ARCH_PTX
と同じにすればいいと思います。 - VisualStudio はC++によるデスクトップ開発をセットアップしますが、細かいことがよくわからないので、オプションは明らかに要らなさそうなのを除いてほぼ全部盛りにしました。
4.Python環境への導入とDLLエラー解消
ここが一番よくわからずモヤモヤしていました。
ビルドはできて、システム変数の登録もしたものの、どうにも動かない。
各システム変数を登録したりしながら、結局非推奨とされている、pip intall セットアップしたdir\python_loader でセットアップしています。
CUDAがもっと古いバージョンであれば、もしかすると問題ないのかもしれませんが、CUDA 11.8でもCUDA 12.32でも、import cv2
で、ImportError: DLL load failed while importing cv2: The specified module could not be found.
が出てました。
検索して、見つけたのがこちらの解説
中段に書いてある、
os.add_dll_directory("C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v12.0\\bin")
import cv2 as cv
というように、opencvをimportする前に、利用しているCUDAのDLLへのパスをdll_directoryに追加する、ということで解消しました。
opencvのコードに毎回書いてもいいのですが、面倒なので、私の方では勝手に次のようにしています。
C:\Users\ユーザー名\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0\LocalCache\local-packages\Python311\site-packages\cv2
の、__init__.py
で指定していまいました。
(もう少し良い方法があれば、ぜひ教えてください)
'''
OpenCV Python binary extension loader
'''
import os
import importlib
import sys
+ os.add_dll_directory("C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v12.3\\bin")
__all__ = []
try:
最終的な動作確認は、次のコードで実施しています。
出力結果も興味があれば開いてみてください。
import cv2
print('認識したGPUの個数:',cv2.cuda.getCudaEnabledDeviceCount()) # 結果が1であればOK
cv2.__version__
print('Build Information')
print(cv2.getBuildInformation())
出力結果
認識したGPUの個数: 1
Build Information
General configuration for OpenCV 4.9.0-dev =====================================
Version control: 4.9.0-384-gc577b24406
Extra modules:
Location (extra): C:/Users/ユーザ名/opencv_contrib/modules
Version control (extra): 4.9.0-66-gac994ed2
Platform:
Timestamp: 2024-04-19T00:33:01Z
Host: Windows 10.0.22631 AMD64
CMake: 3.29.2
CMake generator: Visual Studio 17 2022
CMake build tool: C:/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/amd64/MSBuild.exe
MSVC: 1939
Configuration: Debug Release
CPU/HW features:
Baseline: SSE SSE2 SSE3
requested: SSE3
Dispatched code generation: SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX
requested: SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
SSE4_1 (18 files): + SSSE3 SSE4_1
SSE4_2 (2 files): + SSSE3 SSE4_1 POPCNT SSE4_2
FP16 (1 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
AVX (9 files): + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
AVX2 (38 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
AVX512_SKX (8 files): + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX
C/C++:
Built as dynamic libs?: YES
C++ standard: 11
C++ Compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe (ver 19.39.33523.0)
C++ flags (Release): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /wd4819 /MP /O2 /Ob2 /DNDEBUG
C++ flags (Debug): /DWIN32 /D_WINDOWS /W4 /GR /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /EHa /wd4127 /wd4251 /wd4324 /wd4275 /wd4512 /wd4589 /wd4819 /MP /Zi /Ob0 /Od /RTC1
C Compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.39.33519/bin/Hostx64/x64/cl.exe
C flags (Release): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /MP /O2 /Ob2 /DNDEBUG
C flags (Debug): /DWIN32 /D_WINDOWS /W3 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi /fp:precise /MP /Zi /Ob0 /Od /RTC1
Linker flags (Release): /machine:x64 /INCREMENTAL:NO
Linker flags (Debug): /machine:x64 /debug /INCREMENTAL
ccache: NO
Precompiled headers: NO
Extra dependencies: cudart_static.lib nppc.lib nppial.lib nppicc.lib nppidei.lib nppif.lib nppig.lib nppim.lib nppist.lib nppisu.lib nppitc.lib npps.lib cublas.lib cudnn.lib cufft.lib -LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3/lib/x64
3rdparty dependencies:
OpenCV modules:
To be built: 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 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 shape signal stereo stitching structured_light superres surface_matching text tracking ts video videoio videostab wechat_qrcode world xfeatures2d ximgproc xobjdetect xphoto
Disabled: -
Disabled by dependency: -
Unavailable: alphamat cannops cvv freetype hdf java julia matlab ovis python2 python2 sfm viz
Applications: tests perf_tests apps
Documentation: NO
Non-free algorithms: NO
Windows RT support: NO
GUI:
Win32 UI: YES
VTK support: NO
Media I/O:
ZLib: build (ver 1.3.1)
JPEG: build-libjpeg-turbo (ver 2.1.3-62)
SIMD Support Request: YES
SIMD Support: NO
WEBP: build (ver encoder: 0x020f)
PNG: build (ver 1.6.37)
TIFF: build (ver 42 - 4.6.0)
JPEG 2000: build (ver 2.5.0)
OpenEXR: build (ver 2.3.0)
HDR: YES
SUNRASTER: YES
PXM: YES
PFM: YES
Video I/O:
DC1394: NO
FFMPEG: YES (prebuilt binaries)
avcodec: YES (58.134.100)
avformat: YES (58.76.100)
avutil: YES (56.70.100)
swscale: YES (5.9.100)
avresample: YES (4.0.0)
avdevice: NO
GStreamer: NO
DirectShow: YES
Media Foundation: YES
DXVA: YES
Parallel framework: Concurrency
Trace: YES (with Intel ITT)
Other third-party libraries:
Intel IPP: 2021.11.0 [2021.11.0]
at: C:/opencv/3rdparty/ippicv/ippicv_win/icv
Intel IPP IW: sources (2021.11.0)
at: C:/opencv/3rdparty/ippicv/ippicv_win/iw
Lapack: NO
Eigen: NO
Custom HAL: NO
Protobuf: build (3.19.1)
Flatbuffers: builtin/3rdparty (23.5.9)
NVIDIA CUDA: YES (ver 12.3, CUFFT CUBLAS NVCUVID NVCUVENC)
NVIDIA GPU arch: 80 86 89 90
NVIDIA PTX archs: 90
cuDNN: YES (ver 8.9.7)
OpenCL: YES (NVD3D11)
Include path: C:/Users/ユーザ名/opencv/3rdparty/include/opencl/1.2
Link libraries: Dynamic load
Python 3:
Interpreter: C:/Users/ユーザ名/AppData/Local/Microsoft/WindowsApps/python3.exe (ver 3.11.9)
Libraries: C:/Users/ユーザ名/AppData/Local/Programs/Python/Python311/libs/python311.lib (ver 3.11.9)
Limited API: NO
numpy: C:/Users/ユーザ名/AppData/Local/Packages/PythonSoftwareFoundation.Python.3.11_qbz5n2kfra8p0/LocalCache/local-packages/Python311/site-packages/numpy/core/include (ver 1.26.4)
install path: /registry/Lib/site-packages/cv2/python-3.11
Python (for build): C:/Users/ユーザ名/AppData/Local/Microsoft/WindowsApps/python3.exe
Java:
ant: NO
Java: NO
JNI: NO
Java wrappers: NO
Java tests: NO
Install to: C:/opencv/install
-----------------------------------------------------------------
PS C:\Users\ユーザ名\gcloud\opencv_nameless>
5. cv2.cudaしてみて
伝家の宝刀を手に入れたゾ!と思いましたが、思っていたより扱いが難しくて、またまた試行錯誤中です。