「白黒画像がカラー画像に見えてしまう錯視動画」を作成するスクリプトをOlive+で作ってみます。
錯視は専門ではないのでよくわかりませんが、人の目は、ずっと同じ色を見続けていると、ぱっと画像が切り替わった後に色の残像のようなものが残るそうです。
色の残像として見えるのは、ずっと見ていた色の「補色」に当たる色だそうです。「補色」とは?HSV色座標系のH(Hue、色相)について見てみましょう。
色相は、図のような円周に対して角度0°から、ぐるっと回って、360°で元に戻ってきます。一般的には0°(=360°)の所に赤、120°の所に青、240°の所に緑が割り当てられています。図示したように、加法混色の三原色RGBと、減法混色の三原色CMYが、60°毎に交互に登場します。
肝心な「補色」ですが、この円の中心を挟んで反対側にある色同志を補色の関係にあるといいます。赤の補色はマゼンタ、青は黄色ですね。
一般的には、RGBの各成分値を反転させることで、補色にしているようですね。例えば赤は、(R,G,B)=(1,0,0)なので、成分毎に反転すると、(R,G,B)=(0,1,1)→マゼンタになります。各色の輝度値Yは、以下式で計算できますので、
Y=0.299*R + 0.587*G + 0.114*B
赤色の輝度値Yr=0.299、マゼンタの輝度値Ym=0.701と、輝度が変化(輝度も反転)しています。Olive+スクリプトでは、filter命令のnegativeを使って、RGBの成分を反転することができます。
filter negative, RGB, 1,1,1;
HSV色座標系の色相(H)に対して、180°のオフセットを付け、飽和度(S)とバリュー(V)を変化させない方法で補色画像を作るには、filter命令のhsvadjを使って、以下となります。
filter hsvadj, <hue_ofst>,<sat_coef>,<val_coef>;
↓
filter hsvadj, 180,100,100;
両方実装しておきましたが、結果はあんまり差が無いように思います……。どっちがいいのかな?
// 補色画像を生成する
if (true)
{
// RGBの輝度を反転することで、結果として補色になる
filter negative, RGB, 1,1,1;
}
else
{
// HSV座標系で色相に対して180°のオフセットを付ける
filter hsvadj, 180,100,100;
}
if(true)をif(false)にすると、別法で動画を生成します。
Olive+(Xi-TRACEでも同じです)では、スクリプトの実行中に生成したグラフィックウインドウを、ウインドウスタックと言う考え方で管理します。……ちょっと面倒で、ディスクリプタ方式にすべきだったと後悔してます。気が向いたら修正したいと思います。
ここで、ウインドウスタックについて説明しておきます。
グラフィック画面Aを開くと、その画面には0という番号が与えられます。window命令のopenを実行すると、今開いているのとは別なグラフィック画面Bが開き、新たに0という番号が与えられます。先ほどまで0番だった画面Aの番号は+1されて1となります。filter命令を実行すると、その時点で0番に割り当たっている画面に対してフィルタを施し、結果を新しいグラフィック画面Cに返します。この時、画面Cが0番になって、今まで0番と1番だった画面AとBはそれぞれ+1されて、1番と2番になります。
filter命令がフィルタを施すのは、常に番号0番の画面ですので、もし、最初に開いた画面Aに対してフィルタをかけたい場合には、画像Aを0番に浮上させる必要があり、そのためにwindow命令のfrontを使います。
window front, <num> ;
<num>に指定するのは、画面番号です。
window命令実行前の時点で、画面Aは番号2番ですので、window front, 2;と実行すると、2番に割り当たっていた画面Aが一番上の0番に浮上し、それ以外のウインドウは+1されて下に沈みます。この時点で画面番号は更新されていますので、全く同じ命令「window front, 2;」をもう一度実行すると、今度は画面Bが0番に浮上します。
不要になった画面を閉じる、window命令のcloseもこの画面番号でクローズすべき画面を指定します。
window close, <num> ;
クローズした画面Bは消えて、下の画面が上に詰まります。
今回のスクリプトで何枚か画面を開いて操作していますので、その都度、ウインドウスタックの状態を記載しておきました(これをやらないと、時々自分でもわからなくなるんですけどね……)。参考にしてください。
Olive+は、AVIフォーマットの動画像に対応しています。画像のセーブを実行する命令、save命令でファイル名の拡張子を".avi"とすると、AVI形式のデータに画像を保存します。
save <file_name> ;
もし、指定した".avi"ファイルが存在していれば、動画の最後のフレームに追加します。途中に差し込むことはできません。".avi"ファイルが存在していなければ、ファイルを作成して、最初のフレームとして保存します。
つまり、画像を用意して、動画の順番にsaveを実行して行けば、AVI動画ファイルが完成するということです。今回は、白黒画像と補色画像の2枚しか画像が存在しないので、動画を生成するのに実行したのは、これだけです。
// 補色画像をしばらく表示
idx=0;
while (idx<N_frame_comp)
{
save $(sname);
idx=idx + 1;
}
// 白黒画像をしばらく表示
window front, 1;
idx=0;
while (idx<N_frame_gray)
{
save $(sname);
idx=idx + 1;
}
完成したデータと動画をご覧ください。
Olive+スクリプト:gray_color.olv
スクリプトを実行するには、ダウンロードコーナからOlive+をダウンロード、インストールして、Olive+に実行させてください。
スクリプトを実行すると、最初に変換する画像ファイルを問いあわせるウインドウが開きますので、適切なカラー画像を指定してOKを押してください。JPEG(プログレッシブ形式には未対応)やBMPなどに対応しています。準備ができると、「AVIセーブの設定が開いたら……」というメッセージが出ますので、指示に従ってください。AVIセーブの設定ウインドウでは、「ファイルの上書き」にチェックして、フレームレートを指定されたとおりに設定し、OKを押します。
画像サイズや表示時間などはスクリプト先頭の定数領域で変更可能です。
真ん中に白ドットを作ってありますので、この点をずっと眺めていてください。頭を動かさず、ぼーっと眺めていると良いようです。瞬きくらいはほとんど影響ないので、力を抜いてなんとなーく、眺めていてください。20秒ほどで白黒画像に切り替わりますが、なぜか、カラー画像が飛び込んでくるはず。
このスクリプトがあると、お手持ちの写真などで錯視動画を生成できますので、お試しください。