/**/
Jitter によるビデオデータ・マトリックスの生成、表示は、デジタル画像の表現方法に関するいくつかの前提に基づいて行なわれています。多くの一般的な使用を目的として(これまでのチュートリアルで示したように)カラー画像はchar型の4プレーンのマトリックスにコード化されています。これらのプレーンはマトリックス内の各セルのアルファ、赤、緑、青のカラーチャンネルを表しています。このような色の表現(ARGB)は、私たちが色を知覚する方法(私たちの眼の色受容体は赤、緑、青を感知します)や、コンピュータモニタ、プロジェクタ、テレビが色を表示する方法とよく合致しているため、実用的なものであると言えます。チュートリアル5:「ARGB カラー」では、このシステムの背後にある正当性を調べ、一般的にこのようなデータをどう扱うかについて説明しています。
しかし、ARGB がデジタル形式で色を表現する唯一の方法というわけではないことを覚えておくことは重要です。このチュートリアルでは、Jitter マトリックスでカラー画像情報を表現するいくつかの異なった方法の1つを調べると共に、それぞれ異なった用途のために利用できる、ARGBの代わりとなる方法について検討したいと思います。同時に、ビデオをOpenGL のプレーン上に乗せ、ハードウェアアクセラレーションを利用したビデオ画像のポストプロセッシングを利用する、シンプルで効果的な方法についても見て行きたいと思います。
ソフトウェア動作環境:Jitter で uyvy カラーモードを使用するためには、QuickTime のバージョン 6.5 以降が必要となります。メディアはYUV カラースペースを使ったコーデックによって圧縮されている必要があります(下記で詳しく述べます)
RGBカラースペースを使ったコーデックによって圧縮されている QuickTime メディア(例えば、PICT ファイルや プレーンRGBビデオファイル)は、このチュートリアルで使っている jit.qt.movie の uyvy カラーモードでは復元できません。QuickTime バージョン 7 以降では、メディアがエンコードされるときのカラースペースに関係なく uyvy カラーモード(colormode)で実行することができます。
・Jitter Tutorials フォルダの チュートリアルパッチ 49jColorspaces を開いて下さい。
一見したところ、このパッチは、チュートリアル12:「カラールックアップテーブル」で使ったものと非常によく似ています。パッチはファイルを jit.qt.movie オブジェクトに読み込み、マトリックスを jit.charmap オブジェクトに送ります。カラールックアップテーブルを提供するマトリックス(themap)を作っておくことによって、この jit.charmap オブジェクトでそれぞれのプレーンに対して、任意の方法でカラーマッピングを変更することができます。その後、処理済みのマトリックスが表示されます。
・read colorwheel.jpgと書かれたメッセージボックスをクリックして下さい。パッチの最上部にある qmetro オブジェクトに接続されている、Displayと表示された toggle をクリックして下さい。jit.pwindow と jit.window オブジェクトによって作られたウィンドウの両方にカラーホイールが表示されるはずです。
すぐには(まだ)解らないと思いますが、このパッチの画像マトリックスは、私たちが慣れ親しんでいるARGB マッピングとは違ったカラーシステムによって生成され、操作されています。このパッチの jit.qt.movie オブジェクトはマトリックスを uyvy と呼ばれるカラーモード(colormode)で送信します。これは、画像処理チェインが、いつも使っているものとは違う、YUV 4:2:2: というカラースペースによるデータで動作することを意味します。加えて、いつも使っているものとは違った座標系(ARGB ではなく YUV)で色の送信を行なうため、この送信モードは、クロマ・サブサンプリングというテクニックを使い、与えられたサイズのイメージのデータ送信量を減らしています(およそ半分になっています)。
・パッチの右側の multislider オブジェクトを操作してみて下さい。これらの multislider が画像の色をマップする方法に影響を及ぼしていることに注目して下さい。あなたには、3つの multislider オブジェクトが、それぞれマトリックスの緑、赤、青のマッピングに対応しているという感覚があるかもしれません。いちばん左のmultislider (白地に黒)をゼロにしてみてください(すなわち、すべての値を 0 にしてください)。画像が消えたことに気がつくと思います。normal と表示されたボタンをクリックして、全てをもとに戻して下さい。他の2つの multislider を順にゼロにしてみて下さい。さらに、それらを範囲の中間を横切る水平な直線になるようにセットしてみて下さい。
Manipulating the color.
YUV カラースペースは、ルミナンス/クロミナンス(輝度/色差)カラーシステムです。このシステムでは、与えられた色の光度を、色相を決定する色彩情報から分離させます。この方法では、与えられたピクセルの輝度をルミナンスチャンネル(Y)に格納します。そして、Uチャンネルは、カラー画像の青の量からYを引いた差として作られます。V チャンネルはカラー画像の赤の量からYを引いた差として作られます。U および V チャンネル(クロミナンスを表します)は異なった係数によってスケールされます。結果として、U と V が低い値になると、緑の影が現れ、両方が中間の定数値を持つ場合にはグレースケール画像になります。RGBによる色の値から YUV への変換には、次のような式が用いられます。
Y = 0.299R + 0.587G + 0.114B
U = 0.492(B - Y)
V = 0.877(R - Y)
このカラースペースの U および V の要素は、通常符号を持っています。(すなわち、輝度が青、または赤の量を超える場合には、これらは負の値になります。オレンジ、緑、シアンのような色の場合にこのようなことが起こります。)Jitterマトリックスは unsigned char (符号なし整数)のデータを格納するため、U と V の値は 0-255 の範囲で表され、128 が色空間の中央の点になります。
Y の値が中間値の定数である場合の YUV カラースペース
このチュートリアルパッチで使われている YUV カラースペースの実装仕様は、YUV 4:2:2 と呼ばれるものです。マトリックスデータをビデオとして解釈する必要がある Jitter オブジェクト(例えば、jit.qt.movie、jit.pwindow など)は、colormode アトリビュートが uyvy にセットされている場合に、このカラースペースを生成、表示できます。このカラーモードでは、しばしば、隣り合った2つのカラーピクセルを1つのセルに格納する、クロマ・サブサンプリングと呼ばれる処理が使われます(「マクロ・ピクセル」と呼ばれています)。私たちの眼は色よりも、輝度の微細な変化に適合するため、これは画像のデータ縮小を実行するための効果的な方法で、実質的に、適度な正確さで色を伝えるために必要な情報の約半分をカットすることができます。このシステムでは、Jitter マトリックスの個々のセルは4つのプレーンを持ち、これが水平方向に隣り合った2つのピクセルを表します。プレーン0 は両方のピクセルの U の値を、プレーン1 は最初のピクセルの Y の値を、プレーン 2 は両方のピクセルの V の値を、プレーン 3 は2番目のピクセルの Y の値を持ちます。このプレーンの順序(uyvy)によって、画像のルミナンス(輝度)の変更は、プレーン1 と 3 を調節する(ピクセル列で交互に)ことによって行なうことができるのに対し、ピクセルのクロミナンス(色差)の変更は、1組だけで(プレーン 0 とプレーン 2 を調節することによって)行なうことができます。
歴史的な注: ルミナンス/クロミナンス カラーエンコード(画像の輝度は、画像の色相またはクロミナンスとは別々に送信されます)は、カラーテレビ放送の歴史にその起源をたどることができます。1953年にカラーテレビ放送がアメリカ合衆国で導入された時、テレビの視聴者に対してモノクロ(黒と白)のテレビ受像機でも番組を見ることが可能な方法を提供する必要がありました。結果として、これは、すでにグレースケール画像として輝度情報を持っているオリジナルの放送シグナルに、単純にカラー情報を(副搬送波の形で)追加するという方法に決定しました。これは、YIQ (luminosity-intermodulation-quadrature)と呼ばれ、このカラースペースは NTSC カラーテレビ放送で使用されています。これと等価なPAL テレビジョンシステムは、ここで紹介している YUV カラースペースを用いています。
下のイラストは、ARGB から UYVY への変換が、Jitter でどのように扱われるかを示したものです。jit.qt.movie オブジェクトは、必要な時に(下の囲み欄を参照してください)この変換を実行してくれますが、jit.argb2uyvy および jit.uyvy2argb オブジェクトは任意のマトリックスのカラースペースを変換します。この変換によって、アルファ情報が失われ、ARGBのオリジナルが持っていた色情報は水平に隣り合った2つのセルの間で平均化されてしまうため、カラー情報において僅かな損失が生じるということを覚えておいて下さい。
UYVY カラーシステムはマクロピクセルを使うため、マトリックスの中の個々のセルは、実際には画像内の2つの水平方向に隣り合ったピクセルを表します。例えば、320 x 240 ピクセルの画像は、UYVY として出力される場合には 160 x 240 セルのマトリックスになります。これらのマトリックスを処理する場合、次のことを覚えておくことは重要です。空間情報(すなわち、スケーリング、回転、畳み込み等)に基づいてマトリックスを処理する Jitter オブジェクトでは、これらのピクセルの組を1つのユニットとして取り扱います。このようなタイプの処理を併用する場合、フル解像度のピクセルを用いるカラーモード(colormode)、すなわち ARGB あるいはAYUV(Jitter でもサポートされるフル解像度 YUV カラースペース)で作業を行なう方が、より簡単に扱えるでしょう。
uyvy マトリックスに変換を行なう場合、マトリックスサイズは(水平軸方に)半分になり、argb に再変換される場合には2倍になります(新しい、空のアルファチャンネルも作られる点に注意してください)。
ARGB から UYVY に変換され、さらに再変換される 4 x 4 グリッドのランダム値
多くの商用のビデオコーデックでは、ネイティブなビデオフォーマットとしてYUV 4:2:2 (あるいは、同様なクロマ・サブサンプリングシステムである 4:1:1 や 4:2:1 )を使います。その結果、jit.qt.movieはこれらのファイルを、標準の ARGB フォーマットによるマトリックスを出力するよりも速く uyvy カラーモードに復元できます。 この方法で生成されたマトリックスは、サイズも半分であるため、このシステムを利用できる任意の Jitter パッチのパフォーマンスを向上させます。Photo-JPEG、DVCPRO、NTSC DV のようなコーデックは全て、ネイティブなカラーフォーマットとして、ある種のサブサンプリングされたYUV を使います。
このことを考慮することによって、パッチ内で行なわれている処理を理解することができます。jit.qt.movie は jit.charmap に、uyvy の 4 プレーン char フォーマットのマトリックスを送りますが、この jit.charmap はデータを処理してさらに先に送ります。jit.fpsgui は送られたマトリックスの dim(大きさ)が 160 x 240 であることを報告しています。これは、カラーモードの変更に伴って生じるマクロピクセルを用いたデータの減少について理解した今では理解できることです。加えて、マトリックス themap が 1 つでプレーン1 とプレーン 3 の両方にデータを供給する jit.fillオブジェクトを持つ理由についても理解できます。それは、これらがマクロピクセルの2つの Y の値に対応していて、同じルックアップテーブルを共有することが望まれるためです。
・normal と表示された button オブジェクトをクリックして、multislider オブジェクトを通常のカーブに設定して下さい。brco と書かれたパッチャーオブジェクトの上にある、Y チャンネルのコントラストをコントロールするナンバーボックスを -1 になるまで調整して下さい。
反転された Yカラーテーブル
この新しいカラースペースでは、ルミナンス(輝度)はクロミナンスから分離されているため、ピクセルの色相に影響を及ぼさずに、ブライトネス(明るさ)を反転させることが簡単にできます。ARGB で作業している場合、これはより複雑な手順になります。
・multislider オブジェクトを再び通常に戻し、U および V チャンネルのコントラスト(contrast)を調整して下さい。両方とも -1 に、その後 0 にしてみて下さい。コントラストの設定を通常に戻し、ブライトネス(brightness)の値を両方とも -1 にして下さい。
様々な U と V のセッティング
U および V チャンネルのカラールックアップを反転することによって、画像の色相環が180 度回転します。この両方のチャンネルを定数値にすると画像の彩度が減じられ、このチュートリアルの最初に紹介したデカルト座標空間による一定の彩度、または色相になります。値が 0 の場合、画像はグレースケールになるまで彩度を減じられます。値が -1の場合、画像全体が緑色になります。
・multislider オブジェクトをフリーハンドで変化させて下さい。様々な charの範囲がどのように異なったチャンネルに異なった効果を及ぼすかを感じ取ってみて下さい。
YUV 4:2:2(colormode uyvy)や ARGB(colormode argb、ほとんどのオブジェクトの初期値)に加え、他のいくつかのカラースペースでマトリックスを生成する Jitter オブジェクトが存在します。この例としては、grgb(uyvy と同様なクロマ・サブサンプリングを行なう RGB カラースペース)、ayuv(アルファチャンネルを持つ、フル解像度の YUV カラースペース)、luma(1プレーンの char 型によるグレースケール形式)、ahsl(alpha-アルファ、hue-色相、saturation-彩度、luminosity-輝度(明度))が挙げられます。変換をおこなうオブジェクトは通常 jit.x2y という名前になっています(例えば、jit.argb2uyvy)。加えて、jit.colorspace オブジェクトは様々な 4 プレーンの charによるカラースペース(L*a*b のような浮動小数点カラースペースに近似したものも含みます)間の変換、逆変換をサポートします。カラースペース(および、一般的な色の数値表現)に関するより詳しい情報を探すには、このテーマに関するWikipedia 記事から始めるとよいでしょう。
http://en.wikipedia.org/wiki/Color_space
訳注:日本語では「色空間」というwikipediaの項目があります
http://ja.wikipedia.org/wiki/色空間
・パッチの jit.pwindow の出力が直接 jit.window オブジェクトに入力されているのではない点に注目して下さい。その代り、この出力は jit.gl.videoplane というオブジェクトに対して行なわれています。read track1.mov と書かれたメッセージボックスをクリックして下さい。処理される画像がムービーに変わります。パッチの右側にある normal と表示された button をクリックして、カラールックアップテーブルを通常に戻して下さい。
jit.gl.videoplane オブジェクトは、インレットに送られてくるマトリックスをOpenGL 描画コンテキストのプレーンにテクスチャとして貼付けます。描画コンテキスト(カラースペース)は、パッチ上部にある jit.gl.render オブジェクトによって駆動され、jit.window オブジェクトのウィンドウを通じて可視化されています。Jitter における OpenGL レンダリングの基本を復習する必要がある場合、チュートリアル 30:「3Dテキストの描画」を見ることでレンダリングシステムの生成の基礎について理解できると思います。ここで、注目しておいて欲しいことの1つは、jit.gl.render の ortho アトリビュートです。これが 2 に設定されている場合、シーンのレンダリングは平行投影で行なわれます(すなわち、奥行きは考慮されません)。もう1つは、テクスチャマトリックスを uyvy として解釈するように、jit.window ではなく、jit.gl.videoplane オブジェクトに対し colormode アトリビュートによって命じておく必要があるということです。このパッチでは、実際には OpenGL を 3D モードで使っているわけではありませんが、ハードウェアアクセラレーションによるテクスチャマッピングの機能のいくつかをを利用しています。
・dim 16 16というテキストが書かれているメッセージボックス(jit.pwindow オブジェクトの隣)をクリックして下さい。
jit.pwindow オブジェクトが、極端にダウンサンプリングされ、ピクセル化された映像を表示しているのに注目してください(実際に、それまでと同じ uyvy モードで、8 x 16 のマトリックスとして処理されています)。
しかし、jit.windowオブジェクトは、ピクセルがお互いに滑らかに補間された映像を表示しています(この効果は、jit.matrixオブジェクトで interp アトリビュートを 1 にセットした場合と良く似ています)。
テクスチャとして適用された小さいマトリックスのハードウェア補間
この補間は、グラフィックス・プロセッシング・ユニット(GPU) ハードウェア上で行なわれていて、コンピュータのメイン CPU に対するパフォーマンスに損失を与えないため、ビデオの表示に OpenGL を使う場合の多くの利点の1つと言えます。
・dim 320 240というテキストが書かれているメッセージボックスをクリックして下さい。これによって、マトリックスを、それまでの標準の解像度、320 x 240 ピクセルに戻し、カラーモード(colormode)によって 160 x 240 セルのマトリックスを出力します。パッチの右側で、fullscreen $1と書かれたメッセージボックスに接続された toggle をクリックしてください(あるいは、[ESC] キーを押してください)。
jit.window オブジェクトをフルスクリーンモードにしたとき、jit.gl.videoplane はテクスチャをさらにアップサンプリングし、できる限り滑らかに補間して表示してくれます。
・[ESC] キーを押してトグルを再度トリガし、jit.window のフルスクリーンモードを解除して下さい。
・jit.gl.videoplane オブジェクトにつながっている pak オブジェクトに接続された、赤(R)、緑(G)、青(B)のナンバーボックスオブジェクトを加減して下さい。
適用されているテクスチャが YUV カラースペースでマップされているにも関わらず、jit.gl.videoplane が浮動小数点数による RGBAアトリビュートに対応している点に注目して下さい。rotate と表示されたナンバーボックスを操作して下さい。
videoplane 上での GPU プロセッシングの例
たいていの OpenGL オブジェクトが持つ color および rotate アトリビュート(scale や blend_enable 等も同様です)が、jit.gl.videoplane にも適用されることがわかります。結果として、jit.gl.videoplane オブジェクトは、イメージ処理を直接 GPU 上に乗せることができるため、ビデオプロセッシングにとって途方もなく役に立つものであると言えます。
jit.qt.movie オブジェクトはARGB以外のいくつかのカラースペース(色空間)によるマトリックスを出力することができます。YUV 4:2:2 カラースペースは、サポートするオブジェクト(jit.qt.movie、jit.pwindow、および jit.window)の colormode アトリビュートを uyvy に設定することによって使用できます。uyvy カラーモードはマクロピクセル・クロマサブサンプリングを使うという利点を持っています。これによって、データレートを半分に押さえ、Jitter マトリックス処理チェインでマトリックスの処理を速めることができます。このカラースペースのデータ出力は 4 プレーンの char 情報であるため、jit.charmapのような標準のオブジェクトを使用して、異なった結果を生むマトリックス操作を行なうことができます。
jit.gl.videoplane オブジェクトはマトリックス(uyvy マトリックスを含みます)をテクスチャとして受け取り、オブジェクトによって名付けられた OpenGL 描画コンテキストの平面にマップします。従って、GPU アクセラレーションによるイメージの処理が直接平面上で行なわれます。この処理には、着色、ブレンド、空間変形などが含まれます。チュートリアル41:「シェーダ」では描画コンテキストの中のオブジェクトに処理アルゴリズム全体を適用し、Jitter の処理で GPU を使うことの可能性をより拡大する方法について見て行きます。
(訳注:本文では、「チュートリアル52:...」となっていますが、実際には チュートリアル 41 が「シェーダ」になっていて、そこでは、GPU 上でのアルゴリズムの処理についての記述があります)