チュートリアル3

マトリクスにおける演算


このチュートリアルでは、Jitterのマトリクスに保存されているデータに対して簡単な演算操作を行うことを可能にする方法について説明します。マトリクスのセル、またはその中の個別のプレーンに対してスケーリング演算を行うためのjit.opオブジェクトの使い方について見てみましょう。

・Jitter Tutorial フォルダにある 01MathOperations.patを開いて下さい。(訳注:ファイル名は実際には03MathOperations.patの間違いと思われます。)

このチュートリアルパッチは3つの部分に分かれていて、それぞれjit.opオブジェクトで行うことができる簡単な数値演算の例を示しています。jit.opオブジェクトは、個別の数値に対してというよりは、マトリクス全体のデータを一度に処理するような数値演算を行います。


マトリクスのすべてのセルに定数値を加算します

最初の例では、jit.matrixオブジェクトがjit.opに接続されていて、このjit.opの出力をjit.pwindowによって見ることが出来るようになっています。jit.opオブジェクトの右インレットに接続されているナンバーボックスの値を変えるたびごとに、bangメッセージによってjit.matrixが新しいマトリクスを送りだすようになっています。アーギュメントからもわかるように、このjit.matrixオブジェクトは、プレーンが1で、データ型がchar(すなわち、データは0-255の範囲の値)である、4×3のマトリクスを生成しています。jit.pwinodowオブジェクトは、このマトリクスをグレースケールの画像として視覚化しています。ナンバーボックスをドラッグすると、jit.pwindowのグレーレベルが黒(0) から白(255) まで変化します。

jit.matrixオブジェクトが、全てのセルの値が0にセットされたJitterマトリクスを送り出していることを理解することは重要です。jit.opを経由しないで、jit.matrixjit.pwindowが直接接続されていたとすると、黒い画像が現れ、jit.matrixに何回bangメッセージを送信しても何も変化は起こらなかったでしょう。jit.opオブジェクトは、(ナンバーボックスで決定された)数値を、jit.matrixからjit.opに送られたJitterマトリクスの全てのセルに加算します。


@記号による操作

上の文で、jit.opオブジェクトが、受信したマトリクスの全てのセルに対して加算を行うと説明しました。このjit.opオブジェクトが加算(除算や乗算ではなく)を行った理由は、そのopアトリビュートの値にあります。このopアトリビュートとは、jit.opが受信したマトリクスに対して行う演算を定義するシンボル(またはシンボルのリスト、すぐ後で述べます)のことです。このケースでは、opアトリビュートは+という値にセットされているのがわかります。これは、左インレットにどんなマトリクスが送られて来た場合でも、単純に加算を行うということを意味し、右インレットの整数値をマトリクスの全てのセルに加算します。マトリクス全体に同じ値が加算されるので、この値をスカラーと呼びます。(チュートリアル9では、 jit.opによって、同様に2つのJitterマトリクスを使った演算を可能にする方法ついて御説明します)

重要な注記:jit.opオブジェクトの右インレットでスカラー値を変化させても、新しいマトリクスは出力されません。もし、ナンバーボックスとbuttonオブジェクトを結ぶパッチコードが切断されていたとしたら、jit.pwindowオブジェクトの表示の変化はストップしてしまったでしょう。これは、次のような理由によります。多くのMaxオブジェクトと同様、ほとんどのJitterオブジェクトは左インレットに何らかの入力が行われた場合にだけデータを出力します。上のケースでは、ナンバーボックスの値を変化させるたびに、 jit.opオブジェクトは新しいスカラー値を保存します。その直後にbuttonオブジェクトがjit.matrixにbangメッセージを送り、新しいJitterマトリクス(全ての値が0にセットされたもの)をjit.opオブジェクトの左インレットに送信させます。これが引き金となってマトリクスが出力され、それを見ることができたわけです。TraceメニューのEnableコマンドを選択し、Stepコマンド(Command+T)を使ってメッセージ命令を段階的に見ていくと、この様子を見ることができます。(トレース機能によってMaxメッセージをトレースする方法についての詳細は、Max4.0 Tutorial and Topics マニュアルの"デバッギング"の章を参照して下さい。)

スカラ値はjit.opのvarアトリビュートを使った定数として与えることもできます。例えば、受け取られるJitterマトリクスの全てのセルに対して常に134を加算したい場合、このようなオブジェクトを使ってナンバーボックスを省略することができます。


スカラ値をアトリビュートとして設定します。

同様に、与えられたjit.opオブジェクトによって行われる数値演算を変更しようとする場合には、op の後に関連した数学記号を伴ったメッセージを左インレットに送ります。


データの複数のプレーンに対する演算

2つめの例では、jit.opを使って入力されて来るマトリクスに値の加算を行う、より複雑な場合が示されています。


