ピクセル変換の過程を追いかけてみる
前回のエントリーで紹介したツールを使って、ConvolutionFilterの詳細を追いかけてみたいと思います。<<ここ>>にアクセスして、テスト用画像を開いて下さい。
黒い背景の中央に1ピクセルの白いピクセルが表示されていると思います。
この画像を使ってConvolutionFilterによるピクセル変換を見ていきたいと思います。
(Convolutionでどのような計算が行われているかはConvolutionFlterで遊ぶ その1を参照)
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 0 |
この行列を使ってConvolutonFilterを適用する事の意味を考えてみます。
ターゲットとなるピクセル(以下、ターゲットピクセルと表記します)の周辺にある8ピクセルはずべて0です。
周辺にどんな色のピクセルがあったとしても、0倍されるので結果は0です。
言い換えると、ターゲットピクセルの周辺のピクセルは全く考慮しないということになります。
一方、ターゲットピクセルに対応する行列の数値は1です。
自身のピクセルの強さ(色)を1倍するわけですから、ターゲットピクセルは元の色そのままということになります。
つまり、この行列は、なんのピクセル操作もしない行列です。
平行に移動コピー
| 0 | 0 | 0 |
| 0 | 0 | 1 |
| 0 | 0 | 0 |
ピクセルを1倍してそのまま表示するという意味では、先ほどの「何もしない行列」と同じですが、
1倍するピクセルがターゲットピクセルの右隣になっています。
つまり、ターゲットピクセルを「ターゲットピクセルの右隣のピクセルにそのまま置き換える」という意味になり、
その結果、画像全体が1ピクセル左に移動します。
(メインビューにマウスカーソルをのせて、拡大画像で確認できます。)

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

4方向に移動コピー
| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 0 |
予想通りこうなります↓。
このように1倍する行列はすごくわかりやすいですね。

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

| 0.03 | 0.11 | 0.03 |
| 0.11 | 0.44 | 0.11 |
| 0.03 | 0.11 | 0.03 |

エッジ検出
エッジ検出はややこしいのですこしずつ理解していきます。
<<ここ>>にアクセスして、次のテスト画像を開いて下さい。
黒い背景に白い四角形の画像が表示されます。
| 0 | 0 | 0 |
| -1 | 1 | 0 |
| 0 | 0 | 0 |
何が起こっているのか考えてみます。
メインビューにカーソルを移動して、四角形の左上角のピクセルをポイントして下さい。
以下のようにその部分を拡大してみる事ができます。

ターゲットピクセルを、四角形の左上角のピクセルにして考えてみます。
まず、行列の数値0は無視していいのを思い出して下さい。(0倍なので計算に影響しない)
そうすると、考慮するのはターゲットピクセル(行列の1)とその左隣のピクセル(行列の-1)です。
また、ターゲットピクセルの左隣のピクセルは黒(0)です。
黒(0)を何倍しても0なのでこれも無視できます。
つまり、この場合、考慮するのはターゲットピクセルのみということになります。
結果、ターゲットピクセルを1倍してそのままです。
次に、今見たピクセルの右隣のピクセルをターゲットピクセルにして考えてみます。

行列から、考慮するのはターゲットピクセルとその左隣のピクセルです。
今度は先ほどと違い、ターゲットピクセルの左隣のピクセルは白(255)です。
対応する行列の数値は-1。かけ算すると255 x -1 = -255。
これをターゲットピクセル(白255)と足し合わせます。
結果、255 + (-255) = 0 で、もともと白だったターゲットピクセルが黒に変更されました。
ちょっと乱暴にまとめると、
自分(ターゲットピクセル)の左隣がxで、自分もx(x以下)だったら黒にする。そうじゃなければ、なにもしない。
これを言い換えると、ある色が連続して平行に並んでいる場合、その一番左の色を残し他は黒(0)にすると言えます。
この結果、左端の輪郭が抽出されます。
| 0 | 0 | 0 |
| -1 | 2 | -1 |
| 0 | 0 | 0 |
| 0 | -1 | 0 |
| -1 | 4 | -1 |
| 0 | -1 | 0 |
![]()
※ちなみに、この行列を使ったエッジ検出をラプラシアンフィルタというらしい。
エンボス
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | -1 |
このままだとただの輪郭ですが、行列の計算時に各値を128加算(オフセット)すると、以下のようになります。
(いまのところ、このツールにはオフセットを設定する機能は省略してあるので、実際には↓のような画面を見ることはできません。。)
四角形の上辺と左辺に影が落ちてみえるのが不思議ですよね。
なぜ128オフセットしたのに、ここだけ黒(0)なのでしょうか?
四角形の左上角のひとつ斜め左上のピクセルをポイントしてみましょう。
見た目は黒ですが、計算結果である「new pixel」値が(-255)になっています。
このため、128が加算されてもグレーにはならず黒い影のように見えるというわけです。
それに対し、値が0の黒いピクセルは、オフセットにより128となりグレーになります。
うまいことできてますね。
カラー画像の場合
今回は単純なグレースケール画像で色々見てきましたが、カラー画像になっても理屈は同じだと思います。 R、G、B各チャンネル(グレースケール画像)に対して同じ事が行われるだけです。ここまでのまとめ
webで検索してもなかなかリソースが少ないConvolutionFilterですが、正直、人文系Flash使いとしては、ロジカルにこれを追いかけるのはこの辺りが限界。数学的バックグラウンドを持っている人は、もっとエレガントに説明してくれるはず。 奇才の登場を待ちましょう。。次回は、ConvolutionFilterを使ったアニメーションの可能性について探ってみたいと思います。