お知らせ: にーやんのブログ 2 に移転しました。こちらのブログは、2009 年末までに削除します。

スポンサード リンク

Project N: 015 - ブルーバック合成風(つづき)

前回ColorKeyMaskを使って、ブルーバック合成風の合成(?)に、とりあえず成功しました。ところで、前回紹介できなかった、ColorKeyMaskの引数toleranceについて、少し補足しておきます。

マニュアルには、toleranceについて、次のような説明があります。

Each pixel with a color differing less than tolerance is set to transparent, otherwise it is left unchanged (it is NOT set to opaque).
(toleranceの値よりも差が小さい色を持つピクセルは、透明に設定されます。それ以外は、変更されません(非透明に設定されるのではない)。)

何だかよくわかりませんが(汗)、たぶん、色(color)の許容範囲みたいな感じだと思います(toleranceは、寛容、耐久力、許容誤差などの意)。tolerance=0なら、colorで指定した色のみを透過色とし(つまり、誤差0)、tolerance=50なら、colorとの差が50より小さい色も透過色に含めるということかと。

実際、toleranceを変えてみたところ・・・


tolerance=200あたりでは、かなり輪郭がガタガタになり・・・


tolerance=240では、もうボロボロ。さらに、tolerance=255にすると・・・


真っ黒になっちゃった。

さらに、tolerance=256にすると・・・


tolerance=0と一緒?

ちなみに、colorが背景だけでなく、人物にも使われていたら、当然、その部分も透過色になってしまいます。

Project N: 014 - ブルーバック合成風(ColorKeyMask)


前回までの画像。

このままでは、当然のことながら、人物画(img)の背景の青色が気になります。そこで、全体の背景(bg)に馴染むように青色を消したいと思います。いわゆるブルーバック合成みたいな感じです。

ここでは、ColorKeyMaskというフィルタを使って行います。

ColorKeyMaskは、以前、紹介したMaskと同じように、アルファチャンネルを追加するフィルタなのですが、Maskとの違いは、用意した画像を使うのではなく、色を比較してアルファチャンネルを作り出す点にあります。

ColorKeyMask(clip clip, int color, int tolerance)
ColorKeyMaskの書式です。

