![]() |
OpenCV 4.13.0
Open Source Computer Vision
|
Canny エッジ検出は広く使われているエッジ検出アルゴリズムである。1986 年に John F. Canny によって開発された。これは多段階のアルゴリズムであり、各段階を順に見ていく。
ノイズ低減
エッジ検出は画像中のノイズの影響を受けやすいため、最初のステップでは 5x5 のガウシアンフィルタで画像中のノイズを除去する。これは前の章ですでに見たとおりである。
画像の強度勾配の算出
平滑化された画像を水平方向と垂直方向の両方で Sobel カーネルによりフィルタリングし、水平方向 ( \(G_x\)) と垂直方向 ( \(G_y\)) の一次微分を得る。これら 2 つの画像から、各ピクセルについて以下のようにエッジ勾配と方向を求めることができる:
\[ Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\ Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg) \]
勾配の方向は常にエッジに対して垂直である。これは垂直、水平、および 2 つの対角方向を表す 4 つの角度のいずれかに丸められる。
非最大抑制
勾配の大きさと方向を得た後、エッジを構成しないと考えられる不要なピクセルを除去するために画像全体をスキャンする。このために、各ピクセルにおいて、そのピクセルが勾配方向の近傍で局所最大であるかどうかを確認する。以下の画像を確認すること:
点 A はエッジ上(垂直方向)にある。勾配方向はエッジに垂直である。点 B と C は勾配方向にある。したがって、点 A が局所最大を形成するかどうかを点 B および C と比較して確認する。もしそうであれば次の段階に進められ、そうでなければ抑制される(ゼロにされる)。
要するに、得られる結果は「細いエッジ」を持つ二値画像である。
ヒステリシスしきい値処理
この段階では、どれが本当にエッジで、どれがエッジでないかを判定する。このために、minVal と maxVal という 2 つのしきい値が必要である。強度勾配が maxVal より大きいエッジは確実にエッジであり、minVal より小さいものは確実に非エッジであるため破棄される。これら 2 つのしきい値の間にあるものは、その連結性に基づいてエッジか非エッジに分類される。「確実なエッジ」のピクセルと連結していれば、エッジの一部とみなされる。そうでなければ、これらも破棄される。以下の画像を参照のこと:
エッジ A は maxVal より上にあるため、「確実なエッジ」とみなされる。エッジ C は maxVal より下にあるが、エッジ A と連結しているため、これも有効なエッジとみなされ、曲線全体が得られる。しかしエッジ B は、minVal より上にあり、エッジ C と同じ領域にあるものの、どの「確実なエッジ」とも連結していないため破棄される。したがって、正しい結果を得るためには minVal と maxVal を適切に選択することが非常に重要である。
この段階では、エッジは長い線であるという仮定に基づいて、小さなピクセルノイズも除去する。
そして最終的に得られるのは、画像中の強いエッジである。
次の関数を使用する: cv.Canny(image, edges, threshold1, threshold2, apertureSize = 3, L2gradient = false)
| image | 8ビット入力画像。 |
| edges | 出力エッジマップ。image と同じサイズを持つシングルチャンネルの 8 ビット画像。 |
| threshold1 | ヒステリシス処理のための第1のしきい値。 |
| threshold2 | ヒステリシス処理における 2 番目のしきい値。 |
| apertureSize | Sobel 演算子のアパーチャサイズ。 |
| L2gradient | 勾配の大きさを求める式を指定する。True の場合、より正確な上記の式を使用し、そうでない場合は次の関数を使用する: \(Edge\_Gradient \; (G) = |G_x| + |G_y|\)。 |