HMV に行ったら試聴出来た。一曲目、いいなぁ。東京は夜の七時は karly のも悪くないな。買おうかと思ったけど、やっぱお金ないっス。
三月末には、小西康陽コンパイルの渋谷系コンピも出るらしいし。
今月の目標に 「USB デバイスを作って遊ぶ」 というのを掲げたわけですが、どんなことしたいのかと言えば、外部ディスプレイになんか表示したり、HID デバイスから PC を操ってみたりと、まぁ他愛もないことなわけです。もちろん USB デバイスのハードウェアもソフトウェアも作ったことないわけで、なにから手をつけようかなという状態です。
でもよく考えてみたら、後者の場合ならハードは既存の製品でことたりるんじゃないかということに気が付きました。実はプレステのコントローラをばらすか、アルプス電気から ジョイスティックのコンポーネント部品 (alps.co.jp) を買おうかと思ってたわけです。んで、今日 HARD OFF に行ってみたら、ジャンクコーナーに USB 接続のプレステコントローラモドキ (elecom.co.jp) が 630 円で売りに出てるではないですか。
さてソフトの方はどうしようかと、ここで Visual Studio×DirectX はないし、まさかの HID デバイス直叩きもツライなと思いつつ、ふと頭に浮かんだのが前からちょっと気になってた Ruby/SDL (kmc.gr.jp)。早速ダウンロードしてドキュメントを見てみると、ありました、ピッタリなクラス SDL::Joystick が。joy.rb という、これまたツボをついたサンプルまで付いてて素晴らしい。もちろんアナログスティック対応!
Ruby/SDL の練習も兼ねて、ラインアート的なものを軽くつくってみました。左右のアナログジョイスティックで、ベジェ曲線の両端をグリグリと動かせます。いやはやこれは楽ちんだ。

ソース: joy2b.rb ※ かなりテキトーです! (2006.02.04 17:10 動かないファイルをアップしてたので修正)
Ruby 上でも高速な 2D 描画が売りの Ruby/SDL ですが、SDL::Surface の API (kmc.gr.jp) を眺めていると、アルファブレンディングはサポートされているものの、加算・乗算などの画像合成は用意されていないことに気が付きました。まぁ昨今の華美な加算・乗算合成エフェクトは食傷気味でもありますが、アルファブレンディングの表現力には物足りなさというか古臭さを感じてしまいます。昔読んだコラムには、アルファブレンディングは重いよって書いてあったしね。いまはどうなんだろう。
API がなければスクリプト書けばいいじゃない。ということでちょっと実験してみました。こんなときこそ Ruby の身軽さです。SDI::Surface からピクセルデータを取得する pixels メソッドと、ピクセルデータから SDL::Surface のインスタンスを生成する new_from メソッドがあるから、自分で計算すればなんとかなるかなぁと甘い考えをしていたわけです。元画像には Ruby/SDL の sample フォルダに入ってた ruby っぽい画像 (icon.bmp) にちょい手を加えたのと、コマンドプロンプトを切り抜いた画像を使いました。

書いてみたソースはこんな感じ。ピクセルごとにゴリゴリ計算。スマートな方法をご存知の方、教えてください。
#Multiple blending for Ruby/SDL
def multi(dest, src)
result = Array.new()
(0...dest.pixels.size-1).each do |i|
result << ((dest.pixels[i]*src.pixels[i]) >> 8)
end
return result.pack("c*")
end
img1 = SDL::Surface.loadBMP("icon.bmp")
img2 = SDL::Surface.loadBMP("icon2.bmp")
image = SDL::Surface.new_from(multi(img1, img2), 32, 32, 32, 128, 0, 0, 0, 0)
image.setColorKey(SDL::SRCCOLORKEY, 1)
$image = image.displayFormat
SDL.blitSurface($image, 0, 0, 32, 32, screen, x, y)
いろいろと紆余曲折がありまして、途中かなりの泥沼にはまったのですが、まぁなんとか Photoshop の乗算合成と全く同じ合成効果が得られました!

