第2回 Ruby/OpenCV進捗報告

はじめに

第1回からだいぶ間が開きましたが、ここらで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


結果はこんな感じ。それっぽく直線が検出できています。
f:id:ser1zw:20110321014249p:image

まとめ

そんなわけで、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

こんな感じで特徴点を取得し、描画します。
f:id:ser1zw:20110116223549p:image

まとめ

そんなわけで、Ruby/OpenCVの現状をまとめてみました。


ser1zw/ruby-opencv - GitHub
https://github.com/ser1zw/ruby-opencv

Ruby/OpenCVをいじり始めました

明けましておめでとうございます。笑ってはいけないやつを見てたら年が明けてました。

Ruby/OpenCVをいじっています

この前ご紹介したRuby/OpenCVをいじっています。というのもこのライブラリ、とりあえず動くと言えば動くものの、

  • 最新版のOpenCV(OpenCV 2.2)には未対応
  • Ruby1.9.xに対応してるのもあったけど、うまく動かないっぽい
  • バグいっぱい
    • ずっと放置されてたこれとか
  • テストが無い

という状態。気がついたらGitHubのフォークボタンを押しており、ゴリゴリコード書いておりました。

目標

  • OpenCV 2.2対応
  • Ruby 1.8.7, 1.9.xの両方に対応
  • 機能の追加
  • テストの整備
  • ドキュメントの整備

あたりをやっていきたいと思っています。

現状

現状では

  • とりあえずOpenCV 2.2でも動く
  • とりあえずRuby 1.8.7, 1.9.2で動く(Ubuntu 10.10で確認)
  • テストは30%くらい完了
  • バグいっぱい

という感じ。しばらくはテストとバグ修正がメインになりそうです。

リポジトリ

コードは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

そんなわけで

本年もよろしくお願いいたします。