« 2009年6月 | トップページ | 2009年9月 »

2009年7月15日 (水)

MAX/MSP+Jitter 指定したフォルダの映像ファイルをランダム再生

ローカルのフォルダに映像ファイルを入れておけば、それをランダムで再生できる仕組みを作ってみました。
相変わらず非効率な処理っぽいけどこれは動けば問題ないかと思う。。


rondom_movie


1.黄色のボタンクリック
映像ファイルがあるフォルダを指定します。

●フォルダの指定
フォルダを指定するには「opendialog fold」オブジェクトにbangを送ってあげればダイアログが開きます。
「fold」がついてないとファイル選択になります。
選択後、フォルダのパスを送ります。
送り先は「folder」オブジェクトと真ん中あたりのpack、右上の確認用のメッセージです。

●映像ファイルリストの取得
「folder」オブジェクトを使います。
さっきの「フォルダの指定」で、このfolderオブジェクトにフォルダのパスが送られてきてます。
これにbangを送るとそのフォルダのファイルリストが取得できます。
映像ファイルのみ取得したいので、最初に「types MooV」というメッセージを送っておきます。
(「MooV」はmovファイルだけかな??)
取得したリストはumenuに送ります。

1.赤のボタンクリック
ムービーのランダム再生を始めます。
その前の設定も同時にやってます。処理順的にこれでいいのか分からないけど一応動いてます。

●ファイル数の取得
umenuに「count」メッセージを送るとリスト数が取得できます。
出力は「count 4」みたいになるのでzl slice 1で分けて数値だけ取得します。
この数値をrandomの範囲に設定します。

●ランダム
umenuに設定されているファイル名の中からランダムで1つ選ぶために「random」を使います。
「random」の右のインレットはrange(範囲)で、0からこの範囲内でランダムな数値を出力します。
出力された数値はumenuへ送られます。
umenuは数値が送られてくると、それに対応する番号の項目を出力します。

●パス+ファイル名
umenuの2つめのアウトレットからファイル名が出力されてきます。
これと、最初に選択したフォルダのパスをつなげます。
ここはいいやり方が分からなかったけど、以下のような考え方でなんとかやりました。

・「tosymbol」はリストの中身を連結させて文字列にする。何も指定しなければ単にスペースが消される感じ。
・そのために「パス ファイル名」というリストを作る。
・packを使ってリストを作る。
・「パス ファイル名」とするにはpackの1つめのインレットにパス、2つめにファイル名を入れたい。
・でもパスは基本的に入ってくるのは最初だけで、ファイル名がどんどん変わってく。
・packは1つめのインレットが変更された場合に出力される。
・pakにすれば2つめのインレットに値が入ってきたときも出力されるが、パスが送られてきた時は出力したくない。
・なのでやっぱりpackで、最初は「ファイル名 パス」というリストにする。
・その後に「zl rev」で反転し、「パス ファイル名」というリストにする。

「prepend read」で「read パス+ファイル名」というメッセージを作って送ります。

●映像切り替え
「jit.qt.movie」はさっきのreadメッセージを受け取ることで、映像を再生します。
普通にやると永遠とループ再生されてしまうので、再生が1回終わったら次の映像を再生するようにします。

「jit.qt.movie」のアトリビュートでループ関連のものがあるので設定します。
@loopはループするかどうか、ループする場合の方法を設定できます。
@loopreportはループ通知フラグ。再生がループ ポイントを通過するときに「loopnotify」メッセージが送信されます
@loopreportは「1」にしておけばよさそうです。
@loopは1回再生でいいから0でいいのかなと思うんだけど、0にすると1回目しか「loopnotify」メッセージが送信されませんでした。
ここはデフォルトの「1」でいいみたいです。(なので書く必要はない)

「loopnotify」メッセージは右のアウトレットから出力されます。
「select loopnotify」で、送られてきたメッセージが「loopnotify」の場合にbangを出力させます。
そのbangは左上のrandomのとこに渡り、再度ランダムでファイルを指定することで再生されます。
「●ランダム」のところからここまでを繰り返します。

これをサブパッチ化して使いまわせるようにしよう。

| | コメント (0) | トラックバック (0)

2009年7月14日 (火)

「Jitterで動体検知して遊ぶ」を高速化してもらいました!その2

前回に引き続きhttp://adsr.jp/のmasato221さんが作ってくれたものを解読していきます。
今回はjit.gl.multipleを使ったバージョンで、さらに処理が速く、効率化されてます。

jitter_rx8_multi