落とし穴については、後日書くことにします。上述の処理は、同じサイズの同じ色深度の BMP ファイルで動作します。色深度の穴は深くて冷たかった。
こうなると加算だろうが減算だろうがどんとこい。下は加算合成の例。

がしかし、リアルタイムで合成するのはツライのかな? まー今日のところは結果 ok。
※ new_from メソッドの (R|G|B|A)mask って何を渡せばよいのでしょう? 0x000000ff とか投げてみたけど、よくわかんない。結局 0 に落ち着いた。
昨日の買い物は、sixamo さんの お誕生日イベントのため。アイテムとストーリー作りから撮影、編曲に編集まで、一日でやるのはちと無理があったのでは・・・。
必然的に夜の絵しか撮れないという制約つき。真ん中くらいの昼の絵だけ、昔撮ったやつです。その次のカットの絵はさっき撮ってきた。
新しく買ったビデオ編集ソフトも、マニュアル読む間もなくゴリゴリ押し進んでなんとか仕上げました。なので、最初は Avid Free DV の方がいいかなぁと思ったけど、慣れてくると Vegas Movie Studio もいいですね。ってぶっちゃけ、どのソフトでもいけそうな気がしてきた。
DVD の初回特典についてるような絵コンテも書いてみたかったけど、そんな時間なかった・・・。まぁセルフハメ撮りだしいいか。
作品中にクレジットされてる人は、謝辞の通りです。それっぽく表記してみたかっただけで、他意はありません。読者ならびにコメントスパム隊の皆様には、深く感謝しております。
sixamo の生きる海 映画予告編 の制作を振り返るのエントリ。いかに低予算で好き勝手やるか。そこ重要。まず冒頭でたばこ・・・ではなくココアシガレットを取り出すシーン。

「たばこ=ちょいワルかっこいい」 とする風潮へのアンチテーゼであり、NANA たばこ脳へのサタイアである、わけもなく、ただ単にちょっと面白いかなと思ったから。収録後にスタッフでおいしく頂ける点も評価ポイント。
たばこを吸う人がよくやってる、手で箱をトントンと叩くとたばこがひょっこり出てくるのをやりたかったんだけど、ココアシガレット棒の長さが足りずにうまくいかなかった。
そこで箱に細工して、ゴムの力でココアシガレット棒が飛び出すようになってます。

力加減が難しくて、こんな NG シーンが撮れましたよ → NG テイク (MPEG-1 形式, 1.5 MB)
意味深な食器の絵柄について。

実はステッカーです。ELECOM の耐水光沢フィルム (elecom.co.jp) を使いました。耐水とは言え、長時間水気に曝しているとインクが溶け出してきますので、食用には使えないのが残念です。時間があれば cafepress で作ってみるのも一興だったかな。

