前回に続き、VideoProcessorによる画像処理を取り上げます。
輪郭線抽出の方法の1つはすでに標準のプリセット[Edge detection (vertical)]を紹介しましたが、これは横方向の差分から縦線を優先的に抽出する方法でした。

今回は上下左右の4近傍ピクセルを使ったラプラシアンフィルタを実装してみたいところですが、これには注目ピクセルの近傍(3x3)にアクセス出来る必要があります。gfx_evalrect()ではこの範囲のピクセルを直接参照することが難しいため、これで実装するのは結構面倒なことになりそうな気がします。

フィルタリングの実装

無理矢理なんとかする方法はいくつかありそうですが、ここではgfx_blit()とブレンドモードを使って処理する方法を紹介します。

作成したスクリプトはこちら。※重いので画像サイズの大きい動画にはご遠慮くださいw

ラプラシアンの4近傍カーネルは
| 0  1 0 |
| 1 -4 1 |
| 0  1 0 |
なので、普通はピクセル毎に畳み込みを行っていくのですが、今回の方法はこれをgfx_blit()で重ねて描画することで実現します。手順はだいたい以下のような感じ。
  1. 背景を黒で塗りつぶす
  2. カーネルの1のところを4回重ねたいので、画像の値を1/4に潰す(α=1/4)
    (重ねる画像バッファの各チャンネルは8bitなので、そこに収まるように1/4スケールで計算)
  3. BlendMode=1(加算)にする
  4. 注目ピクセル位置に、カーネルに対応した1ピクセルずれた位置が重なるように描画(4近傍分)
  5. 注目ピクセルを最後に重ねるため、α=-4にして描画
画像の階調を1/4に圧縮して重ねる計算なので精度が落ちますが、はっきりとした境界の部分を検出するくらいには使えそうです。8近傍で重ねるように実装すれば結構いろいろなフィルタカーネルが使えるようになりますが、更に精度が悪くなります(精度が悪すぎるので色が破綻するかも)。
あと、これだけだと画像の端1ピクセル分のところがおかしくなったり、値の範囲チェックなども省略してるのでもろもろ雑だったりします。まぁ効果を見る程度のものということで。

で、実際に処理してみた結果がこちら。
VP_Lap01-0
 ↓ 効果を適用
VP_Lap01

VP_Lap02-0
 ↓ 効果を適用
VP_Lap02

この手法もどこで覚えたのか忘れてしまいましたが、現在のようなピクセルシェーダなんてものがなかった頃のGPUでこういったフィルタを作る時に、重ねてポリゴン描画するだけで高速に処理する方法だったような違うような・・・?
まぁこんなところで役に立つとは思いもしませんでした。

もはや自分はDAWで一体何をやっているんだ?という気分になってきましたが、まぁ楽しめているのでいいかな。