第2回 Ruby/OpenCV進捗報告
進捗
ロードマップ
だいたいこんな感じで進めようと考えています。気分によって順番が変わる可能性があるかも。
- OpenCV 2.2に対応 (完了)
- Ruby 1.9.xに対応 (完了)
- もともと実装されているメソッドのテスト ←いまここ
- 安定して使用するために必要な機能の追加
- 少なくともエラーハンドリングはしっかりしないと
- OpenCVの機能のうち、まだ実装されていないものを追加
- OpenCV 2.2のfeatures2dまわりは是非とも使えるようにしたいところ
- Windowsでも動くように対応
- ドキュメントの整備
テスト
ユニットテストの進捗は以下の通りです。もともと実装されていたメソッドのうち、約70%のテストが完了しています。
下記の表では「まだやってない」がかなり多いですが、主要な機能のほとんどはCvMatへ実装されているので、全体としてはそこそこ進んでる感じです。
クラス/モジュール | 進捗 |
---|---|
CvMat | 80%完了 |
OpenCV | cvCvtColor系の機能がけっこう残ってる |
CvSeq | だいたい完了 |
CvRect | だいたい完了 |
CvContour | だいたい完了 |
CvMoments | だいたい完了 |
CvPoint3d32f | だいたい完了 |
CvScalar | だいたい完了 |
CvPoint | だいたい完了 |
CvSize2d32f | だいたい完了 |
CvPoint2d32f | だいたい完了 |
CvSize | だいたい完了 |
CvChain | だいたい完了 |
CvCircle32f | だいたい完了 |
CvBox2d | だいたい完了 |
CvConnectedComp | だいたい完了 |
CvLine | だいたい完了 |
CvTwoPoints | だいたい完了 |
CvTermCriteria | だいたい完了 |
IplImage | だいたい完了 |
CvHumoments | だいたい完了 |
CvFont | だいたい完了 |
IplConvKernel | だいたい完了 |
Curve | まだやってない |
CvAvgComp | まだやってない |
CvCapture | まだやってない |
CvChainCode | まだやってない |
CvCondensation | まだやってない |
CvContourTree | まだやってない |
CvConvexityDefect | まだやってない |
CvError | まだやってない |
CvHaarClassifierCascade | まだやってない |
CvHistogram | まだやってない |
CvIndex | まだやってない |
CvMatND | まだやってない |
CvMemStorage | まだやってない |
CvSet | まだやってない |
CvSlice | まだやってない |
CvSparseMat | まだやってない |
CvVideoWriter | まだやってない |
GUI | まだやってない |
MouseEvent | まだやってない |
Point3dSet | まだやってない |
PointSet | まだやってない |
TrackBar | まだやってない |
Window | まだやってない |
デモ
OpenCV 2.2 documentationにあるハフ変換のサンプルをRuby/OpenCVを使って書いてみました。
環境はRuby 1.9.2+OpenCV 2.2+Ubuntu 10.10です。
require 'opencv' include OpenCV # 画像をロード mat0 = CvMat.load(ARGV[0], CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH) # グレースケールにして大津の二値化 mat, th = mat0.BGR2GRAY.threshold(0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU) # Cannyのエッジ検出 mat = mat.canny(50, 200) # 確率的ハフ変換で直線検出 seq = mat.hough_lines(CV_HOUGH_PROBABILISTIC, 1, Math::PI / 180, 50, 50, 10) # 検出した直線を描画 result = mat.GRAY2BGR seq.each { |points| result.line!(*points, :color => CvColor::Red, :thickness => 2, :line_type => :aa) } # ウィンドウを作成して表示 GUI::Window.new("src").show mat0 GUI::Window.new("dst").show result GUI::wait_key
まとめ
そんなわけで、Ruby/OpenCVの現状をまとめてみました。
リポジトリはこちら
ser1zw/ruby-opencv - GitHub
https://github.com/ser1zw/ruby-opencv
第1回 Ruby/OpenCV進捗報告
はじめに
ちょっと前に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
Ruby/OpenCVをいじり始めました
明けましておめでとうございます。笑ってはいけないやつを見てたら年が明けてました。
Ruby/OpenCVをいじっています
この前ご紹介したRuby/OpenCVをいじっています。というのもこのライブラリ、とりあえず動くと言えば動くものの、
という状態。気がついたらGitHubのフォークボタンを押しており、ゴリゴリコード書いておりました。
現状
現状では
という感じ。しばらくはテストとバグ修正がメインになりそうです。
リポジトリ
コードはGitHubに置いてあります。人柱上等な皆様は試してみてください。
ser1zw/ruby-opencv - GitHub
https://github.com/ser1zw/ruby-opencv
OpenCV 2.2用ブランチ
https://github.com/ser1zw/ruby-opencv/tree/OpenCV_2.2
OpenCV 2.1用ブランチ
https://github.com/ser1zw/ruby-opencv/tree/OpenCV_2.1
そんなわけで
本年もよろしくお願いいたします。