Misty さんからお誘いのあった、 SDL 2007 新春 off (zinnia.dyndns.org) に参加することにした。
cyberstation で空席状況でも見ようかと思ったら、6:30-22:30 までなのね。
1200 過ぎに新宿到着。新宿御苑の池のほとりを 10 分くらいぷらぷらして、1230 ごろ四谷地域センターへ。会場に誰もいなくてこれはドッキリなんじゃないかと妄想する。うろうろしている間に到着した gony さんと fslasht さんに挙動不審ながらも挨拶して sdl-fan-jp と first contact。
みんなの発表をメモったものにちょいコメントを補足してアップしときます。『載せちゃ、らめぇ〜』 なネタや、『そこちょっと違う』 の際にはご一報を。お名前と内容が正しく対応してなかったらごめんなさい。
【kenmo さん】 画面出ず・・・。あとで。
【mst (Misty) さん】 夢のような A6 ノート!
【イ五さん】 「kadomatu」 デモ。だるまさんがころんだ風ゲーム。目の眼を盗んで門松でかくする。
【dan5 さん】 MyGame (Ruby/SDL の wrapper) の紹介。ぴちょんくんがドングリよけ。三重スクロール。画面綺麗。
【みかげさん】 D/SDL やる。
【U-16 さん】 絵描きさん ウホッ
【say さん】 Wii リモコンと自作センサバー持参するも、Bluetooth ドングル忘れちゃった。Wii リモコンのデモ、見たかったなぁ。さらに esでSDL!
【szkh さん】 Open dynamics engine の Python binding。弾丸撃ちまくり。すごい。Pong のデモも。
【おめがさん】 RectWinder 「イノベーション」 は GB 風味の猪アクションゲーム。
【D.K さん】 アクションゲーム。YGS2000 使用。やねうらおさんの SDK かな?
【るーと雨さん】 Gamehell を名乗る。「おもちげ」 アクションゲーム。
【phonondrive】 Ruby/SDL で作った KAOSS PAD もどきで REASON に MIDI データを送るデモ。
【かみむらさん】 百人一首タイピングソフト。和風な雰囲気が良かった。
【fslasht さん】 Proce55ing で塊魂式の落ちゲー。娘さん (もこちゃん)、かわいい。
【gony さん】 永遠の vaporware 「GSS」 敵をためてるとスコアアップする STG。Perfume キタ━(゜∀゜)━!!
【tekezo さん】 むちむち星人 「BulletGBA」 のデモ。「sshfs」 は視覚的なシェル、ってカッコイイ!
【ohai さん】 Ruby/SDL の中の人 STG デモ。dia でステージ/キャラクタ配置して、Python でエクスポートして、Ruby でスクリプト生成して、D 言語でコンパイル。
【shinh さん】 プロゴルファー!「(誤) code wars 2d → (正) core wars 2d」 はカルネージハードをイメージした Befunge なゲーム。とにかく凄い。
【kosaki さん】 静岡からの参加。
【中村 wo さん】 「nanika 2007」 Voice STG。声で自機が左右に動く。これはひどいと賞賛の嵐!大人気。
【isshiki さん】 operationg system not found! SDL ベンチマークな STG。「ヤルハラのオモチ」の gp2x 移植。「XII attack」は Ruby/SDL な STG。
【丼さん】 Gamehell2000 総帥
メガマック 食べるの速い U-16
あれやこれやとカオス。大人になるって大変だなー。そして don さん、鬼才。
曲のまとめページがあるけどないね、てな話になったので、ちょっと整備しました → phonondrive :: musical works
私がこれまでに作った曲が mp3 形式でダウンロード出来ます。
+ U-16 [オフお疲れ様でしたー。 これからもよろしゅうございます。 メガマックの意外な美味さにハマりそうです。 余計に太って..]
+ hon [あ、すいません。「imitation sky」のmp3へのリンクがつながってない感じです。]
+ ハジメ [>KAOSS PAD もどき に、すごい高まります。ぬおー。]
+ phonondrive [> U-16 さん こちらこそよろしくです。 マックはなんだかんだでクセになるね。 きっとなんか入ってる。]
+ phonondrive [> hon さん 全然気が付いてなかったです。ご指摘ありがとうございます。]
+ phonondrive [> ハジメさん いや、そんな大したもんじゃないですよー。]
2007.10.5 発売。DVD 9 枚組で 29,400 円。2007.3.1 予約開始の完全予約生産 → [ニュースソース (iza.ne.jp)]
ウゴウゴルーガを観るために朝早起きしていた私としてはちょっと欲しいかも。当時はかなりハマってた。放送時間が夜に移ってからツマンなくなって観なくなっちゃったんだけど、夜のは PIZZICATO FIVE とか出てたみたいで、今考えると惜しいことをしたなぁ。
そして実は OP/ED テーマ曲のシングル CD を持っていたりする。ジャケット裏の四コマ漫画がまた味があってね。「こどもなんだよ」 のイントロ SE を phs の着信音にしてた時期もありました。

