画像処理 画像処理アルゴリズム

Canny edge detectionの処理アルゴリズム

スポンサーリンク

Canny edge detectionは画像の輪郭部分を抽出するのに、よく用いられるのですが、詳細なアルゴリズムを理解しないまま使われている事も多いのではないでしょうか?(それ、私)

特に、ヒステリシスしきい値の部分などは、詳細な説明も少ないので、今回、まとめてみたいと思います。

 

まずは処理結果から。

 

Canny edge detectorCanny edge detector
処理前画像Canny edge detection処理後

 

大まかな流れとしては

1.ノイズ除去

ガウシアンフィルタなどでノイズを除去します

Canny edge detector

 

2.輪郭抽出

ソーベルフィルタで輪郭を抽出します

Canny edge detector

 

3.非極大抑制

エッジの強さが極大となる部分以外を除外します。

詳細は後述

Canny edge detector

 

4.ヒステリシスしきい値処理

詳細は後述

Canny edge detector

 

完成!!

 

以上の4ステップで成り立っていますが、非極大抑制とヒステリシスしきい値処理がちょっとわかりづらいので、詳細は以下の通りです。

 

非極大抑制

ソーベルフィルタ後のエッジの強さを3D表示すると、こんな感じ↓になります。

Canny edge detector

 

この山の尾根のみを抽出するのが、非極大抑制となります。

Canny edge detectorCanny edge detector

 

具体的には、まず、ソーベルフィルタでエッジの強さを求めて、エッジの角度を求めます。

横方向

Canny edge detector

縦方向

Canny edge detector

エッジの強さ

Canny edge detector

エッジの角度(実際にはエッジの線に直行する向きが求まります)

Canny edge detector

 

エッジの向き(エッジの法線方向)が求まったら、

0°(-22.5°~22.5°)

Canny edge detector

45°(22.5°~47.5°)

Canny edge detector

90°(47.5°~112.5°)

Canny edge detector

135°(112.5°~157.5°)

Canny edge detector

の4つに分類します。

 

エッジの法線方向の3画素のエッジの強さを用いて、中央のエッジの強さが、残す2つの良さよりも大きければ、その部分が極大点ということになり、中央のエッジの強さが最大とならない部分を除外する処理が非極大抑制となります。

Canny edge detectorCanny edge detector
エッジの強さ非極大抑制

 

この処理によりエッジの部分の細線化が行われます。

 

ヒステリシスしきい値処理

ヒステリシスしきい値の処理については、Webで探してもあまりわかりやすいのが無いような気がしますが、以下の通りです。

 

まず、非極大抑制処理で細線化された画像に対して、2つのしきい値を用いて二値化します。

2つのしきい値は、なんとなくエッジっぽい部分(しきい値「小」)と、確実にエッジな部分(しきい値「大」)となるしきい値を設定します。

 

非極大抑制処理画像

Canny edge detector

 

Canny edge detectorCanny edge detector
しきい値「小」しきい値「大」

 

 

この2つの画像を用いて、しきい値「小」の中から、しきい値「大」につながっている部分のみを残します。

分かりやすいように、しきい値「小」の画像にしきい値「大」のエッジを赤くして重ね合わせて表示すると↓

 

Canny edge detector

 

この赤い線につながっていない部分を除外します。

Canny edge detector

 

この処理がまさにCanny edge detectionとなります。

 

(参考)

OpenCV 3.0.0-dev documentation Canny Edge Detection

 

画像処理アルゴリズムへ戻る

コメント

  1. m-oshima より:

    canny法について勉強している者です.書物等で調べてもパッとイメージしにくく
    調べているうちにこちらのページに辿り着きました.
    ソーベルフィルタ後のエッジの強さを3D表示されているかと思いますが,
    どのようなソフトを使って示されていますでしょうか?

    • akira より:

      m-oshimaさん、コメント頂きありがとうございます。

      ここで使用している3D表示ですが、半分、公私混同ではあるのですが、以前、会社で作成したAZP-8100(現在は生産終了)というソフトで表示しています。
      https://www.avaldata.co.jp/products/imaging/item/azp-8100

      内容的にはOpenGLを使ってライブラリを作成し、そのライブラリをC#でラップして使用しています。

      そのため、現在では使用できない状況なのですが、輝度値をCSVファイルに出力する事ができれば、Excelの等高線のグラフ表示で、似た感じの表示ができると思います。
      (確か256x256個のデータまでしか表示出来ないと思います)

  2. ぽぽっち より:

    135°と45°の画像は逆なような気がするのですが、これであっているでしょうか?違っていたらごめんなさい!!

    • akira より:

      ここでの角度については、エッジの向きに応じて処理を変えるためのフラグ的な使い方をしているので、あまりこだわりが無いのですが、基本的には右手座標系のつもりで角度を定義しているつもりでして、画像の左から右の向きが+X方向、画像の上から下の向きが+Y方向、画像の手間から奥への方向が+Z方向で、回転方向は時計回りを正の方向にしているつもりです。
      他の文献等を探すと135°と45°が逆の説明もあるかと思いますが、プログラム上、極大値を探す方向(赤い点の位置)が合っていれば良いんじゃないでしょうかね?

  3. […] 3/20 Canny edge detection […]

タイトルとURLをコピーしました