niiyan's blog

niiyanの個人ブログ。

HowToApplyFilterToManySingleFrames

特定のフレームや範囲にだけフィルタをかけたい場合、AviSynthではApplyRangeフィルタやFilterRange関数を使って、これを行うことができます(参照)。

しかし、その対象フレームや対象範囲が複数に渡るときは、これらのフィルタを何度も呼び出す必要が出てきます。それは、スクリプトを書く手間がかかるだけでなく、AviSynthに負荷をかけてしまうことにもなりかねません。

AviSynth.orgに掲載されているHowToApplyFilterToManySingleFramesを使えば、なるべくAviSynthに負担をかけずに、かつ、比較的簡単に、複数の範囲にフィルタをかけることができます。この方法では、AviSynthに内蔵されているConditionalFilterフィルタとConditionalReaderフィルタを使用します。




ソースクリップ



例として、このビデオクリップの1フレームと3-4フレームだけに、GreyScaleフィルタを適用したいと思います。GreyScaleフィルタは、ビデオクリップをグレースケールに変換するフィルタです。

スクリプト

global FreezeThis = 0
video = ColorBars(80,60) # ソースクリップ
frozen = video.GreyScale() # 適用したいフィルタ
ConditionalFilter(video, frozen, video, "FreezeThis", "==", "1")
ConditionalReader("Setting.txt", "FreezeThis", false)

ここでは細かい説明は省きますが、「"FreezeThis"」の値が1ならフィルタ適用後のクリップ(frozen)を選択、そうでなければオリジナルのクリップ(video)を選択するという内容になっています(いずれAviSynth Wikiで、もう少し詳しく説明するかもしれません)。

2行目のクリップのパスと3行目の適用したいフィルタ、そして5行目のSetting.txtさえ変更すれば、ほかのフィルタを使用したい場合にも応用できます。

これとは別にSetting.txt(上記スクリプトの5行目で指定)を用意します。これは、"FreezeThis"の値を設定するためのファイルです。

Setting.txtは、次のように記述します。

type int
default 0
1 1
R 3 4 1

1行目:

type int

データがint型(整数)であることを宣言しています。この場合、とくに変更する必要はありません。

2行目:

default 0

デフォルト値を設定しています。指定されなかったフレームには、この値が適用されます。

今回の例では「"FreezeThis"」の値が1ならfrozenを選択することになっているので、デフォルトは0にしておきます。これも変更する必要はありません。

3行目:

3行目以降で、フィルタを適用したいフレーム(または範囲)を指定します。

1 1

左がフレーム番号、右が値です。このように値を1に設定すると、そのフレーム(この場合は1フレーム)ではfrozenが選択されます。

4行目:

R 開始フレーム 終了フレーム 値

範囲を指定したいときは、このように記述します。RはRange(範囲)のRです。

R 3 4 1

例の場合、3から4フレームまでの値を1に設定していることになり、その範囲はfrozenが選ばれることになります。

さらにフレームを指定したい場合は、同様にして設定を追加していきます。

フィルタ適用後



上記のスクリプトを実行すると、このようになりました。Setting.txtで指定したフレームだけが、グレースケールになっています。

備考: 複数の範囲にフィルタを適用できるFilterRangeExプラグインもあります。