マトリクスの各プレーンに対して個別のスカラ値を使います

このパッチは最初のものとよく似ていますが、重要な違いは、ここでは4つのプレーンを持つマトリクスを扱っているという点です。このことは、ここで使用されるマトリクスを生成するjit.matrixの最初のアーギュメントからわかります。jit.pwindowはJitterマトリクスデータの4つのプレーンを、アルファ、赤、緑、青という4つの別々なカラーチャンネルとして解釈し、これらをカラーで表示します。この例では、 jit.opオブジェクトのopアトリビュートは4つのシンボルからなるリストを伴っています。各々のシンボルは入力されてくるマトリクスの1つのプレーンに対する数値演算を設定します。このパッチでは、最初の(アルファ)プレーンはそのまま通過させ、他のプレーンは、個々に数値を加算します。(このように、思いのままに演算子を混ぜ合わせたり、一致させたりすることができます。)

このjit.opオブジェクトの右インレットに接続されているpakオブジェクトは、4つの整数を受け取りリストにまとめます。pakとMaxのpackオブジェクトとの唯一の違いは、(左インレットに新しい数値、またはbangメッセージが送られた時にだけ新しいリストを出力するpackオブジェクトに対し)pakでは、どの数値が変更された場合でも新しいリストを出力する点です。pakによって生成されるリストの4つの数値は、 jip.opオブジェクトに入力されてくるマトリクスの個々のプレーンに対するスカラ値を決定します。上の例では、(opアトリビュート最初のアーギュメントはpassなので)プレーン0には何も加算されません。プレーン1,2,および3では、それぞれ、161,26,及び 254がそれぞれ加算されます。jip.pwindowオブジェクトは出力されるマトリクスのセルを美しいマゼンタをのような色として解釈します。(画面は単に一色に見えますが、実際にはマトリクスにはすべて同じ値をセットされた12個の異なるセルがあります。)

重要な注記:上の例で、jit.opオブジェクトのopアトリビュートに1つの値だけを与えた場合(そして、スカラとして1つの数値だけを使用した場合)、jit.opは、その数学演算子とスカラ値を入力されて来るマトリクスの全てのプレーンに適用します。


画像の色の変更

3つめの例では、jit.opオブジェクトを、すでに一連のデータが格納されているマトリクスに適用しています。


個々のプレーンにスカラを乗算します

・importmovie colorbars.pictというメッセージボックスをクリックして下さい。jit.matrixオブジェクトにimportmovieメッセージを送ると、オブジェクトによって格納されるJitterマトリクスに、ピクチャまたはQuictTimeムービーから画像の1フレームを読込みます。これによって、ディスク上のピクチャはオブジェクトの持つマトリクスの大きさに合わせられます(このケースでは、320×240になります)。

buttonオブジェクトをクリックするとパッチの右側にあるjit.pwindowオブジェクトには画像補正カラーバーが表示されます。このケースでは、jit.opオブジェクトは、算術演算子としてアルファプレーン用にはpassが、他のプレーン用には*(乗算)がセットされています。4つのプレーンを持つ画像を操作していますから、個々のスカラーを4つの浮動小数によるリストを使ってセットします。1から3までのプレーンに1. を適用するとオリジナルの画像が示されます。


すべてのスカラが1の場合

スカラを0., 1., 0., 0., にセットすると次のような画像になります。


これは赤を表します。

カラーバーが格納されているマトリクスの(プレーン1を除く)すべてのプレーンには0が掛けられています。これによって、マトリクスのアルファ、青、緑のプレーンが取り除かれ、後には赤(プレーン1)だけが残ります。

jit.opオブジェクトのスカラーとして(0., 0., 1., 0.5のような)中間の値を設定すると、カラーバーはまた違った画像に見えます。


かわいいでしょ?

この場合、アルファチャンネルは無視され、赤のチャンネルは0になります。青のプレーンの値はすべてもとの画像の半分になります。緑のチャンネル(プレーン2)はそのままです。

重要な注記:jit.opの数学的なスカラには、浮動小数の数値で表されているもの、整数で表されているものがあります。これは、入力されるマトリクスの数値の型だけでなく、(opアトリビュートで定義され)関連づけられている演算子にもよります。このチュートリアルの全ての例ではcharのマトリクスが使用されているため、これらに加算を行う時には整数を用いることが理にかなっています。(マトリクスのデータは常に0-255の範囲の整数である必要があるので、すべての浮動小数点の数値は丸められます)。入力にfloat32によるマトリクスを使っていたとしたら、それに浮動小数点の数値を加算することは全く理にかなっていたでしょう。同じように、charのマトリクスに浮動小数点スカラを掛け合わせることは合理的と言えます(240*0.5=120であり、これは整数です)。しかし、jit.opが出力するマトリクスはcharマトリクスのままなので(下記の注を参照)、依然として0-255の間の数値だけを得ることができます。

