Home - wagavulin/opencvr GitHub Wiki

ビルドと動作確認

対応環境

今のところ開発・テストはUbuntu-22.04とMac。

  • OpenCV: 以下3つのうちいずれかの方法でインストール
    • Ubuntu: sudo apt install libopencv-dev
    • Mac: brew install opencv。これを書いている時点では4.7.0_2
    • ソースコードからビルドしたもの: CMakeオプション-DOPENCV_GENERATE_PKGCONFIG=YESを指定したもの
  • Python: 3.11以上
    • バインディングコードの生成ツールがPythonのため必要
  • Ruby: 3系。rbenv install 3.1.3
  • Numo::NArray: gem install numo-narray
  • C++コンパイラ: g++ clang++など
  • Make: sudo apt install make

gem

まだgemになっていないので以下手順でビルドする。

ビルド

OpenCVをaptまたはhomebrewで入れた場合は以下。

$ make -C dummycv  # dummycv/libdummycv.soを生成
$ mv dummycv/libdummycv.so .  # <- このコマンドはMacのみ必要。Ubuntuでは不要。
$ ./dev-tools/gen-headers-txt.rb > headers.txt
$ ./gen2rb.py      # autogen/以下にファイルを生成
$ ruby extconf.rb  # Makefileを生成
$ make             # cv2.soを生成

ローカルビルドしたものを使う場合は環境変数PKG_CONFIG_PATHを設定した上で上記コマンドを実行する。例えば/path/to/opencv4以下にインストールした(つまり-DCMAKE_INSTALL_PREFIX=/path/to/opencv4を指定した)のであれば export PKG_CONFIG_PATH=/path/to/opencv4/lib/pkgconfigを実行する。

サンプル実行

$ ./samples/tiny.rb

実行するとout.jpgが生成され、横600縦400ピクセルで黒背景に水色で"Hello OpenCV Ruby"と書かれているはず。

テスト

$ ./test/bind-test1.rb

使い方

パス設定

numo/narraycv2をrequireする。numo/narrayは上記のようにgemでインストールしてあればパス設定は必要ないはず。cv2はパスを指定する必要がある。例えば実行するrubyファイルがcv2.soと同じディレクトリにあるなら$:.unshift(__dir__)とする。

バインディング規則

Python版とだいたい同じ。

// C++
cv::Mat img = cv::imread("input.jpg", cv::IMREAD_COLOR);
# Python
img = cv2.imead("input.jpg", cv2.IMREAD_COLOR)
# Ruby
img = CV2::imread("input.jpg", CV2::IMREAD_COLOR)
  • クラス・メソッド・モジュール名
    • クラス・メソッド名はC++, Pythonと同じ。
    • トップのモジュールはCV2、それ以外は1文字目を大文字にしたもの。
      • 例えばC++のcv.xphoto.oilPainting()はRubyではCV2::Xphoto::oilPainting()
  • 引数・戻り値
    • C++でオプショナルになっている引数はRubyでも省略可能。
    • オプショナルの引数はキーワード引数も使用可能。キーワードはC++の仮引数と同じ。
    • 必須引数はキーワードにはできない。
    • 引数が出力に使われる場合(引数が非const参照など)、結果は戻り値として返る。
  • 特別対応のクラス
    • cv::MatはNumo::NArrayになる。Python版においてnumpy.ndarrayが使われているのと同様。
    • cv::Size, cv::Point, cv::RectなどはArrayになる。
      • 例えばcv::Sizeは数値2つを持つArraycv::Rectは数値4つを持つArray

OpenCVのAPIは公式サイトを参照。Ruby版はPython版とほぼ同じ。例えば以下のcv::clipLine()は、C++では3つの引数imgSize, pt1, pt2を受け取りboolを返すが、pt1, pt2は非const参照で出力にも使われる。そのためPython/Rubyでは戻り値が3つになる。

api-sample1

対応機能

バインディング可能なクラス、メソッドはC++のヘッダファイルにCV_WRAPCV_EXPORTS_Wなどのキーワードで指定されており、それを使っている(Python版と同様)。

使用するヘッダ

/usr/include/opencv4以下には多くのヘッダがあるが、ビルドオプションによって有効になっていない機能もあるため、すべてを使えるわけではない。C++では/usr/include/opencv4/opencv2/opencv.hppをインクルードすると、その環境でサポートされているヘッダが読み込まれるようになっている。gen-headers-txt.rbはこれを利用し、#include <opencv2/opencv.hpp>とだけ書かれたC++ファイルを-Mオプションをつけてg++を実行し(-Mはそのファイルからインクルードされたファイルを表示し、コンパイルはしない)、その結果を整形している。

未対応ヘッダ

CUDA関連は未対応のためヘッダパス中にcudaが含まれているものは除外している。

対応状況

以下は未対応

  • 公開メンバ変数
  • CUDA関連機能
  • いくつかのクラス

メソッドが対応しているかどうかはgen2rb.py実行時に出力されるautogen/log-support-status.csvにある。 なお、ここでの判定はあくまで引数・戻り値の型が対応可能でバインディングコードを生成していることを意味しているだけで、実際にどうさせて確認しているわけではない。

また、OpenCV-4.7.0での対応状況はWikiに記載している。

やりたいこと

  • gemを作る
    • OpenCV本体とバインディング部のcv2.soのバイナリをどうするかが悩みどころ。gemに含めるかその場でビルドするか。OpenCV本体のビルドはさすがに難しいが、cv.soはどうするか。インストール時にビルドすると、その環境にあるOpenCVに応じたcv2.soができる。ただしOpenCVのヘッダが必要なので、UbuntuであればOpenCVのdevパッケージがインストールされている必要がある。
  • vscode上での補完
    • vscodeでCV2::と書いたあとにメソッドが補完できるようにしたいが、どうすればいいのか未調査。