Misty さんが、拙作の LUCINA (autumn strings style) をアレンジして下さいました → Lucina mist mix (rainer.blog7.fc2.com)
幻想的な音場を持った曲に仕上がってます。
意外なところで題意が連鎖して面白いなぁ。
特に借りたいものないし、閉店間際だったので適当に。
en:Code, Jazztronik | ヴォーカリスト, 徳永英明 | ヴォーカリスト 2, 徳永英明 | PURE BEST, ZOO | SINGLE BEST, EXILE
Jazztronik のは PATHWAYS [JAZZTRONIK THEME] (M1) が豪華で聴き応えあるし、ALL INSIDE (M2) は classical で ambiental な感じで良かった。LITTE TREE (M11) は葉加瀬太郎とのコラボなんだけど、Vn はあまり強く主張してこない感じでちょっと拍子抜け。TIGER EYES - CLUB VERSION - (M13) は、ドライブにもいいかも。
徳永英明はカバーもの。しかも 女性 Vo ものカバーしてる点がハスキーボイスと相まってなんともいい。原曲を Jazzy にリハーモナイズしてるところがちらほらあって、バックトラックを聴くのも面白い。
ZOO と EXILE は、先日雪山にいったら Choo Choo TRAIN なんて曲もあったね、という話になったので新旧聞き比べ。意外と BPM 遅いのね。てか EXILE のリーダーは元 ZOO なのか。中西圭三はガチ。
Camellia (sourceforge.net) というオープンソースの画像処理ライブラリを試してみました。
インストールは簡単で、> gem install camellia とやるだけです。あとは付属のサンプルスクリプトで 手持ちの画像を読み込むようにしてみると、あら簡単。

↓ 赤 (255, 0, 0) 輝度信号 (Y) と赤色成分の差 (V) を抽出

Camellia では DIB 形式でデータを持ってるので (正確には、DIB ですぐ吐ける)、SDL::Surface.new_from でそのまま SDL の Surface に乗りました。
image_sdl = SDL::Surface.new_from(image_camellia.get_pixels, height, width, depth, pitch, 0x0000ff, 0x00ff00, 0xff0000, 0)
※ (R|G|B)mask の使い方、やっとわかった。camellia では、RGB じゃなくて BGR でデータ持ってるみたいです。最初は色が変だった。OpenCV もこの形式だとドキュメントには書いてあったような・・・Computer Vision 界ではこっちの方が扱い易いのかしら。
※ pitch には width*3 を入れたらうまくいきました。この辺も全然わかってない。まぁ結果オーライで。