スカラ値を変えていろいろ実験してみると、簡単にいくつかのカラーバーを消したり、隣り合ったバーを結合させたりすることができることがわかるでしょう。これはカラーバーが同じ範囲にある標準的な色の値に設定されているためです。1度に1つのチャンネルだけを見る(1つを除くすべてのプレーンを0に設定する)と、上に並んでいる7つのバーのうちの4本がカラーで示されます。

このチュートリアルでは + と * という演算子について説明してきました。しかし、実際にはjit.opは他にも非常に多くの数学演算を行うことができます。扱える演算子を網羅したリストはリファレンスページで、またはjit.opのヘルプファイルにあるp op_list というサブパッチをダブルクリックして見ることができます。


サイズの変更

jit.pwindowオブジェクトを生成すると、幅80ピクセル、高さ60ピクセルのウィンドウとしてMaxにあらわれます。このサイズは、Maxの他のインターフェイスオブジェクトと同じように、グローボックスを使って変更することができます。正確にサイズの変更を行いたい場合は、インスペクタを利用するか、size メッセージの後に幅と高さをピクセルで表した値を続けたものを送ります。


jit.pwindowのサイズを変更します

あるサイズ(ピクセル値)のjit.pwindowオブジェクトに異なるサイズ(セル数)のマトリクスを送った場合、jit.pwindowオブジェクトは、マトリクス全体を表示するために入力されたマトリクスをスケーリング(拡大、縮小)します。非常に大きなjit.pwindowに非常に小さなマトリクスを送ると、ピクセレーション(全く同じ色のままの、画像の中の矩形の領域)として表示されます。また、小さなjit.pwinodowに大きなマトリクスを送ると、詳細な変化の度合いが失われて表示されるでしょう。

重要な注記:上の例では、jit.matrixは320×240セルのサイズ(dim というリストで指定されています)、4つのプレーン(planecount は4)、Char型のカラーバーを持っています。jit.opオブジェクト(そして、今後ご紹介するほとんどのJitterオブジェクト)はこの情報を認識し、マトリクス全体に演算を行い、同じ形のマトリクスを出力するために適応を行います。jit.matrixオブジェクトが違うサイズに変えられると、jit.opオブジェクトは即座にこれを認識し、再び適応を行います。jit.pwindowオブジェクトもまた入力されてくるマトリクスに適応しますが、少しだけ異なった方法をとります。入力されるマトリクスが自分自身の大きさより小さい場合、データを複製してすべてのピクセルを満たします(この結果は、前の段落で述べたピクセレーション効果になります)。入力されるマトリクスが自分自身の大きさより大きい場合、データの一部を無視せざるを得なくなり、可能なものだけを表示します。このため、チュートリアルパッチのjit.pwindowは、入力されてくるマトリクスのサイズ(セル数)とは決して一致しないにもかかわらず、jit.opオブジェクトのマトリクスのサイズに適応するためにベストを尽くします。最後の例の jit.pwindowでは、jit.opオブジェクトの出力するマトリクス全体を可能な限り表示しようとしますが、受け取った320×240のマトリクスを、自分自身が持つ160×120の表示領域にはめ込むために、他の行と列はすべて無視します。


まとめ

jit.opオブジェクトによって、一度にJitterマトリクスのすべてのデータに対して数学的な演算を行うことができます。マトリクスのセルすべて、または個々のプレーンに対しての演算が可能です。jit.opが行う数学的な演算は、jit.opオブジェクトのop アトリビュートによって決まります。これは、オブジェクトに@op [演算子] というアトリビュートアーギュメントをあらかじめ設定しておくか、op [演算子] というメッセージを左インレットに送ることで設定することができます。複数のプレーン(マルチプレーン)を持つマトリクス(カラー画像、ビデオのようなもの)では、演算子のリスト(例えば、op pass * * *)を送ることによって、個々のプレーンに対しての演算方法を指定することができ、それぞれ異なったスカラー値を設定できます。チュートリアル9では、単純なスカラの代りに2つめのJitterマトリクスを使用する方法についてご説明するつもりです。

jit.pwindowのサイズは size [幅] [高さ] というメッセージで設定できます。jit.pwindowは、受け取ったすべてのマトリクスのサイズに最大限に適応しようとします。入力されてくるマトリクスのサイズがjit.pwindow自身のサイズより小さい場合は、データを複製し、大きい場合はいくつかのデータを無視します。たいていのJitterオブジェクトは、受け取ったマトリクスの大きさ、型、プレーン数に最大限に適応しようとします。jit.opの場合には、それ自身の大きさは指定されないので、入力されてくるマトリクスの属性に適応します。