Canny edge detectionは画像の輪郭部分を抽出するのに、よく用いられるのですが、詳細なアルゴリズムを理解しないまま使われている事も多いのではないでしょうか?(それ、私)
特に、ヒステリシスしきい値の部分などは、詳細な説明も少ないので、今回、まとめてみたいと思います。
まずは処理結果から。
→ | ||
処理前画像 | Canny edge detection処理後 |
大まかな流れとしては
1.ノイズ除去
ガウシアンフィルタなどでノイズを除去します
2.輪郭抽出
ソーベルフィルタで輪郭を抽出します
3.非極大抑制
エッジの強さが極大となる部分以外を除外します。
詳細は後述
4.ヒステリシスしきい値処理
詳細は後述
完成!!
以上の4ステップで成り立っていますが、非極大抑制とヒステリシスしきい値処理がちょっとわかりづらいので、詳細は以下の通りです。
非極大抑制
ソーベルフィルタ後のエッジの強さを3D表示すると、こんな感じ↓になります。
この山の尾根のみを抽出するのが、非極大抑制となります。
→ |
具体的には、まず、ソーベルフィルタでエッジの強さを求めて、エッジの角度を求めます。
横方向
縦方向
エッジの強さ
エッジの角度(実際にはエッジの線に直行する向きが求まります)
エッジの向き(エッジの法線方向)が求まったら、
0°(-22.5°~22.5°)
45°(22.5°~47.5°)
90°(47.5°~112.5°)
135°(112.5°~157.5°)
の4つに分類します。
エッジの法線方向の3画素のエッジの強さを用いて、中央のエッジの強さが、残す2つの良さよりも大きければ、その部分が極大点ということになり、中央のエッジの強さが最大とならない部分を除外する処理が非極大抑制となります。
→ | ||
エッジの強さ | 非極大抑制 |
この処理によりエッジの部分の細線化が行われます。
ヒステリシスしきい値処理
ヒステリシスしきい値の処理については、Webで探してもあまりわかりやすいのが無いような気がしますが、以下の通りです。
まず、非極大抑制処理で細線化された画像に対して、2つのしきい値を用いて二値化します。
2つのしきい値は、なんとなくエッジっぽい部分(しきい値「小」)と、確実にエッジな部分(しきい値「大」)となるしきい値を設定します。
非極大抑制処理画像
しきい値「小」 | しきい値「大」 |
この2つの画像を用いて、しきい値「小」の中から、しきい値「大」につながっている部分のみを残します。
分かりやすいように、しきい値「小」の画像にしきい値「大」のエッジを赤くして重ね合わせて表示すると↓
この赤い線につながっていない部分を除外します。
この処理がまさにCanny edge detectionとなります。
(参考)
OpenCV 3.0.0-dev documentation Canny Edge Detection
関連記事
←画像処理アルゴリズムへ戻る