ConvolutionFilterで遊ぶ その3

ピクセル変換の過程を追いかけてみる

前回のエントリーで紹介したツールを使って、ConvolutionFilterの詳細を追いかけてみたいと思います。<<ここ>>にアクセスして、テスト用画像を開いて下さい。
黒い背景の中央に1ピクセルの白いピクセルが表示されていると思います。
この画像を使ってConvolutionFilterによるピクセル変換を見ていきたいと思います。
(Convolutionでどのような計算が行われているかはConvolutionFlterで遊ぶ その1を参照)

さて、いま、行列は以下のようになっています。
0 0 0
0 1 0
0 0 0

この行列を使ってConvolutonFilterを適用する事の意味を考えてみます。
ターゲットとなるピクセル(以下、ターゲットピクセルと表記します)の周辺にある8ピクセルはずべて0です。
周辺にどんな色のピクセルがあったとしても、0倍されるので結果は0です。
言い換えると、ターゲットピクセルの周辺のピクセルは全く考慮しないということになります。
一方、ターゲットピクセルに対応する行列の数値は1です。
自身のピクセルの強さ(色)を1倍するわけですから、ターゲットピクセルは元の色そのままということになります。
つまり、この行列は、なんのピクセル操作もしない行列です。

平行に移動コピー

では、行列を以下のように変更してみます。
何が起こるでしょうか?
Kernelの数値を変更して実際に結果を確認してみて下さい。
0 0 0
0 0 1
0 0 0

ピクセルを1倍してそのまま表示するという意味では、先ほどの「何もしない行列」と同じですが、
1倍するピクセルがターゲットピクセルの右隣になっています。
つまり、ターゲットピクセルを「ターゲットピクセルの右隣のピクセルにそのまま置き換える」という意味になり、
その結果、画像全体が1ピクセル左に移動します。
(メインビューにマウスカーソルをのせて、拡大画像で確認できます。)
convEx1.jpeg

両側に移動コピー

次はターゲットピクセルの左の数値も1にしてみましょう。
0 0 0
1 0 1
0 0 0

今度はターゲットピクセルの右隣だけでなく、左隣のピクセルもコピーします。
左方向の平行移動と右方向の平行移動を重ね合わせたようなイメージです。
convEx2.jpeg

4方向に移動コピー

ということは、以下のような行列は、
0 1 0
1 0 1
0 1 0

予想通りこうなります↓。
このように1倍する行列はすごくわかりやすいですね。
convEx3.jpeg

ガウスぼかし

1倍する行列はこのくらいにして、つぎはガウスぼかしについてみていきます。
Presetから「gauss」を選択して下さい。
convEx4.jpg

行列が次のように変更されると思います。
0.03 0.11 0.03
0.11 0.44 0.11
0.03 0.11 0.03

これも、わりと行列から結果が推測しやすいと思います。
行列をみると、ターゲットピクセルの色を44%に薄めて、薄まった分を周辺のピクセルのから少しずつ足してるのがわかります。
イメージとしては、ターゲットピクセルを周りの色と馴染ませる感じですね。
convEx14.jpg

エッジ検出

エッジ検出はややこしいのですこしずつ理解していきます。
<<ここ>>にアクセスして、次のテスト画像を開いて下さい。
黒い背景に白い四角形の画像が表示されます。

行列を次のように変更してみて下さい。
0 0 0
-1 1 0
0 0 0

四角形の左辺だけが抽出されました。おもしろいですね。
convEx6.jpg
何が起こっているのか考えてみます。
メインビューにカーソルを移動して、四角形の左上角のピクセルをポイントして下さい。
以下のようにその部分を拡大してみる事ができます。
convEx7.jpeg
ターゲットピクセルを、四角形の左上角のピクセルにして考えてみます。
まず、行列の数値0は無視していいのを思い出して下さい。(0倍なので計算に影響しない)
そうすると、考慮するのはターゲットピクセル(行列の1)とその左隣のピクセル(行列の-1)です。
また、ターゲットピクセルの左隣のピクセルは黒(0)です。
黒(0)を何倍しても0なのでこれも無視できます。

つまり、この場合、考慮するのはターゲットピクセルのみということになります。
結果、ターゲットピクセルを1倍してそのままです。
次に、今見たピクセルの右隣のピクセルをターゲットピクセルにして考えてみます。
convEx8.jpeg
行列から、考慮するのはターゲットピクセルとその左隣のピクセルです。
今度は先ほどと違い、ターゲットピクセルの左隣のピクセルは白(255)です。
対応する行列の数値は-1。かけ算すると255 x -1 = -255。
これをターゲットピクセル(白255)と足し合わせます。
結果、255 + (-255) = 0 で、もともと白だったターゲットピクセルが黒に変更されました。
ちょっと乱暴にまとめると、
自分(ターゲットピクセル)の左隣がxで、自分もx(x以下)だったら黒にする。そうじゃなければ、なにもしない。
これを言い換えると、ある色が連続して平行に並んでいる場合、その一番左の色を残し他は黒(0)にすると言えます。
この結果、左端の輪郭が抽出されます。

「両側にコピー」でやった事を応用すれば、右辺も抽出できます。
0 0 0
-1 2 -1
0 0 0

convEx9.jpeg

同様に、上辺と下辺を抽出することで、基本的な輪郭検出の行列になります。
0 -1 0
-1 4 -1
0 -1 0

convEx10.jpeg
※ちなみに、この行列を使ったエッジ検出をラプラシアンフィルタというらしい。

エンボス

エンボスは輪郭検出に似ています。
輪郭検出と違うところは、斜め1方向だけにとどめるところです。
0 0 0
0 1 0
0 0 -1

convEx11.jpeg
このままだとただの輪郭ですが、行列の計算時に各値を128加算(オフセット)すると、以下のようになります。
(いまのところ、このツールにはオフセットを設定する機能は省略してあるので、実際には↓のような画面を見ることはできません。。)
convEx12.jpeg
四角形の上辺と左辺に影が落ちてみえるのが不思議ですよね。
なぜ128オフセットしたのに、ここだけ黒(0)なのでしょうか?
四角形の左上角のひとつ斜め左上のピクセルをポイントしてみましょう。
convEx13.jpeg
見た目は黒ですが、計算結果である「new pixel」値が(-255)になっています。
このため、128が加算されてもグレーにはならず黒い影のように見えるというわけです。
それに対し、値が0の黒いピクセルは、オフセットにより128となりグレーになります。
うまいことできてますね。

カラー画像の場合

今回は単純なグレースケール画像で色々見てきましたが、カラー画像になっても理屈は同じだと思います。
R、G、B各チャンネル(グレースケール画像)に対して同じ事が行われるだけです。

ここまでのまとめ

webで検索してもなかなかリソースが少ないConvolutionFilterですが、正直、人文系Flash使いとしては、ロジカルにこれを追いかけるのはこの辺りが限界。数学的バックグラウンドを持っている人は、もっとエレガントに説明してくれるはず。
奇才の登場を待ちましょう。。
次回は、ConvolutionFilterを使ったアニメーションの可能性について探ってみたいと思います。
つづく…

カテゴリー: flash パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です