一週間前にふとはじめた Ruby で Computer Vision (CV) ですが、ついに Ruby/OpenCV (blueruby.mydns.jp)、Camellia (camellia.sourceforge.net)、Ruby/SDL (kmc.gr.jp) の合わせ技で、Windows 上の Ruby でリアルタイムに視覚情報を扱うことが出来るようになりました!
CV で Hello world! と言えば Laughing man しかないわけです。

といっても OpenCV の顔認識機能 (ってのがあるらしい) を使っているわけじゃないです。というか Ruby/OpenCV は OpenCV の視覚情報処理機能をラッピングしてない? そんなわけで Camellia で検出した領域の中で最も大きい領域に Laughing man を上書きしてるだけなので、こんな遊び (DivX 形式, 1.1 MB) も出来ます。

SDL surface に乗ってるので、こんなこと (DivX 形式, 1.5 MB) も簡単。
1. Ruby/OpenCV で webcam の画像をキャプチャ (webcam → IplImage)。mswin32 用に Ruby/OpenCV をクロスコンパイルした。 【関連記事: cygwin でコンパイル | mignw32-ruby 用にクロスコンパイル】
2. 得られた画像データを IplImage 形式から DIB (Device Independent Bitmap) 形式に変換する (IplImage → DIB)。Ruby/OpenCV に IplImage.to_dib メソッドを付け足した。 【関連記事: Ruby 拡張ライブラリ作成の失敗談 (1) | Ruby/OpenCV/SDL で webcam からの絵が出た !? | Ruby 拡張ライブラリ作成の失敗談 (2)】
3. Camellia で視覚情報処理する (DIB → CamImage)。DIB の読み込みは CamImage.set_pixels(IplImage.to_dib) で ok。 【関連記事: Ruby で画像認識】
4. 視覚情報処理したデータを Ruby/SDL を用いて Window に描画する (CamImage → SDL surface)。SDL::Surface.new_from(CamImage.get_pixels) で ok。 【関連記事: Ruby で画像認識】
クロスコンパイルも拡張ライブラリの作成も初めてだったのでかなり gdgd ですが、後続の人の一助になればいいなぁ。的確なコメントを下さった say さん、ありがとうございました。あと中を覗いてみて、各ライブラリの作成者に頭が上がらなくなりました。
Ruby やっぱすごい。おきらくスクリプティング!
(01_blob.rb)
require 'sdl'
require "opencv"
include OpenCV
require 'rubygems'
require_gem 'camellia'
include Camellia
# Initialize the SDL screen
SDL.init(SDL::INIT_VIDEO)
screen = SDL::setVideoMode(320, 240, 16, SDL::SWSURFACE)
SDL::WM::setCaption('SDL_app', 'SDL_app.rb icon')
# Open a camera device
capture = CvCapture.open(-1)
while true
while event = SDL::Event2.poll
case event
when SDL::Event2::KeyDown, SDL::Event2::Quit
exit
end
end
# Capture a frame
frame = capture.query
# Prepare a Camellia image (IplImage/CamImage structure)
img_camellia = CamImage.new(frame.width, frame.height, CAM_DEPTH_8U, CAM_COLORMODEL_RGB)
img_camellia.set_pixels(frame.to_dib)
# Convert an image from RGB to YUV format
yuv = img_camellia.to_yuv
# Set ROI (Region of Interest) and detect BLOBs (block of bits)
yuv.set_roi(CamROI.new(2, 0, 0, yuv.width, yuv.height))
blobs = yuv.encode_threshold(144).labeling!
blobs.each {|b| img_camellia.draw_rectangle(b.left, b.top, b.left + b.width - 1, b.top + b.height - 1, cam_rgb(0,0,255))}
# Convert an image from CamImage structure to SDL surface
img_sdl = SDL::Surface.new_from(img_camellia.get_pixels, img_camellia.width, img_camellia.height, img_camellia.depth * img_camellia.nChannels, img_camellia.width * img_camellia.nChannels, 0, 0, 0, 0)
img_sdl.setColorKey( SDL::SRCCOLORKEY ,1)
img_sdl = img_sdl.displayFormat
# Display an SDL surface image
SDL.blitSurface(img_sdl, 0, 0, img_camellia.width, img_camellia.height, screen, 0, 0)
screen.updateRect(0, 0, 0, 0)
end
いま使ってる opencv.so をアップしておきます。cygwin で mingw32-ruby 用にクロスコンパイルしました。OpenCV 1.0rc 内の各種 dll が必要です。ffcall と OpenCV::GUI まわりのファイルをコメントアウトしてビルトしたので、OpenCV::GUI はサポートしてません。修正した .h/.cpp ファイルも入ってます。
※ ちなみにしばらく使ってると VC++ runtime が落ちたり、Ruby が Malloc failed して死にます! どこか Release しなきゃいけないのかしら。(追記) どうも Camellia の labeling! メソッドでメモリリークしてるようです。コミットチャージがグングン上がっていきます。Ruby/OpenCV と Ruby/SDL は大丈夫。さてどうしたもんだろう。
※ 何故かたまに画像が上下反転します。なんでだろう。
あと他の環境で動くか試してません。でも動いたらいいなというか、みんなが興味持ってくれたらいいなというか、.oO(みんなが作ったもっといいものを私は使いたい)。
Binary:
ruby-opencv-cvs-phonondrive-070225.zip (7 KB)
Sample code:
00_capture.rb (camellia いらない)
01_blob.rb
お、おぉぉぉ…リアル笑い男が!
多分 Augmented Reality か Mixed Reality の部類に入るんですよねコレ。ぬぉぉ面白そう。まさかこんなことをやってくれようとは…ッ!
なんだか動画を見ていたら ARToolkit (ttp://www.hitl.washington.edu/artoolkit/) で遊びたくなってきました。っとその前に Webcam を調達せねば。ぐはぁ。
そう、その AR ってのをやってみたいんです。なんか面白そうなんで。
webcam は PS2 の EyeToy 使ってます。中古だけど TSUTAYA で 1,000 円でした。
おお、まさか昔自分が書いたRuby/OpenCVを使っている人がいようとは…
公開しておいて放置しているので申し訳ないのですが…
既に1.0も出ているし、また手をつけてみようかなぁ
いろいろ新機能も追加されているみたいだし
やや、開発者の lsxi さん ?! Ruby/OpenCV では、大変楽しく遊ばせて頂いております。
開発再開とは願ってもないお言葉です。お時間がありましたら是非ともよろしくお願いいたします。