2012年12月14日金曜日

convo2d その3

更新しました。

convo2d-0.1.3.7z
https://github.com/chikuzen/convo2d

* 5x5マトリクスが効かなくなっていたのを修正
* ちょっと高速化

追記:
本フィルタはGenericFiltersに統合されましたので、開発/配布を終了しました。
今後はGenericFiltersをお使い下さい。

2012年12月13日木曜日

convo2d その2

更新しました。

convo2d-0.1.2-2.7z
https://github.com/chikuzen/convo2d

・入力クリップの各フレームのフォーマットが一定でない場合、及びフレームのサンプルがfloatの場合の処理を追加。

VapourSynthはAviSynthと違って、クリップの各フレームの解像度や色空間がすべて同じであるとは限りません。フレーム0は720x480のYUV420P8なのに、フレーム1は1920x1080のRGBということもありえます。
そこらへんを忘れていたので処理を追加しました。


さて、せっかく書いたプラグインなので、なにかやってみようと思います。
とりあえず簡単そうなやつで、アンシャープマスクでもいってみましょうか。

一般にアンシャープマスクと呼ばれる処理は次のようなことを行います。
1. 元画像と、それをぼかした画像を用意する。
2. 元画像とぼかした画像の差分をとる。
3. 差分をそのまま、もしくは何かしら手を加えてから元画像にかぶせる。
この結果として、なんかコントラストがきつくなったような画像が得られます。

まずは元画像を読み込みます。
import vapoursynth
core = vapoursynth.Core()
core.std.LoadPlugin('/path/to/vsimagereader.dll')
clip = core.imgr.Read('/path/to/lena.bmp')
次にぼかした画像を用意する。
core.std.LoadPlugin('/path/to/convo2d.dll')
blur = core.convo2d.Convolution(clip, [1, 1, 1, 1, 1, 1, 1, 1, 1])
二つの画像の差分をとります。
def clamp(value):
    if value < 1: return 0
    if value > 254: return 255
    return value

lut_diff = []
for y in range(256):
    for x in range(256):
        lut_diff.append(clamp(x - y + 128))

diff = core.std.Lut2([clip, blur], lut_diff, [0, 1, 2])
とりあえず今回はそのままかぶせます。
lut = []
for y in range(256):
    for x in range(256):
        lut.append(clamp(x + y - 128))
result = core.std.Lut2([clip, diff], lut, [0, 1, 2])
では元画像と結果を並べてみましょう。
last = core.std.StackHorizontal([clip, result])

差分のクリップに閾値をつけたり、値に倍率を掛けたり、あるいはぼかし方を変えてみたりしてみるのも面白いかもしれません。

しかし、これではconvo2dの使い方というよりLut2の使い方みたいですな…。

追記:
0.1.2では修正が不十分だったので、0.1.2-2に更新しました。

2012年12月10日月曜日

convo2d

VapourSynth用に空間convolutionフィルタを書きました。

convo2d-0.1.1.7z
https://github.com/chikuzen/convo2d

マトリクスを変更することによって様々な処理が行えることから、カスタムフィルタと呼ばれたりするものです。

単純な平滑化/先鋭化からエッジ検出、エンボス、ピクセルシフトといろいろ出来るので、ググってマトリクスを探してみるのもいいかもしれません。

追記:
メモリリーク、及び画像端の処理が間違ってたのを直しました。