OpenCVを使うならC++かPythonか?


このエントリーをはてなブックマークに追加

Computer Visionの巨大なライブラリであるOpenCVC/C++, Python, Javaのインターフェースが提供されており、どの言語で始めるか迷っている方もいるかと思います。私は残念ながらJavaからOpenCVを使ったことはないのですが、C++からはそれなりに、Pythonからは少しだけOpenCVを利用した経験があります。そこでC++PythonのそれぞれからOpenCVを利用するときのメリット、デメリットを、初心者向けにまとめようと思います。

初めやすさ

どちらの場合も、公式で配布されているインストーラをダウンロードし、解凍するところまでは同じです。

C++の場合、インクルードパスとライブラリパスをセットし、DLLにパスを通すという作業が必要になります。x86x64の違い, Debug/Releaseモードの違い、vc10, vc11, vc12の違いなど、ハマりどころが多く、まともに動かせるようになるまで苦労するかもしれません。

Pythonの場合、Python本体とnumpyをインストールした後、cv2.pydにパスを通すだけでOpenCVを使えるようになるはずです。C++に比べるとだいぶ簡単です。

以上より、初めやすさの点ではPythonに軍配が上がります。

コードの見やすさ

C++の場合、関数に与えた引数を見ただけでは入力と出力が分からないという弱点があります。例えば色空間を変換する関数cv::cvtColor()の使用例を以下に示します。

cv::cvtColor(img1, img2, cv::COLOR_BGR2GRAY)

これを見ただけではimg1からimg2への変換かimg2からimg1への変換かが分かりません(ちなみにimg1からimg2への変換が正解)。もちろんIDEを使っているならマウスで関数を選択するなどしてヒントを表示させることもできますが、やや面倒です。

一方Pythonの場合は、出力が戻り値になるよう統一されているので、変換の方向が明らかです。

img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

戻り値が複数ある場合もOKな点もC++より優れています。

コードの見やすさはPythonの勝ち。

IDEとの相性

C++の場合、ヘッダファイルをインクルードするので、補完も効きますしや関数のシグネチャ情報を表示させることもできます。

Pythonの場合、私の知る限り補完は限定的にしか働きません(Python版OpenCVにて補完機能を使う (VS2013 Python Tools) - minus9d's diary)。

IDEとの相性はC++が上。

他ライブラリとの連携

これはPythonが得意とするところです。

Pythonでは画像をnumpyのarrayを使って表現するために、numpyの豊富な関数群を利用できるのが強みです。例えば、同じ画像を異なる関数で処理したとき、その結果が同じかどうかを確かめるのにnumpy.allclose()という関数を利用することができます。同じことをC++で行うためには自分で関数を書かないといけないはずです。

その他、matplotlib, scipy, scikit-learnなどの強力なライブラリと簡単に連携できるのも優位な点です。

他ライブラリとの連携はPythonが優位。

速度

PythonからOpenCVを使う場合でも、結局は内部ではDLLを叩いているはずなので速度面のペナルティは限定的なのではないかと想像します(実際に比較したわけではありませんが…)。しかしPythonでは気をつけないと思わぬ速度低下が簡単に起こります。

例えば画像のすべての要素に1を足すのに、(1)2重ループ (2)array + scalarの2種類の方法をとり、経過時間を比較してみます。

import timeit

# 方法1
start = timeit.default_timer()
for j in xrange(height):
    for i in xrange(width):
        img[j,i] += 1
end = timeit.default_timer()
print "elapsed time = ", end - start

# 方法2
start = timeit.default_timer()
img += 1
end = timeit.default_timer()
print "elapsed time = ", end - start

結果はこの通り雲泥の差です。

elapsed time =  2.5530520247
elapsed time =  0.000329666753108

画像というデータ量の大きいメディアを扱う以上、C++を選んでおくのが速度面では無難かもしれません。

速度はC++の勝ち。

ドキュメントの豊富さ

Web上の情報はC++の方が若干多い気がします。stack overflowで"opencv C++"と"opencv python"のヒット数を比べたところ、13,170件と6,135件でC++の方が多くヒットしました。

ちなみに、WebでOpenCVの情報を検索しようとすると、両方の言語の検索結果が混じってヒットしてしまうので慣れるまでは大変です。さらに時代遅れであるOpenCV1.x系の情報も混じるので情勢はさらに悪くなります。どちらの言語を使うにしても、本を買うほうが上達は速いかもしれません。

ドキュメントの豊富さはC++がやや優位。

まとめ

C++Pythonのそれぞれに特徴があり、一意に優劣を定めることはできません。一応の指針を与えるならば、

  • プログラミング自体初めて→Python
  • 学習重視→Python
  • 性能重視→C++

となりそうな気がします。