はじめに
ちょっと前にRuby/OpenCVをいじってます宣言をしてからだいぶいろいろやったので、ここらで一旦まとめておきます。
進捗
テスト
ユニットテストの進捗は以下の通りです。CvMatクラスがツワモノすぎてなかなか終わりません。
進捗は、現在Ruby/OpenCVがラップしている関数の数をもとにした値です。OpenCVに実装されている関数はもっといっぱいあります。
さらに、表に書いていないクラスについてはまったく手をつけていません。つまり、まだまだ作業がいっぱい残ってるということです。
クラス/モジュール | 進捗 |
---|---|
CvMat | 半分くらい |
CvBox2D | だいたい完了 |
CvFont | だいたい完了 |
CvMat | だいたい完了 |
CvPoint | だいたい完了 |
CvPoint2D32f | だいたい完了 |
CvPoint3D32f | だいたい完了 |
CvRect | だいたい完了 |
CvScalar | だいたい完了 |
CvSize | だいたい完了 |
CvSize2D32f | だいたい完了 |
IplImage | だいたい完了 |
OpenCV | cvCvtColor系の機能がけっこう残ってる |
変更したもの
いろいろ変更しているので、抜けとかもあるかもです。
方針としては、なるべくOpenCVやRubyのお約束に従うようにと考えています。
- to_aryを持ってるクラスにはto_aも実装
最近はto_aryよりto_aを使うことのほうが多いと思うので、エイリアスとしてto_aも実装しました。
- CvVector削除
現在使われておらず、これからも使う予定がなさそうなので削除しました。必要になったら復活させるかも。
- CvMatの各ピクセルへアクセスする際の座標の指定方法
CvMatの各ピクセルにアクセスする際、mat[(x座標), (y座標)]の順だったのを、OpenCVのお約束に従いmat[(y座標), (x座標)]に変更しました。互換性を考えるとアレなのですが、これまでのバージョンでも引数を4つ以上与えると順番が逆になっていたので、まぁいいかなと。
- CvSeqで帰ってくるメソッドをArrayで返すように変更
CvMat#copyとかです。現在のところCvSeqを使うメリットが見当たらなかったので、素直にArrayで返すようにしました。もしかしたら直すかもしれません。
- CvMatにcvMatMulを実装してCvMat#*をそっちに割り当て
以前はcvMulに割り当てられていたのですが、一般的に行列の乗算と言ったらcvMatMulのほうだと思うので。
- CvMat#flipで引数を渡さないときの挙動を変更
引数が無い場合、以前はx方向、y方向の両方の軸について反転していましたが、OpenCVに合わせてy方向の反転をするようにしました。
それに伴い、両方の軸について反転するときはシンボル:xyを渡すように変更しています。
- CvMatの==, >, >=, <, <=, !=は削除
これらはcvCmp, cvCmpSに割り当てられており、必ずnilではないCvMatのインスタンスが返ってきます。
そのため、
if mat1 > mat2 # hogehoge... end
とかやったときに条件式が必ず真になってしまい、紛らわしいので削除しました。行列の比較系メソッド(CvMat#gtとか)はまた見直すかもしれません。
要検討項目
- CvMatで画素値を簡単に変更できない
現在、CvMatのあるピクセルの値を変更するには、
mat = CvMat.new(128, 128, :cv8u) mat[0, 0] = CvScalar.new(0, 0, 255) # matの(0, 0)をR=255, G=0, B=0にしたい
のようにいちいちCvScalarクラスのインスタンスを作成しなければならず、「ちょっとRの値だけ変えたい」みたいなことが簡単にできません。これはCvMat#[]で値を返すときにCvScalarのインスタンスを新たに作ってしまっているのが原因なのですが、現状では良い解決策が思いつかないので、そのままになっています。
- テストランナーで実行したときと単体でユニットテストを実行した時で結果がちょっと変わるメソッドがある
要はバグです。ぼちぼち直します。
- エラーハンドリング
現在はOpenCVの投げる例外をキャッチしていないので、OpenCV側で例外が投げられると、その場でプログラムが落ちてしまいます。
なんとかしなければとは思うものの、各メソッドをtry-catchで囲むくらいしか対策が思いつかないので、保留になっています。
なんかいい方法ないかなー。
デモ
せっかくなので、現状でちゃんと動いてるっぽい機能のデモなどを。
Webカメラでキャプチャした映像からcvGoodFeaturesToTrackで特徴点を取得するサンプルです。
Ruby 1.9.2+OpenCV 2.2+Ubuntu 10.10でやっています。
require "opencv" include OpenCV # ウィンドウを作成 window = GUI::Window.new("Good features to track") # キャプチャ開始 capture = CvCapture.open # 何かキーが押されるまで while GUI::wait_key(10).nil? # カメラからフレーム取ってきて img = capture.query # グレイスケールに変換した画像からcvGoodFeaturesToTrackで特徴点を取得 corners = img.BGR2GRAY.good_features_to_track(0.2, 5, :use_harris => true) # 特徴点を赤丸で囲んで corners.each { |point| img.circle!(point, 5, :thickness => 2, :color => CvColor::Red, :line_type => :aa) } # 表示 window.show img end # 最後にウィンドウを破棄 window.destroy
まとめ
そんなわけで、Ruby/OpenCVの現状をまとめてみました。
ser1zw/ruby-opencv - GitHub
https://github.com/ser1zw/ruby-opencv