お絵描きソフトInkscape(インクスケープ)の使い方を初級レベルから上級レベルまで広く紹介しています。
情報追加のリクエストや分かりにくい点があれば下のCONTACTフォームからどうぞ。

Inkscapeで畳み込みフィルタを試してみた

 畳み込みフィルタのパラメータをいろいろ変えて、どんなフィルタ結果が得られるのか、試してみたので、その様子をここで紹介します。

(2023.06.13更新)

試してみるにあたって

 なお、畳み込みフィルタと勝手に呼んでますが、Inkscape(SVG形式)の言葉で言えば、コンボリューションマトリクス(feConvolveMatrix)と呼ばれるフィルタプリミティブ要素だけを使って作ったフィルタのことです。Inkscapeの組み込みフィルタではエッジ検出イメージエフェクト > エッジ検出)がそれにあたります。

 畳み込みフィルタに用いる行列(カーネル)の大きさ(何行何列か)や、その個々の要素の値については、畳み込みフィルタ一般としても、SVG形式の規定としても、特に制約はないようです。

 Inkscapeのフィルタ機能としては、例えば行列の要素としてゼロは指定できるけれど、0.0001や-0.0001のような細かい値は指定できない、カーネルの大きさも1~5しか指定できないなどの仕様上の制約はあるようですが、現実的な範囲では自由に値を指定できるようです。

 (参考:畳み込み演算を使ったフィルタとは?(画像処理の一般論として)

 とはいえ、あらゆるパラメータを試してみるわけにもいかないので、名前の付いているようなメジャーなカーネル(3x3)について、変換結果がわかりやすいサンプル画像と、表計算ソフトに入力したデータの両方で、畳み込みを実行した結果を観察してみました。

Prewittフィルタ

 まず、Prewittフィルタと呼ばれているカーネルです。色が上下左右どちらかの向きに沿って大きく変化しているところを強調するカーネルです。

 これ自身が「フィルタ」と呼ばれることが多いようですが、SVGの世界では「このカーネルを使って畳み込みを行うようなフィルタプリミティブ要素を使ったフィルタ」ということになるので、Prewittカーネルと呼んだほうがしっくりきます。

 それはいいとして、まず表計算ソフトで畳み込みをやってみました。

 左側に変換対象の画像のピクセル列を模したデータを書き、真ん中に書いたカーネルの行列を使って画像の黒枠内について畳み込みを実行した結果が右側のフィルタ適用後のデータになります。

 この場合は除数(スケーリングファクタ)とバイアスをそれぞれデフォルトの1.0と0.0にしているので、最大値が1.5で最小値が-1.5になっていますが、実際はこの変換結果をどんな色で表現したいかに応じて除数とバイアスを調整することになります。

 とりあえず、除数とバイアスはデフォルト値のままで、同じことをInkscapeでもやってみました。

 左が変換前の画像で、上下に変化するグラデーションを設定したものです。どんなグラデーションを設定しているのかは、画像の隣にグラフで描いてみました。台地上に真ん中のところで緑が明るい(ピクセル値が1.0)ものになっています。

 右がPrewittフィルタで変換したものです。Prewittフィルタは前後3ピクセルの間での変化量が大きい個所で大きい値を出力するものですが、上の表計算ソフトで使ったカーネルを見ると分かるように、この例で用いたPrewittフィルタのカーネルは上側の3要素が1.0で下側の3要素が-1.0になっているので、反転して畳み込んだ結果は上側が黒(0.0)で下側が緑(1.0)になるような斜面部分で大きな値になります。反対側の斜面(上側が緑で下側が黒の部分)では値は大きくならず、黒のままです。Inkscapeでもその通りになっている(上の斜面部分がうっすらと緑になっている)ことが分かります。

 もっと斜面部分をくっきり表示させたい場合は、除数に例えば0.1を指定すれば、変換結果の最大値を1.0(つまり明るい緑)にすることができます。

 ところで、Prewittフィルタの要素は「1」と「-1」から構成されているので、これを上下(または左右)と斜め方向のピクセル値の微分を取っているのだ、と説明しているコンテンツが多いのですが、その説明では「畳み込み演算と関係ないじゃないか!」と思えてしまうので、どうもしっくりきません。

 前後のピクセル値に差があるところを強調するための畳み込みカーネルなんじゃないの?と考えると、このカーネルは、ピクセル値の変化が強調されるように、差が大きいところほどさらに差を大きく見せるような重みを設定した重み付き和を求めるためのカーネルだと理解できなくはなさそうです。

 実際、次のように「1」と「-1」ではないけれど、それなりに前後の差を表したようなカーネルを作って試してみました。


 これでも、除数とオフセットをちょっといじることで変換後の表示色を調整すると、次のように、斜面のところを同じように強調できることがわかります。(当たり前といえば当たり前ですが)

Sobelフィルタ

 次に、Sobelフィルタと呼ばれるカーネルです。

 Prewittフィルタと同様に、上下(または左右)と斜め方向でピクセル値の変化が大きいところを強調するように変換するカーネルですが、変換対象の真ん中のピクセルから斜め方向の重みが相対的に小さくなっています。変換対象のピクセルの垂直または水平方向の変化以外の変化もある程度盛り込むけれども、Prewittフィルタに比べて少し弱めに盛り込むので、垂直または水平方向の変化がより強調されることになるそうです。

 Inkscapeでやってみると、次のように、Prewittフィルタ(左)ではグラデーションの中のピクセル値の変化の微妙な違いが結果に現れますが、Sobelフィルタ(右)ではその違いが少ししか盛り込まれないので上下方向の変化だけが強調されているように見えます。


Laplacianフィルタ

 次に、Laplacianフィルタと呼ばれるカーネルです。

 変換対象のピクセルと周囲のピクセルとの変化の変化(要するに2次微分)を求めるためのカーネルだと説明されています。

 まずは表計算ソフトでやってみます。

 変化の変化が大きいところを強調するので、ピクセル値が変化していない領域と変化している領域との境目のところ(つまり変化が変化しているところ)がフィルタ適用後に大きい値になっています。

 これを例によって無理やり畳み込み演算として理解すると、変換対象のピクセル値が周囲のピクセル値に対して「凹んでいる」ことを強調するように、変換対象のピクセル値は大きなマイナスの重みを設定しているということになります。

 同じことをInkscapeでもやってみると、次のように、黒一色の領域とグラデーションの領域との境目(つまり、ピクセル値の並びで考えると「凹んでいる」ところ)が強調されます。

 なんでもう一方の、緑一色の領域とグラデーションの領域との境目のほうは強調されないのか?こちらだって変化の変化は大きいはずでは?とも一瞬思いますが、こちらは「凹んでいる」ところではなく「出っ張っている」ところなので、中央のピクセルの重みがマイナスであるようなLaplacianフィルタでは強調されないということなのですね。

 「出っ張っている」ほうを強調したい場合は、カーネルの要素をひっくり返して、中央のピクセルの重みを大きいプラスにすればよいことになります。