●描画オブジェクトの生成
「jit.gl.multiple」はjit.glオブジェクトを繰り返し描画することができます。
やりたいのは●を敷き詰めることなので、jit.gl.gridshapeで●を作っておきます。

jit.gl.gridshape sample @shape circle @depth_enable 1 @automatic 0 @blend_enable 1 @blend_mode 6 1 @dim 10 10 @name pixel @texture tex1 @tex_map 3 @tex_plane_s 0.5 0. 0. 0.5 @tex_plane_t 0. 0.5 0. 0.5

@name pixel
「pixel」という名前をつけています。
「jit.gl.multiple」で繰り返すオブジェクトを指定するための名前です。

読み込んだ映像をテクスチャとして使うための設定もしています。
@texture tex1
「tex1」という名前がついたテクスチャを使うようにします。

@tex_map 3
@tex_plane_s 0.5 0. 0. 0.5
@tex_plane_t 0. 0.5 0. 0.5
この3つはテクスチャの適用方法になると思うんだけど、まだ理解はできず。
tex_plane_sとかはデフォルト値でいいような気がしてしまうけど、なんでこういう値になるのか。。
まあそのうち理解できるはず。

●映像の読み込み
1)jit.qt.movie 20 15 @unique 1
普通に読み込みます。

2)jit.slide @slide_up 4 @slide_down 8
Matrixが滑らかに変化するようにします。

3)jit.gl.texture sample @name tex1
テクスチャを作成します。「tex1」という名前にします。

●動体検知
「jit.matrix 3 float32 20 15」まで前回のと同様です。

●描画
1)jit.expr @expr \"snorm[0]*in[1]*1.33\" \"snorm[1]*-1.*in[1]\" \"0\"
X,Y,Z値を計算します。Zは0で、X,Yは前回と同じ計算です。

2)jit.expr @expr \"(in[0]+(in[1]/50))\"
scale値を計算します。
in[0]は動体検知の結果。動きが大きい部分=白に近い=値が大きいほど描画する●が大きくなります。
in[1]は右のインレットからの入力値。

3)jit.matrix 1 char 20 15付近
これは「jit.gl.multiple」のテクスチャの初期設定みたいなもの?
ディメンション値が変わったとき(最初も含む)に実行されて、全てのセルを1にして出力します。

4)jit.gl.multiple sample 3 @targetname pixel @glparams position scale texture

「3」はプレーン数かな?

@targetname pixel
繰り返し描画するオブジェクトの名前を指定します。

@glparams position scale texture
インレットで受け取るパラメータ。
この指定で第1インレットがposition、第2がscale、第3インレットがtextureになります。
描画する●たちのpositionとscaleの値をMatrixで受け取ることで描画します。
textureのほうは・・・なんだろう?テクスチャとなるMatrixと同じディメンション数のMatrixを渡してあげればいいっぽいけども。このMatrixの中身分だけ描画が繰り返される気がする。


こんな感じでまだ完全に理解できてるわけではないです。
それでもmasato221さんに作ってもらったのを見る前と今とでは全然違う。
「jit.gl.multiple」もよく分かんないからいいやって思ってたけど、今なら全然使える気がする。。
ほんとmasato221さんありがとうございました~。

今回のやつは会社のエントランスに設置してみる予定です。
他にもいろいろ作る予定。WEBカメラだけじゃなくてセンサーも使ってみたい。やっとGainerを使う日が来るかも。
会社のサイトとの連動も考えてます。

とりあえずローカルにある映像を順番に再生するのをやりたいのだが・・・

| | コメント (0) | トラックバック (0)

2009年7月 9日 (木)

「Jitterで動体検知して遊ぶ」を高速化してもらいました!その1

前回の「Jitterで動体検知して遊ぶ」で、いつも参考にさせてもらっているhttp://adsr.jp/のmasato221さんからコメントをいただき、なんと高速処理版を作ってくれました!
しかも2種類。いやーほんとありがたいです。うれしいです。助かります。
データは直リンクOKということでしたので遠慮なくリンクしてみます。
http://adsr.jp/patches/rx8.zip

masato221さんとはうちの同僚&元同僚がaircordのサイト制作で関わったとか。
なんか機会があればよろしくお願いします。。

というわけで今回は作っていただいたパッチの1つめを見てみます。

jitter_rx8

●映像入力
右上のエリアで動画を読み込みます。
読み込んだ動画は「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はまだ理解できてなくて・・・これを機に理解できるようにしよう。
また一通り解読したらブログに書きますので。

| | コメント (2) | トラックバック (0)

« 2009年6月 | トップページ | 2009年9月 »