![]() |
OpenCV 4.13.0
Open Source Computer Vision
|
この章では、次のことを学ぶ
Cannyエッジ検出は、広く用いられているエッジ検出アルゴリズムである。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 を適切に選択することが非常に重要である。
この段階では、エッジは長い線であるという仮定に基づいて、小さなピクセルノイズも除去する。
そして最終的に得られるのは、画像中の強いエッジである。
OpenCVは上記のすべてを単一の関数 cv.Canny() にまとめている。その使い方を見ていく。第1引数は入力画像である。第2、第3引数はそれぞれ minVal と maxVal である。第4引数は aperture_size である。これは画像勾配を求めるために使われるSobelカーネルのサイズである。デフォルトは3である。最後の引数は L2gradient であり、勾配の大きさを求める式を指定する。Trueの場合、上で述べたより正確な式を使用し、そうでない場合は次の関数を使用する: \(Edge\_Gradient \; (G) = |G_x| + |G_y|\)。デフォルトはFalseである。
以下の結果を参照のこと。