「Jitterで動体検知して遊ぶ」を高速化してもらいました!その1
前回の「Jitterで動体検知して遊ぶ」で、いつも参考にさせてもらっているhttp://adsr.jp/のmasato221さんからコメントをいただき、なんと高速処理版を作ってくれました!
しかも2種類。いやーほんとありがたいです。うれしいです。助かります。
データは直リンクOKということでしたので遠慮なくリンクしてみます。
http://adsr.jp/patches/rx8.zip
masato221さんとはうちの同僚&元同僚がaircordのサイト制作で関わったとか。
なんか機会があればよろしくお願いします。。
というわけで今回は作っていただいたパッチの1つめを見てみます。
●映像入力
右上のエリアで動画を読み込みます。
読み込んだ動画は「color」という名前をつけたMatrixに入れておきます。
これを後で使います。
●動体検知
真ん中のエリアです。
1)jit.dx.grab 20 15 @unique 1
「@unique 1」というのが追加されました。
ドキュメントを見ると「デジタイザから新しいフレームを受信しなかった場合は bang には応答しません。」と書いてあります。
WEBカメラのフレームレートって低いので、前回のbangのタイミングとフレームが変わってなかったら何もしないってことですかね。処理が軽減されますね。
2)jit.rgb2luma
1プレーンのグレースケールのMatrixに変換します。
動いた部分を調べるだけならグレースケールの1プレーンだけでOKですね。
さらに処理が軽減されますね。
3)jit.dimmap @map 0 1 @invert 1 0
Matrixを(映像を)反転します。鏡っぽくするので。
4)t l l → jit.op @op absdiff
ここがよく分からず。。
2つのMatrixの違う部分を調べてるのは分かるけども、1つ前の「t l l」で違うMatrixを出力できてるということだろうか?
今のフレームと1つ前のフレームを比べることで動いてる部分を調べることができるはずだけどこれだと同じフレームが渡されてる感じがしてしまう。
うーん、もしかすると、両方のインレットにMatrixが送られてくるのはほぼ同時だけど厳密には同時ではないから1つめのインレットにMatrixがきた時点では2つめのインレットに入ってるMatrixは1つ前のだから大丈夫ってことかな。
そういうことにしておこう。
5)jit.expr @inputs 3 @expr \"snorm[0]*in[1]*1.33\" \"snorm[1]*-1*in[1]\" \"(in[2]/100)+in[0]\"
exprはあんまり理解してなかったけど、今回理解が深まりました。
・in[0]の数値はインレットの番号っぽい。
なのでin[1]は2つめのインレットに入ってくる値。
・cell[0]はMatrixのX座標。1,2,3,4,5,・・・
・cell[1]はMatrixのY座標。1,2,3,4,5,・・・
・norm[0]はMatrixのX座標を0~1の範囲で正規化したもの。ex)0.0,0.1,・・・,0.9,1.0
・norm[1]はMatrixのY座標を0~1の範囲で正規化したもの。ex)0.0,0.1,・・・,0.9,1.0
・snorm[0]はMatrixのX座標を-1~1の範囲で正規化したもの。ex)-1.0,-0.9,-0.8,・・・,-0.1,0.0,0.1,・・・,0.9,1.0
・snorm[0]はMatrixのY座標を-1~1の範囲で正規化したもの。ex)-1.0,-0.9,-0.8,・・・,-0.1,0.0,0.1,・・・,0.9,1.0
norm、snormの意味が今まで分からなかったけどやっと分かった。これは便利だ。
「@inputs 3」としてインレット数を3つに変更。
2つめので●の並ぶ間隔、3つめので●の大きさを調整できるようになってます。
ここでできたMatrixはプレーン数が3つで、X値、Y値、サイズとなってます。
6)jit.iter
Matrixを1セルずつ出力していきます。
1つめのアウトレットではさっきのMatrixのX値、Y値、サイズがリストで出力されます。
「zl slice 2」でそのリストの最初の2つを1つめのアウトレットに出力。
「prepend position」で「position」とくっつけて「position X Y」というメッセージにする。
「zl slice 2」の2つめのアウトレットは残り(この場合はサイズ)が出力されます。
それを「prepend scale」で「scale」とくっつけてメッセージにします。
jit.iterの2つめのアウトレットでは今出力しているセルの座標がリストで出力されます。
その座標を使って「getcell X Y」のメッセージを作ります。
これを最初に作った「color」という名前の映像のMatrixに送ることで、その座標の色を取得できます。
getcellメッセージの出力結果は「jit.matrix color」の2つめのインレットから出力されます。
メッセージ内容は「cell X Y val A R G B」となってます。
必要なのは後半の「R G B」の部分だけなので「zl slice 5」として「cell X Y val A」と「R G B」に分けます。
「R G B」が2つめのインレットから出力されます。
それを「prepend color」としてcolorのメッセージにします。
また、同時に「if $f1+$f2+$f3 > 0. then 1 else 0」で色を調べて、黒だったら●を表示しないようにします。
これは「gate」に黒だったら0、黒じゃなければ1を送ることでbangメッセージが最後の「jit.gl.gridshape」に行かないように制御しています。
7)jit.gl.gridshape sample @shape circle @depth_enable 1 @automatic 0 @blend_enable 1 @blend_mode 3 1 @dim 10 10
●を表示します。
処理もすっきりしたし、処理速度も速くなりました。
前は20x15でもけっこうCPU負荷が高かったけど、これだと48x36でも大丈夫です。
左上のとこで変更できます。
いろいろと勉強になりました。
なんかレベルアップした気がする。。
では次はもう1つのjit.gl.multipleを使ったバージョンを見てみます。こっちはさらに速くなっております。
でもmultipleはまだ理解できてなくて・・・これを機に理解できるようにしよう。
また一通り解読したらブログに書きますので。
| 固定リンク
この記事へのコメントは終了しました。
コメント
改めて言葉にしてもらったのを読むとこちらも理解が深まりますね〜。
ありがとうございます。
>>4)t l l → jit.op @op absdiff
ここ、Max特有のright to leftの考えかたなんです。
t(trigger)オブジェクトで順番を変えているので、ほぼ同時ではありますが順番だけはきっちりと左・右の順に送っています。
jit.opを始め多くのオブジェクトは左インレットに信号を受けたときにしか処理を開始しないので、処理後に格納される右インレットのものは次のフレームが来るまで保持され、ちゃんとフレーム差分が取り出せる、という仕組みですね。
なるほど、そういうつながりでしたか!
SDLXで多分すれ違ってますが、機会がありました際にはよろしくですー。
投稿: masato221 | 2009年7月 9日 (木) 17時54分
なるほどー。処理の順番はまだ理解できてないな。。
そのへんがちゃんとイメージできるようになれば。。
スーパーデラックスは何度か行ったことあるんでもしかしたら見かけてるかもしれませんね。今度もし見つけたら声かけさせてもらいますね。
投稿: primevision | 2009年7月 9日 (木) 21時45分