ちなみに認識した領域は、x, y, height, width でデータ持ってますので、SDL でカッコよくマーキングすることも出来そうです。
でも静止画だとつまんないからホントは webcam からの映像で遊びたいわけで、実は OpenCV (sourceforge.net) に目をつけていたのですが、Ruby/OpenCV (blueruby.mydns.jp) は最新版は cvs で拾って cygwin でコンパイルしてね、な感じで手が出ませんでした。そういえば extconf.rb ってのは cygwin 用なのでしょうか。mingw32/win32 で通ったためしがないです。
Linux だと v4l 用のライブラリがいくつか Rubyforge に登録されてましたが、Win32 用がないんですよね。Video for Windows やら Twain やら DirectShow の API を眺めては、Ruby/Win32API でなんとかならないものかと試してみましたが、そもそも Win32API の引数の扱い方をよく理解してなくて全然うまくいかない。Ruby にはポインタがないらしいんだけど。
一方、Python の VideoCapture (sourceforge.net) てのを見つけて、Python ともどもインスコしてみたら、これまた簡単に絵が出てきて嬉しいやら悲しいやら。あ、Ruby/Python (waseda.ac.jp) でなんとかなるかなと思ったら、Ruby 1.6×Python 1.5 用だった。しばらく格闘してみたけど、これまた全然うまくいかない。
Ruby/OpenCV のサンプルを見てみると、capture = CvCapture.open(0) でデバイス開いてるし。なんて楽しそうな環境なんだ〜。
あーでもない、こーでもないとやってるうちに一日がオワタ。
骨喰わば骨髄までと言うことで、ここまで来たら Cygwin (cygwin.com) をインストールしてみることに。あ、ネットワークから必要なものだけダウンロード出来るんだ。すごいな。とりあえずデフォルトでいろいろ入ってるんだろうと楽観してそのまま先に進む。
インストール後にさっそく ruby -v として Ruby inside で cygwin すごいじゃない! と思ったのも束の間、よく見たら [i386-mswin32] ってそっちかい。notepad と打ったらメモ帳起動するし。いままでに遊んだエミュレータは Basilisk II や QEMU なので、cygwin にもそのイメージがあったからちょっとビックリ。ファイルシステムもイメージじゃないんだね。
何度か setup.exe をクリックしては、ruby やら cvs やら make やらいろいろ入れる。
Ruby/OpenCV 開発室 (blueruby.mydns.jp) によると、まず ffcall (fsf.org) をインストールするとのことなんだけど、./configure が終わらない。延々とループしてるような気がしないでもないけど、そんなもの?・・・あ、5 分くらいしたら正常終了した。Makefile と config.h が出来たらしい。make、make install で /usr/local/lib や /usr/local/include にいろいろと出来る。
※ 『まぁ ffcall は option らしいので』 とか甘くみてるとあとあとトンでもないことになる (OpenCV::GUI まわりで compile error 出まくり)。当たり前だけど Ruby/ffcall じゃダメ。callback.h が必要。ソースに入ってる callback.h.in をリネームしてもダメっぽかった。
次、いよいよ Ruby/OpenCV。予め Windows 側で OpenCV (sourceforge.net) をインストールしておく。
※ OpenCV 1.0rc をインストールしないとダメ。最新版の 1.0 には一部 .h ファイルがはいってない!ここ落とし穴。
そして cvs で Ruby/OpenCV の最新版のソースコードをダウンロード。みんなが c・v・s! c・v・s! 言ってるのはこれか。最近は svn だっけ?
cvs -d :pserver:anonymous@rubyforge.org:/var/cvs/opencv checkout CVSROOT
でもって下準備スクリプトを実行。
./misc/setup.cygwin.sh
で、Windows (C:\Program Files\OpenCV) にインストールした OpenCV ファイルが /usr/local/bin やら /usr/local/lib やら /usr/local/include/opencv にコピーされる。
※ Ruby/OpenCV 開発室 で配布してる昔のバージョン (0.0.5) には misc フォルダがない、というか別モノなので注意。
ruby extconf.rb --with-opencv-include=/usr/local/include/opencv
--with-opencv〜 指定しないと ckeck require headers... で no 出て終わる。
make
make install
で /usr/lib/ruby/site_ruby/1.8/i386-cygwin に opencv.so 出来る。
さていよいよサンプルファイルを実行、といきたいところだが、cvs 版の sample フォルダはカラッポ。そして 0.0.5 版に含まれてるサンプルファイルは、なんと cvs 版の Ruby/OpenCV と API が非互換!!
う、ウゴカネぇ。
しょうがないので、一番基本的なとこだけ抑えてみる。
#!/usr/local/bin/ruby
$: << "../"
require "opencv"
include OpenCV
capture = CvCapture.open(-1)
window = GUI::Window.new("camshift demo")
frame = nil
while true
frame = capture.query
window.show(frame)
end
なんかグレーなウィンドウがポツンと出てきた。あれ、白くなって・・・うわー応答なしだ。webcam 側の LED はスクリプト開始とともに点灯するので、画面に表示されてないだけかな。SDL で横取りすれば ok?
あーやれば出来る子だと思ってたけど絶望した。生粋の窓っ子の自分に絶望した。続きはまた明日。
・・・と思ったけど、未練がましくリファレンス見ながらちょびちょびいじってみたら、絵、撮れたよ!

