【Jetson Nano】OpenCVからCUDAを使ってみる

【Jetson Nano】OpenCVからCUDAを使ってみる

Jetsonで画像処理をするならやっぱりGPUアクセラレーションを試さないと ということで、OpenCVからCUDAを使って基本画像処理をすることにした。
本記事では、Raspberry Pi Camera V2(imx219 camera module)から画像ストリームデータを取得し、それに対して画像処理を行う。

OpenCV4.3.0のインストール

僕が買ったJetson NanoにはJetPack 4.3がインストールされていて、OpenCVのバージョンは4.1.1になっている。4.1.1自体はCUDAに対応しているようだが、デフォルトで入っていたOpenCVはCUDA対応でビルドされていなかったらしい。

この記事を書いている時点での最新のOpenCVは4.3.0が最新なので、アップデートを兼ねてインストールすることにした。
インストールの際には下記の資料を参考にさせていただきました。

https://qiita.com/daisuzu_/items/8cc8de8ea8dc557a2aad

上記の記事では4.1.2だが、4.3.0に置き換えても同じことができる。
インストール時にめちゃくちゃメモリを食うのでスワップ領域の確保は必須。

下記に自分が使用したスクリプトを示します。

インストール作業は基本的に上記のスクリプトを走らせるだけ。
必要な周辺パッケージのインストール⇒opencvのダウンロード、zip解凍⇒ビルド
という手順を実行してくれる。

cmakeのオプションを一部変更する。
CUDAを使用するためにWITH_CUDAオプションをON。(-D WITH_CUDA=ON)
あと、自分の場合はYOLOを使用するためにpkg-configを使えるようにしておいた。(-D OPENCV_GENERATE_PKGCONFIG=ON)

pythonからOpenCV+CUDAを使ってみる

準備ができたところで、簡単なテストスクリプトを組んで見ることにする。

cvtColor()をCUDAで処理している。
このプログラムの中でやっていることはごく単純で

  • Gstreamerでカメラの画像を連続的にキャプチャ
  • imgにキャプチャ画像(カラー)を格納
  • GPUでカラー画像をモノクロ画像に変換
  • ウィンドウに表示

となっている。

CPU, GPU間のデータのやりとりや処理について、以下のように理解した。

①GPUのリソースを利用するためには、まずはGpuMatによってアロケーションを行う必要がある。
②次に、CPU領域にある画像配列imgをGPUの領域へアップロードupload()する。
③画像処理は、対象の関数cvtColor()の直前に”cuda”をつけるだけ。
④最後に、GPUで扱っていた配列img_gpu_dstをCPU領域へdownload()によって戻してやる。

アロケーションの部分のオーバーヘッドが大きいようなので、上記のスクリプトだともしかしたらCPUより遅いかもしれない。

単にGPUを使えば何でも速くなるわけではなく、プログラムの順序や構造に工夫が必要。

Jetsonカテゴリの最新記事