バックナンバーはこちら。
https://www.simulationroom999.com/blog/compare-matlabpythonscilabjulia3-backnumber/
はじめに
畳み込み演算の微分フィルタの話。
Sobelフィルタについて解説。
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
Sobelフィルタ【再掲】

Sobelフィルタと使うんだけど、なんか課題があるんだっけ?

そうそう。
そこをまずは確認って感じだ。

まず、Sobelフィルタを再掲しておこう。
\(
K_{sbl}=
\begin{bmatrix}
1 \\
2 \\
1 \\
\end{bmatrix}
\begin{bmatrix}
-1 & 0 & 1
\end{bmatrix}=
\begin{bmatrix}
-1 & 0 & 1 \\
-2 & 0 & 2 \\
-1 & 0 & 1 \\
\end{bmatrix}
\)

使用する画像は恒例の、犬と自転車。
ちなみに、Sobelフィルタをする前にグレースケールにしているものとする。

そのままSobelフィルタを使用すると?

まず、単純にそのままSobelフィルタで畳み込みをしている。
以下の結果になる。


お!なんかエッジ検出できてる?!

でも、なんか異様に暗いな。
エッジも検出出来てるところと出来てないところがあるような気がする。

正解。

これは負の勾配に差し掛かった時に演算結果がマイナスになるんだよね。
それが0にサチって結果エッジが検出出来てない感じになる。

どうするの?!

まぁ普通にabs関数でも挟めば解決だ。
abs関数を入れた結果

そして、その結果が以下。


お!いい感じ度合が上がったか?!

でも、なんか横方向のエッジが検出されていないような???

これはSobelフィルタの向きが起因しているな。
転置したもので再度試してみよう。
\(
K_{sbl}^T=
\begin{bmatrix}
-1 & 0 & 1 \\
-2 & 0 & 2 \\
-1 & 0 & 1 \\
\end{bmatrix}^T=
\begin{bmatrix}
-1 & -2 & -1 \\
0 & 0 & 0 \\
1 & 2 & 1 \\
\end{bmatrix}
\)


横方向のエッジは拾えてるけど、今度は縦方向のエッジが居なくなったぞ。

まぁ、横方向のエッジ検出のカーネルだからね。

どうすんの!!?
最終的なSobelフィルタ

縦方向のエッジ検出、横方向のエッジ検出、
これらを合成すれば解決だ。

どうやって合成するの?

以下な感じで合成する。
\(
G_s=\sqrt{G_{sx}^2+G_{sy}^2}
\)

\(G_{sx}\)が縦方向のエッジ検出のSobelフィルタの結果で、
\(G_{sy}\)が横方向のエッジ検出のSobelフィルタの結果かな?

そうそう。
それぞれをベクトルと捉えて、それらを合成したノルムをエッジというスカラ値にする感じだな。
結果としては以下になる。


おーー!!
完璧にエッジ検出できたんじゃん!?

うむ。
現時点ではここまでだろうな。

(現時点では?ここまで?まだなんかあるんか?)
今後の予定

というわけで、これを各ツール、各言語で試していく。

まぁ、エッジ検出できそうな方式は定まったしね。
まとめ

まとめだよ。
- 単純にSobelフィルタのカーネルで畳み込みをしても期待する結果にならない。
- マイナス値がでるので、絶対値なり二乗なりで対処する必要あり。
- 横方向、縦方向のエッジしか検知できないので、合成する。
バックナンバーはこちら。
コメント