「バイラテラルフィルターって何?」ってのがあって、見てみると速攻で実装できそうだったので作ってみました。画像処理実験室の記事を参考にさせていただいています。今回のプログラムは、次のものです。ps_2_0)まぁ、いつものように適当にファイルが入っています。大事な部分だけを抜粋すると、次のファイルだけに注目すればいいことになります。シェーダプログラム他にも、実行ファイル、リソースファイル、プロジェクトファイルが入っています。画像をスムーズにしつつもエッジ部分はぼかすことのない効果を持っているらしいです。輝度の差も見て、変化が大きいところは重みを小さくすることによってエッジを残します。位置に移動する重みwxと、輝度に依存する重みwdで合成する感じになります。ぼかしの重みにガウス分布を用いると。それぞれの重みは次のようになります。前の係数は、分母で割ることを考えるといらないけどね。重みの大体の幅を決めるものと考えることができます。大きくなると全体的にぼけたように合成されます。x軸(横方向)にテクセルの差、y軸(奥方向)に輝度の差をとって、z軸(上方向)を合成の重みとします。重みが大きいほうが合成結果に強く影響を及ぼします。ガウスぼかしの時は、輝度によらず重みを合成するので、下のような感じで、輝度方向は変化しない重みになります。バイラテラルフィルタでは、これが輝度によっても変わるので、重みのグラフは次のようになります。エッジを強く残したいときは、輝度の差による重みの変化を大きくすれば(分散を小さくすれば)よく、次のようなグラフになります。(または、フィルタのテクセルの幅を小さくして少しだけぼかすとき)。σd=2の時は下のようなグラフになります。元画像がこんなだったとします。バイラテラルフィルタで距離の分散を大きく(σx=5)して、輝度の分散を小さく(σd=0.2)すると次のようになります。ぼやけるところはぼやけていますが、境界部分などは比較的はっきりしています。距離の分散を小さく(σx=0.01)すると全体的にはっきりします(σd=1)。このサンプル画像はよくないかもね。■実装2パスで17x17テクセルのガウスぼかしのプログラムを変更することによって実装をしてみました。中心以外のテクセルは、隣接したテクセルの平均値を使って2テクセル同時に計算しています。1パス目で横方向にぼかします。重みの正規化をしています(だから浮動小数点バッファが必要です)。したがって、1パス目の後の画像は全体的な輝度がおかしくなっています。2パス目の縦方向にぼかした結果が次のものです。ガウスぼかしと違うのは、輝度の差で重みを調整しているということです。今回は、輝度の差の2乗を使うということで、RGBの各成分の色の差を内積命令で合成して使っています。1パス目のシェーダプログラムは次のようなもんです。この前のもと素材の生成時には、アルファ成分に1を書き込むようなレンダリングをしています。2.0に収まらなかったので、係数をベクトルにするなどの最適化をしているので、見づらくなっています。すまん(まぁ、テクスチャ座標の計算を最適化しろとの声もありますが...)。2パス目のシェーダは次です。重いと思う人は、テーブル化するなり(区分)線形化すると良いのではないでしょうか。符号などに関して前処理をします。}また、テクセル間の距離に関する重みは、前もって計算しておきます。}■最後にはやりもののフィルタらしいですねぇ。何度もかけるとトゥーンシェーディングになるようです。これ自体で、云々はないのかもしれないのですが、画像処理的には使えそうな感じがします。もどるimagire@gmail.com。