while ループの中に
frame.to_CvMat().save_image( "test.bmp" )
と書いたらなんか保存された。赤いのは webcam の LED のせいです。
でも
window.show(frame.to_CvMat())
はダメみたい。転送が追いついてないのかな。まぁよかろう。OpenCV::GUI がダメなら Ruby/SDL があるじゃない。
あーでも、この opencv.so は cygwin 用なんだよなぁ。でも一歩くらい前進した。
とあるシンポを聴講してきた。なんとか現状を打破しましょうとみんなで頑張りますよの会。
日向に落ちた影の話ばかりで、日陰の中の陰の話は出てこなかった。
綺麗な花を咲かせる話ばかりで、発芽の話は出てこなかった。
閉会後にパネラーの方を直接尋ねてみた。今日話題に上らなかった問題は、噂には聞いているが手が回らないそうだ。憂慮はしているようだけど、憂慮ならみんなしてるわけで、そこから一歩踏み出す話が聞けるのかと思ってたけど、みんな私なんかとは悩みの次元が違ったようだ。
でも本当はそんなことなくて、統計上の数字にしかならないんだろう。死人に口なし。資料には表れてたけど触れられなかった。経験のところでも一言あったけど、流された。「なくなった理由はわからない」 と。結局、会場と私の興味は異なってた。
トリアージタグの議論 (ja.wikipedia.org) が言い得ていて、「軽傷者の声は常に大きく、重傷者には訴える力は残されていない。時に多くを救うには、見込みのないものを諦めざる得ないこともある。」
自助努力。それは向こう岸の言葉で、競争と共栄のバランスは難しいけど、迷えるスイマーを水泡に帰す。個のポテンシャルを信じるなら、必要なのは手助けではなくキッカケだ。そんなときには 『両腕の届く範囲でベスト』 という、アップルシードに出てきたセリフを思い出すことにしている。
Ruby/OpenCV の cygwin 上でのコンパイルは成功したので、cygwin1.dll や cygruby18.dll 不要の opencv.so を作りたいのですが、なかなかうまくいきません。
Makefile 中のフラグに -mno-cygwin を設定してみたり、cygwin 用の mingw32 な Ruby をインストールしてみたりと、いろいろいじってなんとか cygwin 依存をなくそうとしましたが、一部の cygruby18.dll 依存が消えてくれません。

誰か Ruby/OpenCV を Win32 用にクロスコンパイルしてくれないかしら。
(続き)
買った。ストラップ付いてた。
「買い」 かと言われるとちと微妙。先行アナログから曲数が増えた印象なかったし、ジャケは素材集モノ (imagenavi.jp)だしね。でも Sugarless GiRL (M02) はいい。

やっぱり諦めきれずに Makefile を見直すも、これ以上 cygwin Ruby を呼んでるとこないだろうと途方にくれる。このままだと 「ちょっとクロスコンパイル言ってみたかっただけじゃないの」 とみんなの失笑を買ってしまう。ふと gcc に --verbose オプションつけるといろんなことがわかるよという言葉を思い出して、再度 make した結果を眺めていると・・・ぁゃιぃ。-lruby が、ぁゃιぃ。
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
RUBY_SO_NAME = ruby
となってて気が付かなかったヨ。ここを
LIBRUBYARG_SHARED = -lmsvcrt-ruby18
LIBRUBYARG_STATIC = -lmsvcrt-ruby18-static
と書き換えてやったら、cygwin free な opencv.so が出来た!もちろん mswin32 Ruby でちゃんと読み込めた。
ただこの opencv.so、ffcall がクロスコンパイルの足をひっぱると原因の切り分けが難しくなるので、とりあえず callback (OpenCV::GUI) まわりをひたすらコメントアウトしておいた不完全版。今度は完全版に挑戦しなきゃね。
でも OpenCV::GUI なくても Ruby/SDL に乗せればいいやと思って、ここで webcam からの画像を SDL で表示させようとして問題発生。Ruby/OpenCV には OpenCV の画像形式 (Intel Image Processing Library 形式: IplImage) から DIB 形式に変換する iplConvertToDIB 関数が実装されてないのでした。 (2007.2.22 訂正) iplConvertToDIB 関数は IPL (Intel Image Processing Library) ライブラリの関数であり、OpenCV ライブラリとは別のモノでした。
そいや、camellia のデータ構造 (CamImage) は IPL ベース (camellia.sourceforge.net) らしいなぁ。そこから攻めればうまくいくかな?CamImage も IplImage も構造体の中身というかメンバーは一緒なんだけど、さすがに = で代入は出来ないよな。なんか共通に扱えるような良い方法あるのかなぁ。
OpenCV だと webcam から得られるデータが IplImage 形式で、より汎用性のある DIB 形式に変換しないことには Ruby/SDL や Camellia で遊ぶこともままなりません。どうやら IplImage 構造体の imageData メンバに生データが入ってる (hawaii.aist-nara.ac.jp) っぽいのですが、Ruby から取り出す術がわかりません。「直接取り出すことは出来ない」 で FA なのかな・・・。
しょうがないので、Ruby/OpenCV のソースに手を入れて、ライブラリが IplImage 以外のデータ形式を返せないものかと試行錯誤してみました。素直に IplImage.imageData を返してみたり、バッファに memcpy でまるっと読み込んで返してみたり、Camellia のソースを見て CamImage.get_pixels をまねしてみたり、果ては CamImage オブジェクトを作って返してみたりと、いろいろやってみたのですが、無常にも Ruby は segmentation fault で落ちるばかりです。
んで、今日は諦めて google 相手に愚痴ってたら、衝撃の事実が! 戻り値は VALUE 型でなければならない (jcom.home.ne.jp)。ああ、痛すぎる。
VALUE 型の関数は return で rb_dbl2big とか rb_float_new とかおまじないしてて、これはきっと特別なケースなんだろうと思ってたんだけど、むしろそっちが本流なのね。
Ruby 拡張ライブラリの作成方法の習得を完全にスキップしてた。まぁ今日のところは、なんやかんやソースに手を入れても、なんとかコンパイルできることがわかっただけでも良しとしよう。
髪の毛が乾くまでの間ちょっくらコードでもいじってみようかと、先ほどの失敗を踏まえつつちょこと修正してみたら、サックリ絵が出たー。

