概要
pip経由でOpenCVをインストールすると使用できないモジュールや機能がありますが、GPU利用もその一つです。公式ドキュメントや参考文献を見ながらOpenCVをC++からビルドしてPythonでGPUを使用できるようにします。
OpenCV with GPU
OpenCVでGPUを使うことができます。もう少し具体的に言うとOpenCVで用意されているCUDAモジュールを使用することでNVIDIA GPUを使うことができます。他にもOpenCLを使うこともできたり細かい話は色々ありますが詳細は割愛します。
pipでインストールしたOpenCVには制限がある?
PythonでOpenCVを使う場合、pipを使って下記のコマンドでインストールすると思います。
pip install opencv-python
または
pip install opencv-contrib-python
このようにpip経由でインストールされたOpenCVではCUDAを使用することができません。例えば次のようなCUDAを使用するコードを書くとエラーになります。
import sys
import cv2
### Read source image
img_src = cv2.imread("/image.jpg")
### Run with GPU
img_gpu_src = cv2.cuda_GpuMat()
img_gpu_dst = cv2.cuda_GpuMat()
for i in range(100):
img_gpu_src.upload(img_src)
> OpenCV(4.5.5) /io/opencv/modules/core/include/opencv2/core/private.cuda.hpp:106: error:
(-216:No CUDA support) The library is compiled without CUDA support in function 'throw_no_cuda'
GPUを使用するにはC++からオプションを指定してビルドしたものを使う必要があります。
C++からビルドって何の話?
突然C++がでてきて何の話だと思われるかもしれませんので補足です。
OSSであるOpenCVのソースコードはこちらで見ることが可能で、例えばdnnモジュール
の中身が知りたければopencv/modules/dnn/src/
で見ることができます。ソースコードを見てみると.cpp
ファイルがたくさんあることがわかります。なのでOpenCVはC++から実行することができます・・・というよりはもともとC++から実行できるものをPythonで実行できるようにビルドしているという方が正確です。
ビルドはCMakeを使用するのですが、その際にCUDAが使えるようにWITH_CUDNNやWITH_CUDAといったオプションをONにする必要があります。
なお、CMakeについては下記を参照ください。
OpenCVをビルドする
前置きが長くなりました。それでは実際にビルドしていきましょう。実行環境はGoogle Colaboratory
です。オプションについてはこちらに説明がありますが、とりあえずGPUを使うだけであれば下記のソースコードで問題ないと思います。また、注意点としてこのビルドは時間がかかります。
%cd /content
# opencvおよびopencv_contribをcloneする。
!git clone https://github.com/opencv/opencv
# opencv_contribが不要であればコメントアウト
!git clone https://github.com/opencv/opencv_contrib
# ビルド先のディレクトリの作成
!mkdir /content/build
%cd /content/build
# オプションの指定
!cmake -DOPENCV_EXTRA_MODULES_PATH=/content/opencv_contrib/modules -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF -DWITH_OPENEXR=OFF -DWITH_CUDA=ON -DWITH_CUBLAS=ON -DWITH_CUDNN=ON -DOPENCV_DNN_CUDA=ON /content/opencv
# ビルド
!make -j8 install
OPENCV_EXTRA_MODULES_PATH
ではcontribのパスを指定しています。今回はcontribも含めてビルドしていますが、もしcontribが不要であれば削除して構いません。
ビルド後は/content/opencv/build/lib/python3
以下にcv2.cpython-37m-x86_64-linux-gnu.so
が作成されています。MyDriveに保存する場合は次のようにcpコマンドを使えば良いかと思います。
!cp /content/build/lib/python3/cv2.cpython-37m-x86_64-linux-gnu.so /content/cv2.cpython-37m-x86_64-linux-gnu.so
!mkdir /content/drive/{your_saved_path}/cv2_with_GPU
!cp /content/cv2.cpython-37m-x86_64-linux-gnu.so /content/drive/{your_saved_path}/cv2.cpython-37m-x86_64-linux-gnu.so
!pip uninstall opencv-python -y
# ビルド済みのOpenCV(GPU対応)を呼び出す
!cp "/content/drive/{your_saved_path}/cv2.cpython-37m-x86_64-linux-gnu.so" .
ランタイムを再起動してimport
してgetCudaEnabledDeviceCount
の結果を確認して1がでればOKです。また、ビルドしたバージョンは__version__
で確認できます。
import cv2
print(cv2.cuda.getCudaEnabledDeviceCount()) # 結果が1であればOK
cv2.__version__
参考になりそうな記事一覧
今回はGoogle Colaboratory
で実行したので環境構築をスキップできましたがUbuntuやDockerで実行する場合は環境構築が必要です。その際に役に立ちそうな記事を列挙します。
その他参考文献