
1. 概要
この記事では,OpenCV C++版のPythonラッパー版である「OpenCVのPythonバインディング」の概要を,短めにまとめます.
2節で「バインディング」と名付けられたOpenCVの他言語ラッパー自動生成の仕組みについてまず述べたのち,3節では,C++版とPython版のインターフェースの違い&共通点を整理します.そして4節では「Pythonで使えるので,科学技術計算・機械学習でインタラクティブに使用できる」という利点をまとめます.
2. Python版バインディングの自動生成
OpenCV は,バインディング(綴じ)」という,他言語ラッパー関数の自動生成機能が組み込まれています.このバイディング機能により,標準のC++版の(各クラスの)関数群を,コンパイル時に自動的にラッパーして,同じ関数名.引数・返り値のインターフェースを持ったPyhon版の関数を自動生成することで,Python版が提供されています.
(自動生成であるがゆえに)C++版での関数と書きごごちが同じであるOpenCV-Python版が提供されていることが,理解しておきたいポイントです.ただし,言語をまたぐと(文法や仕組みが違うので)完全に同じものにはなりません.
次の3節では,C++版とPython版の違いを,おさえておきましょう.
3. 「C++版との違い」と「Python版の書き方例」
Coreモジュ-ルの記事でも書いているように,C++版は画像/行列・多次元配列を「cv::Matクラス」というMatrixクラスに格納します.そしてcv::Matクラスには,①「画素値のfor操作」などの画像データの直接操作が提供されている一方で,「②numpyのarrayクラスで行なうような行列・線形代数計算」も,このMatクラスを引数にとるようなCoreモジュ-ルの各関数で実施するように(C++版では)なっています.
それに対して,OpenCV-Pythonバインディングでは,画像データや行列は,(pythonなので)numpy arrayオブジェクトを使用する仕組みになっています (つまり,cv::Matクラスは,Pythonインターフェースでは登場しません).
3.1 C++版とPythonバインディング版の関数の比較
ここまでをまとめると,Pythonバンディングでは,cv::Matであったところが,numpy arrayに替わるだけで,(自動生成であるがゆえ)関数のインターフェース感はC++版と同じままPythonの各関数が使えるという事です.これを具体的に「imread関数 」により,その違い&共通点をみておきます.
例えば.画像を読むこみimread関数の場合,Python版では
filename = "input.png"
img = cv.imread(finename)
という感じで,numpyのarrayをimreadの返り値にもらいますが,元のC++版では,
#include <opencv2/opencv.hpp>
int main() {
cv::Mat img = cv::imread ("sample.jpg", cv::IMREAD_COLOR)
return 0;
}
というようなMatクラスで画像を受け取るコードを書きます.
imreadに限らず,C++で引数としてMatクラス(画像or行列データ)を使用している関数は,Python版ではnumpy arrayを引数に持つようになっています.
この仕組み・特性のおかげで,「OpenCV C++版のクラス・関数に,既に詳しい人」は,すぐPythonで各関数を馴染ある関数インターフェースのまま使えるし,「OpenCV-Python版に先になれていた人」も元のC++版や,他言語のOpenCVバインディングをつかう際にも楽に移行できる.
4. Pythonで使えるので「①インタラクティブに使える」&「②科学技術計算・機械学習に強い」
Python版では,IPythonやJupyterNotebookなどの「科学計算的なインタラクティブ環境」上で,C++版のようなコンパイル作業を経ずに,「インンタラクティブに使うことができる」のは大きな利点である.元のC++だとリアルタイム計算には強いものの,インタラクティブに使えるスクリプト言語ではないので,実験的に「ああでもない,こうでもない」と沢山試すことができません (C++でソフトウェアをつくると,プログラムが大きくなってくるほど,コンパイルに相当な時間が必要になっていくので).
みなさんもIPyhon上や Jupyter上で,OpenCV-Pythonをインタラクティブに使用していろんなを試すことができます.例えば,当サイトの用語Wiki記事の Cannyエッジ検出や,ハフ変換などの記事中の図の画像では,OpenCV-Python(もしくはscikit-image)を用いて作成してた.これらのコードは,管理人はJupyterNotebook上で,快適に作成したものです .私はOpenCVに慣れているので,ああだこうだせずスラスラとつくっていますが,それでも,Pythonでできると,部分実行して試すこともできるし,デバッグや修正も楽であり,便利です.
加えて,OpenCV-Pythonは,科学計算分野の人間からすると元のC++版と違い,PyTorchなどのPythonに直接組み込めるのも,非常に便利です.OpenCV-Pythonバインディングは,「2000年代 当時の科学技術計算全般でのPythonの人気上昇 (※)」から追加された流れもあり,結果的にその後,組み込み環境や,ラズベリーパイなどのエッジ計算モジュールにおいても,OpenCV-Pythonの使用が増えることとなりました.
※ 参考になるQ&A記事→ Pythonはなぜ,ディープラーニング・機械学習向けの人気言語になったのか?【Q and A 記事】
また,OpenCVだけで完結するアプリなら「本番環境がC++ でも,Python版で先に色々と実験的に試したり,Pythonで事前検証しておく」という「別言語(Pythonやjavascript版)での事前実験」も可能で,これも役に立つことがあるはずです().
参考記事
- OpenCV-Pythonの紐づけ(Bindings)がどのように動作するのか? (鳥取大のOpenCV3公式ドキュメントの日本語翻訳)