OpenCVでCUDAの利用

はじめに

今回はOpenCVのCUDA機能を利用できるようにします。利用環境は以下のとおり。
  1. OS:Windows 7 64bit
  2. マシン:TSUKUMOのG-GEAR
  3. C++コンパイラ:Visual Studio 2008 Pro SP1
  4. グラフィックボード:GeForce GTX580
  5. グラフィックボードドライバ:270.81
  6. CUDA 4.0
  7. OpenCV 2.3.1

OpenCVのインスコ

OpenCVは本家からダウンロードしました。
OpenCV本家
http://opencv.willowgarage.com/wiki/ 今回使うversionは2.3.1です。 インストールといっても、ダウンロードしたexeを実行すると、解凍されてされてファイル一式が入ったディレクトリが出来上がるだけです。これを適当な場所に置きます。 あとはこれをVS2008で使えるように、プロジェクトのプロパティーにてパスを設定します。 「C/C++」→「全般」→追加のインクルードディレクトリ:
(opencvのディレクトリ)\build\include

「リンカ」→「全般」→追加のライブラリディレクトリ:
(opencvのディレクトリ)\build\x86\vc9\lib   (CPUを使う場合)
(opencvのディレクトリ)\build\gpu\x86\lib   (GPUを使う場合)

をおきます。

また、DLLのある以下の場所のパスを通します。
(opencvのディレクトリ)\build\x86\vc9\bin   (CPUを使う場合)
(opencvのディレクトリ)\build\gpu\x86\bin   (GPUを使う場合)
(opencvのディレクトリ)\build\common\tbb\ia32\vc9

面倒であればコンパイルした実行ファイルと同じ場所にDLLをコピーしてきて置くのが楽です。 それと、デバッグモードで実行するときに"tbb_debug.dll"がないとおこられるので、tbb.dllをコピー&リネームでごまかしました。
注)
最初は、GPUが使えない旨のメッセージが出てだいぶハマりました。
GPUのライブラリでコンパイルされてないとかなんとか。
意味わからん。。。
で、オチは結局、DLLのパスをGPU用のものでなくCPU用のものにしていただけだった。。

GPUサンプルのコンパイルと実行

うまくOpenCVでCUDAが使えるかどうか、サンプルコードで検証して見ます。 OpenCV添付のサンプルコードのうち、以下のものを使います
(opencvのディレクトリ)\samples\gpu\performance

この中の三つのファイル
performance.h
performance.cpp
tests.cpp
をVS2008でコンパイルします。 このとき、performance.cppの先頭付近に次のコードを追加しました。


#ifdef _DEBUG
    #pragma comment(lib,"opencv_calib3d231d.lib")
    #pragma comment(lib,"opencv_core231d.lib")
    #pragma comment(lib,"opencv_contrib231d.lib")
    #pragma comment(lib,"opencv_features2d231d.lib")
    #pragma comment(lib,"opencv_flann231d.lib")
    #pragma comment(lib,"opencv_gpu231d.lib")
    #pragma comment(lib,"opencv_haartraining_engined.lib")
    #pragma comment(lib,"opencv_highgui231d.lib")
    #pragma comment(lib,"opencv_imgproc231d.lib")
    #pragma comment(lib,"opencv_legacy231d.lib")
    #pragma comment(lib,"opencv_ml231d.lib")
    #pragma comment(lib,"opencv_objdetect231d.lib")
    #pragma comment(lib,"opencv_ts231d.lib")
    #pragma comment(lib,"opencv_video231d.lib")
#else
    #pragma comment(lib,"opencv_calib3d231.lib")
    #pragma comment(lib,"opencv_core231.lib")
    #pragma comment(lib,"opencv_contrib231.lib")
    #pragma comment(lib,"opencv_features2d231.lib")
    #pragma comment(lib,"opencv_flann231.lib")
    #pragma comment(lib,"opencv_gpu231.lib")
    #pragma comment(lib,"opencv_haartraining_engine.lib")
    #pragma comment(lib,"opencv_highgui231.lib")
    #pragma comment(lib,"opencv_imgproc231.lib")
    #pragma comment(lib,"opencv_legacy231.lib")
    #pragma comment(lib,"opencv_ml231.lib")
    #pragma comment(lib,"opencv_objdetect231.lib")
    #pragma comment(lib,"opencv_ts231.lib")
    #pragma comment(lib,"opencv_video231.lib")
#endif

まあ、必要ないライブラリまで使っている気がしますが、最初だし気にしないことに。 もちろんGPU用のlibとdllを使ってコンパイルしてください。 で、コンパイル、実行。 ありゃ、途中でメモリ関連のエラーが出る。 でも、一部の種類の処理だけで、他は動いている模様。 引数に


performance.exe --filter matchTemplate


というように、テストしたい処理名だけを記述すれば、その処理のテストができます。 動く処理は動くみたい。 なので今日はここまででokにしましょうか。