colorは、透過色に設定したい色を16進数で指定します。ここでは青色の部分を透過させたいので、color=$0000ffとします(imgの背景は、#0000ffの青色で塗りつぶしてあります)。toleranceは、とりあえず0にしておきます(toleranceについては後述)。

img = ColorKeyMask(img, $0000ff, 0)
これを、img = ConvertToRGB32(img)の後に挿入します(スクリプトは前回を参照)。ColorKeyMaskは、RGB32でのみ動作するフィルタです。すると・・・


適当にやった割りに、いい感じじゃないですか!?


この画像を2倍に拡大してみました。輪郭も悪くない・・・ていうか、(・∀・)イイ!!

ちょっと長くなってきたので、次回へつづく。

Project N: 013-Clip Properties(クリップ情報の取得)

前回、次からはLayer以外の話を進めるみたいなことを書きましたが、ひとつだけ書き忘れていたことがありました。


前回までに、Layerフィルタを使って、画像(img)と背景(bg)を合成したクリップです。

見てもらってわかるように、画像(img)はクリップの左上隅にあります。
これをクリップの中心(あたり)に位置するようにしたいのです。

Layer(clip base_clip, clip overlay_clip, string op, int level, int x, int y, int threshold, bool use_chroma)

Layerフィルタの書式です。
このうち、xとyが、overlayクリップ(ここではimg)の位置を指定するための引数になります。
どちらも、int型(整数)です。

xはクリップの左端からの距離、yは上端からの距離になります。
xとyを指定しなかった時に、imgが左上に来ていたのは、デフォルトでは、x=0, y=0となっているからです。

さて、xとyを指定すれば、imgの位置を調整できることがわかりました。
では、imgがクリップの中心に来るようにするには、どうすればいいでしょうか?

そこで、次のように考えてみました。


bgの横幅をa、imgの横幅をbとします。
このとき、aとbの差を二等分したものをxとすればいいのではないかと。

もっといい方法があるかもしれませんが、こんなのしか思いつきませんでした。 orz

ここで、クリップの情報(Clip Properties)を取得する関数を使います。
クリップの幅を求める関数はWidth()です。
引数は、clipのみ。

たとえば、imgの幅を知りたい場合、次のように記述します。

Width(img)

bgの幅を知りたい時は、imgの部分をbgにすればいいだけです。
これを利用して、xを表すと、

x = (Width(bg)-Width(img))/2

bgの幅からimgの幅を引いたものを、2で割っています(/は、わり算の演算子。bgとimgの差をカッコで括っていることに注意)。

同様にして、yを求めます。
クリップの高さを求める関数はHeight()なので、

y = (Height(bg)-Height(img))/2

となります。

img = ImageReader("C:\My Documents\nyatrix\img\nyatrix.png", 0, 0, 24, false)
img = ConvertToRGB32(img)
bg = BlankClip()
x = (Width(bg)-Width(img))/2
y = (Height(bg)-Height(img))/2
Layer(bg, img, "add", 255, x, y)

スクリプトは、このようになりました。


プレビューすると、imgが真ん中に来てますね。
・・・たぶん、真ん中です。

Project N: 012-マスク(Mask/ResetMask)

前回、画像(img)のアルファチャンネルをShowAlphaフィルタで確認したところ、真っ白でした。



真っ白=アルファ値最高、なので、Layerでの合成時にlevelの値がそのまま反映されていたのですが、ではアルファチャンネルが真っ白でなければ、どうなるのでしょうか。

Maskというフィルタを使うと、アルファチャンネルに独自のマスクを指定することができます。

マスクは白黒の画像で、黒が透過、白が非透過になります。
画像処理系のソフトで、特定の範囲にだけ処理を施す場合に使われますね。


試しに、上の画像をマスクとして追加してみます。
Mask(clip clip, clip mask_clip)
Maskの書式です。

そこでスクリプトを、次のように変更します。
img = ImageReader("C:\My Documents\nyatrix\img\nyatrix.png", 0, 0, 24, false)
img = ConvertToRGB32(img)
mask_clip = ImageReader("C:\My Documents\nyatrix\img\nyatrix_mask.png", 0, 0, 24, false)
mask_clip = ConvertToRGB32(mask_clip)
img = Mask(img, mask_clip)
bg = BlankClip()
Layer(bg, img)
MaskはRGB32でのみ動作するため、mask_clipもConvertRGB32()しています。

これをプレビューすると・・・



さらにShowAlphaでチェックすると・・・



マスクが変更されているのがわかります。

ちなみに、ResetMaskというフィルタを使うと、マスクをリセットして、完全非透過(つまり真っ白け)のクリップをマスクに追加することが出来ます。
試しに、先程のスクリプトの最後に次の1行を追加して、
ResetMask()
ShowAlpha()すると・・・



真っ白になっちゃった!(某マジシャン風)

・・・・・・。

Layer関連の話はこれくらいにして、次回からは、もう少し動画づくりの作業を進めていきたいと思います。

Project N: 011-アルファチャンネル(ShowAlpha)

アルファチャンネルに関しては、用語集などを参考にしてください。
私には、とても説明など出来ません orz

といいつつ、ちょっとだけ話をします(ぉ

RGBは、光の三原色R(Red)、G(Green)、B(Blue)の3つのチャンネルの組み合わせで色を再現します(たぶん)。
このうち、RGB24は、RGB各8bit -> 8*3=24bitだから、RGB24(確か)。
一方、RGB32は、RGB各8bitにアルファチャンネル8bitを加えて、8*3+8=32でRGB32です(きっと)。

RGB32に関しては他の定義もあるようなことをどこかで読んだ(気がする)のですが、AviSynthにおけるRGB32はRGB + アルファチャンネルで合ってます(と言ってみる)。


上は(あくまでも)イメージ図。

で、AviSynthに限定して話をすると、アルファチャンネルは透過度を表すデータとして使われ、黒=透明、白=不透明(非透過)となります。
アルファチャンネルが黒だと背景をそのまま通し、白は通さない、グレーは半透明なので背景とブレンドされたようになる、というわけです(おそらく)。

では、前回、Layerで合成した画像の場合、アルファチャンネルはどうなっているのでしょうか。

そこで、ShowAlphaというフィルタを使って、アルファチャンネルを表示してみましょう。

ShowAlphaは、AviSynth2.5.3から追加されたフィルタです。
書式は次の通り。

ShowAlpha(clip clip, string pixel_type)

ShowAlphaはRGB32でのみ動作します(アルファチャンネルがあるのはRGB32だけなので)。
ただし、pixel_typeを指定した場合、アルファチャンネルを別の色空間(YUY2/YV12)に変換して表示することもできます(AviSynth2.5.4以降)。


level=0


level=128


level=255

上から順にlevel=0, 128, 255、それぞれの場合のアルファチャンネルです。

Layer(img, bg, "add", 0)
ShowAlpha()

こんな感じで、スクリプトを書きました。
pixel_typeは指定していません。

level=0の時、アルファチャンネルは黒(真っ黒)なので透明、つまり背景(bg)の色(黒)をそのまま通します。
これに対し、level=255では、アルファチャンネルは白なので非透過、つまり背景の色を通さないので、画像(img)が表示されます。

ちなみに、Layerで合成する前の画像(img)のアルファチャンネルはどうなっているかと言いますと・・・、



真っ白でした。

Page 3 of 5: « 1 2 3 4 5 »