なんか絵が逆さまだったり、途切れてたり、色が変だったり、10 回に 1 度くらいしかスクリプトが走らなかったりしますが、『あ・・・アハ・・・読める、読めるぞぉ。』 てなわけで、SDL 上に webcam からの絵が読めました。
webcam からの画像を取得 (grab and retrieve) する OpenCV::CvCapture.query をちょろっと改造しました。
(cvcapture.cpp)
VALUE
rb_query_cam(VALUE self)
{
IplImage *frame = cvQueryFrame(CVCAPTURE(self));
return rb_str_new2((char *)frame->imageData);
}
Ruby スクリプト
(camtest.rb)
require 'sdl'
require "opencv"
include OpenCV
SDL.init( SDL::INIT_VIDEO )
screen = SDL::setVideoMode(640,480,16,SDL::SWSURFACE)
SDL::WM::setCaption('SDL_app','camtest.rb icon')
capture = CvCapture.open(-1)
image = SDL::Surface.new_from(capture.query_cam, 320, 240, 24, 320*3, 0xff0000, 0x00ff00, 0x0000ff, 0)
image.setColorKey( SDL::SRCCOLORKEY ,1)
image = image.displayFormat
SDL.blitSurface(image, 0, 0, 240, 180, screen, 0, 0)
色が変なのは (R|G|B)mask の指定が BGR になってたからです。RGB で ok。他は・・・色深度とかデータ長とか整合性をとってないせいかも。あとはメモリリークしてる? いや、query に入れたのがまずかったのかな。
キャプチャ絵を DIB で取得するんじゃなくて、ひとまず IplImage で持ってきたのを IplImage.to_dbi みたいに使えた方が便利だな。OpenCV の画像認識も併用出来るしね。
まぁ細かいところはあとで詰めていくとして、とりあえず絵が出た。大変よろこばしい。
うーん、OpenCV でキャプチャた画像は 320x240x3 で 230 KB ほどあるはずなんだけど、imageData をそのまま抜いただけだと 120 KB しか取れてないな。そのせいで画像が乱れたり、segmentation fault するのかなぁ。
あ、上下逆なのはカメラを逆に置いてたっぽいです。

