【画像処理】Cannyエッジ検出器の原理・特徴・計算式

Cannyエッジ検出器により輪郭(エッジ)検出の原理や特徴、計算式についてまとめました。

【はじめに】Cannyエッジ検出器の概要

Cannyエッジ検出器は、画像の輪郭(エッジ)部分を検出するアルゴリズムです。
輪郭を検出する他のアルゴリズムとしては「ソーベルフィルタ」「ラプラシアンフィルタ」などがあります。

それらのフィルタと比べた時のCannyエッジ検出器の特徴は次の通りです。

①輪郭の検出漏れや誤検出が少ない。
②各点に一本の輪郭を検出する。
③真にエッジの部分を検出できる。

■入力画像(左)、出力画像(右)

処理手順

Cannyアルゴリズムの大まかな処理手順は以下の通りです。

順序 内容
Gaussianフィルタで画像を平滑化する。
平滑化された画像の微分を計算する。
微分した結果から勾配の大きさと方向の計算する。
Non maximum Suppression処理をする。
Hysteresis Threshold処理をする。

【手順1】ガウシアンフィルタで平滑化処理

ガウシアンフィルタは、画像の平滑化処理に用いられているフィルタです。
このフィルタは、処理をかける画素の周りの画素値とガウス分布の重み付けを利用することで自然な平滑化をおこなうことができます。
入力画像をI、ガウシアンフィルタのカーネルをK_gとすると、平滑化画像をGは次式で計算します。

(1)   \begin{eqnarray*} G=I*K_g \end{eqnarray*}

*は畳み込み積分を表しています。

【参考】ガウシアンフィルタの原理・特徴・計算式

【手順2】平滑化画像を微分

平滑化画像Gをソーベルフィルタなどで微分します。
ソーベルフィルタの水平方向微分、および垂直方向微分のカーネルをK_x, K_yとします。
このとき、水平方向、及び垂直方向の微分画像G_x, G_yは次式で計算できます。

(2)   \begin{eqnarray*} G_x=G * K_x\\ G_y=G * K_y \end{eqnarray*}

【手順3】微分画像から勾配の大きさ・方向の計算

微分画像Gから勾配の大きさ|G|と方向\thetaを次式で計算します。

(3)   \begin{eqnarray*} |G|&=&\sqrt{G_x^2+G_y^2}\\ \theta &=& tan^{-1}\frac{G_y}{G_x}=atan2(G_y, G_x) \end{eqnarray*}

【手順4】Non maximum Suppression処理

Non maximum Suppression処理でにより、③の微分画像|G|輪郭を細線化します。
注目画素の画素値と、輪郭の勾配方向に隣り合う2つの画素値を比較します。
そして、3つの中で注目画素の画素値が最大でない場合、画素値を0(黒)に置き換えます。

尚、注目画素の法線方向は、③で求めた勾配方向から求まります。

【手順5】Hysteresis Threshold処理

Hysteresis Threshold処理では、2つの閾値(最大閾値・最小閾値)で「信頼性の高い輪郭」と「信頼性の低い輪郭」を選びます。
④で生成した細線画像の画素値と2つの閾値から、次のように輪郭の信頼性を評価します。

画素値 評価
最小閾値より小さい 信頼性の低い輪郭。
最小閾値~最大閾値の間 信頼性の高い輪郭が隣にあれば信頼性の高い輪郭。違えば信頼性の低い輪郭。
最大閾値より大きい 信頼性の高い輪郭。

そして、信頼性の低い輪郭は除去します。
これにより、途切れてしまっている輪郭を繋げることができます。
同時に誤検出した輪郭を削除できます。

【実装例】プログラム

Cannyアルゴリズムの実装例(プログラム)について下記事で解説しています。

詳細記事
Python 【Python/OpenCV】Cannyアルゴリズムで輪郭検出
関連記事 【画像処理入門】アルゴリズム&プログラミング

コメント