search
LoginSignup
2

posted at

updated at

PythonでOpenCV with CUDAを使う方法

概要

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で実行する場合は環境構築が必要です。その際に役に立ちそうな記事を列挙します。

その他参考文献

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2