(2007.2.24 追記) 試しにデータサイズを返すようにしてみた。
VALUE
rb_query_raw(VALUE self)
{
IplImage *frame = cvQueryFrame(CVCAPTURE(self));
return INT2FIX(frame->imageSize);
// return rb_str_new2((char *)frame->imageData);
}
230400 (= 320 * 240 * 3) が返って来たので、imageData の中身はやはり 230 KB あるようだ。とすると残りの 100 KB はどこに消えた?ちなみに得られた 120 KB のデータを Photoshop で RAW 形式として読み込むと、上の画像と同じ絵が得られた。
return rb_str_new2() で何かがおこってるのか。segmentation fault するってことはメモリの読み書きがマズイってことなのかな。
一週間前にふとはじめた 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
そういえば先日の SDL オフの際に、Win32 版 Ruby/SDL の開発・保守を行う人を募集されてました。興味あるかたは是非! (私信) その節は、私のどうしようもない質問に丁寧に応対して下さいまして、ありがとうございました。
メンテナといえば、sixamo.rb の話 (d.hatena.ne.jp/saronpasu) の行方も気になる [via: kdoo (yowaken.dip.jp)]
長らくキッチンに置きっぱなしだった、使ってないデスク・キャビネット・カーペットを処分した。なんか素敵に開放感なんだけど、広くなったとは言え、スパゲティを茹でるくらいしかやることはないわけだが。
問題は居住空間の方で、クローゼットの中から古い資料が入ったダンボールを引っ張りだしてきて、これもそろそろ捨て時かなぁなんて悩みながら開けたら、まるっきり別のものが入ってて、そういえばあの時一緒に捨てたんだけっけ。怖い子だ。しかしもう三年も前の話なのか。
とりあえず友達に貸して返ってきたけどそのまま封印してた N64 と PS のつまったダンボールは後輩のとこに置いてきた。PS2 は別の後輩に貸した。このまま貸したことさえ忘れそうだ。久々にマリオカートやった。5 年以上ぶりとは言え、ミニターボとかショートカットとか体が覚えてるな。そして後輩君とか誰もついてこない。当時相当やりこんだからなぁ。でも捨て。
ハードウェア箱からは、Sound Blaster Live! の 5 in ベイコンソールとか、MS 謹製サイドワインダーとか、アップスキャンコンバータとか、56k モデムとかいろいろ出てきた。微妙に古い・・・。捨て。
あと本だな。Direct3D とか C++ Builder とか HTML とか FLASH の本もいらないな。捨て。
あと買った家電・楽器の箱を捨てずにとってあるんだけど、これも捨て。
それにしてもちっとも片付かないかな。物大杉!
作業中に棚から 2.5 in HDD が落ちてきて、左手の甲から微妙に出血。ボタモチマダー (AA 略
(ADSL) メタル回線代 2,000 円+プロバイダ代 3,500 円 → (光) B フレッツ回線代 3,000 円+プロバイダ代 1,500 円でいいんじゃないかと思い立ち、光に移行することにした。
マンションタイプで回線共有とは言え、線路損失 60 dB でリンクが 1.5 Mbps しか出てない ADSL よりはマシになるかなぁと思ったわけだけど、どうなることやら。
しかしここで問題発生。プロバイダの HP を見たら、『プラン変更は各月の一日付けで適用』 と書かれてる。えーなんだそれ。WILLCOM の即日プラン変更可能のノリでいたのが間違いだった。明日電話して確認してみよう。
ダメだったらどこかで新規契約しようかと思う。長年使ってたプロバイダを捨てるのは残念だけど、ネット難民になりかねないからなぁ。こんなことなら価格.com (kakaku.com) のキャンペーン使って申し込めばよかったかも。でも価格.com のページだと開通まで一〜二ヶ月とあるなぁ。今日電話した感じだと来週には開通する勢いだったのに・・・。
とりあえずルーターだけ買ってみたが、気が早すぎたようだ。
+ Misty [おぉ、ついに phonondrive さんも SDL の世界に!実は私も C++ で SDL | GL | AL な..]
+ phonondrive [お誘い頂きありがとうございます。しかし当方、一昨日インストールしたばかりの者ですが・・・。 先日曲を聴いたときに b..]
+ ohai [アルファブレンドはソフトウェアサーフェスを使っているなら普通に数倍遅くなるだけだと思いますが、ハードウェアサーフェス..]
+ phonondrive [コメントありがとうございます。SW と HW でもかなり変わってくるんですね。パフォーマンスが出ないようでしたら O..]