第 10 章: Canny 画像エッジ検出

Canny エッジ検出は、多段階のエッジ検出アルゴリズムを使用してエッジを検出する方法です。1986 年、John F.Canny は有名な論文「A Computational Approach to Approach to Edge Detection (エッジ検出へのアプローチへの計算論的アプローチ)」を発表し、その中でエッジ検出の実行方法について詳しく説明しました。

OpenCV では、Canny エッジ検出を実装する関数 cv2.Canny() が提供されています。

1. Canny エッジ検出の基礎:

Canny エッジ検出は主に次のステップに分かれています。

  • ステップ 1: ノイズ除去。ノイズはエッジ検出の精度に影響を与えるため、最初にノイズを除去する必要があります。
  • ステップ 2: 勾配の大きさと方向を計算します。
  • ステップ 3: 非最大抑制。つまり、エッジを適切に薄くします。
  • ステップ 4: エッジを決定します。最終的なエッジ情報は、二重閾値アルゴリズムを使用して決定されます。

異議申し立ての手順を簡単に説明します。

1. ガウス フィルタリングを適用して画像ノイズを除去します。

画像のエッジはノイズの影響を非常に受けやすいため、誤ったエッジ情報の検出を避けるために、通常は画像をフィルタリングしてノイズを除去する必要があります。フィルタリングの目的は、テクスチャの弱い一部の非エッジ領域を滑らかにして、より正確なエッジを取得し、エッジとして判断されるのを避けることです。実際の処理では、通常、画像内のノイズを除去するためにガウス フィルタリングが使用されます。

画像-20211102155727078

上の図は、ガウス フィルター T を使用して元のイメージ O 内のイメージ値 226 のピクセルをフィルター処理し、フィルター処理された結果イメージ内の D の値を取得する方法を示しています。

フィルタリング処理では、フィルタオブジェクトのピクセルの周囲のピクセルの加重平均値を計算して、最終的なフィルタリング結果を取得します。ガウス フィルター T の場合、中心点に近づくほど重み値が大きくなります。ピクセル値 226 の画像 O のピクセルの計算プロセスとフィルター T によるフィルター処理の結果は次のとおりです。

画像-20211102160004938

ガウス フィルター (ガウス カーネル) は固定されていません。たとえば、次のような場合もあります。

画像-20211102160038258

フィルターのサイズも可変であり、ガウス カーネルのサイズはエッジ検出の効果において重要な役割を果たします。フィルターのカーネルが大きくなるほど、エッジ情報のノイズに対する感度が低くなりますただし、カーネルが大きくなると、エッジ検出の位置推定エラーが大きくなります。一般に、ほとんどの場合は 5×5 コアで十分です。

2. 勾配を計算する

前の画像勾配では、画像勾配の大きさを計算する方法を紹介しました。ここでは、エッジの方向に対して垂直なグラデーションの方向に焦点を当てます。(エッジに垂直なグラデーション方向)

画像-20211102160207612

エッジ検出オペレーターは、水平方向に Gx を、垂直方向に Gy を返します。勾配の大きさ G と方向 θ (角度値で表される) は次のとおりです。

画像-20211102160403963

ここで、atan2(・) は 2 つのパラメーターを持つ arctan 関数を表します。

グラデーションの方向は常にエッジに対して垂直であり、通常、最も近い値は水平 (左、右)、垂直 (上、下)、斜め (右上、左上、左下、右下)、その他の 8 方向です。異なる方向。

したがって、勾配を計算すると、勾配の大きさと角度 (勾配の方向を表す) の 2 つの値が得られます。

勾配の表記を以下に示します。その中で、各勾配には大きさと方向の 2 つの異なる値が含まれています。観察しやすいように、ここでは視覚的な表現方法を使用します。たとえば、左上隅の値「2↑」は実際には 2 進数のペア「(2, 90)」を表しており、エシュロンの大きさが 2 で角度が 90°であることを意味します。

画像-20211102160526612

3. 非最大抑制

グラデーションの大きさと方向を取得した後、画像内のピクセルを走査し、エッジ以外の点をすべて削除します。具体的な実装では、ピクセルを 1 つずつ走査し、現在のピクセルが周囲のピクセルの中で同じ勾配方向の最大値であるかどうかを判断し、その判断結果に応じてこの点を抑制するかどうかを決定します。上記の説明から、このステップがエッジ洗練のプロセスであることがわかります。各ピクセルについて:

  • 点が正/負の勾配方向の極大値である場合、その点を保持します。
  • そうでない場合は、ポイントを抑制します (ゼロに戻ります)。

下の図では、3 つの点 A、B、C は同じ方向を向いています (グラデーションの方向はエッジに対して垂直です)。3 つの点がそれぞれの極大値であるかどうかを判断します。極大値である場合はその点を保持し、そうでない場合は点を抑制します (ゼロに戻ります)。

画像-20211102160711241

比較と判定の結果、点 A が最大のローカル値を持つことがわかります。そのため、点 A (エッジと呼ばれます) は保持され、他の 2 つの点 (B と C) は抑制されます (ゼロに戻されます)。

下の画像では、背景が黒い点はすべて上方向の勾配 (水平エッジ) の極大値です。したがって、これらの点は保持され、残りは抑制されます (0 として扱われます)。つまり、背景が黒い点は最終的にエッジ点として処理され、その他の点は非エッジ点として処理されます。

画像-20211102160932347

「正\負のグラデーション方向」とは、反対方向のグラデーション方向を指します。たとえば、上の画像では、黒い背景のピクセルはすべて、垂直勾配 (上または下) の方向 (つまり、水平エッジ) の極大値です。これらの点は最終的にエッジ点として処理されます。

上記の処理の後、基本的に同じ方向のいくつかのエッジ点のうちの 1 つだけが保持され、エッジ リファインメントの目的が達成されます。

4. 二重しきい値処理を適用してエッジを識別します。

上記の手順を完了すると、取得したターゲット エッジ画像には画像の強いエッジがすでに得られています。ただし、一部のゴースト エッジがエッジ イメージ内に存在する場合もあります。これらの仮想エッジは、実際の画像またはノイズによって生成される場合があります。後者については、それをノックアウトする必要があります。

2 つのしきい値を設定します。1 つは高しきい値 maxVal、もう 1 つは下限しきい値 minVal です。現在のエッジ画素の勾配値(勾配の大きさを指す、以下同じ)と2つの閾値との関係に応じて、エッジの属性を判定する。具体的な手順は次のとおりです。

  • 現在のエッジ ピクセルの勾配値が maxVal 以上である場合、現在のエッジ ピクセルは強いエッジとしてマークされます。
  • 現在のエッジ ピクセルの勾配値が maxVal と minVal の間にある場合、現在のエッジ ピクセルを仮想エッジ (予約) としてマークします。
  • 現在のエッジ ピクセルの勾配値が minVal 以下の場合、現在のエッジ ピクセルは抑制されます。

上記のプロセスで仮想エッジが得られますが、これはさらに処理する必要があります。一般に、仮想エッジが強いエッジに接続されているかどうかを判断することで、仮想エッジがどの状況に属するかが判断される。通常、仮想エッジの場合:

  • 強いエッジに接続されている場合は、そのエッジをエッジとして扱います。
  • 強いエッジとの接続がない場合、そのエッジは弱いエッジとして扱われ、抑制されます。

下図の左図は3つのエッジ情報を示し、右図はエッジ情報の分類の模式図であり、具体的な区分は以下の通りです。

  • 点 A の勾配値は maxVal より大きいため、A は強いエッジです。
  • 点 B と C の勾配値は maxVal と maxVal の間にあるため、B と C は仮想エッジです。
  • 点 D の勾配値が minVal 未満であるため、D は抑制されます (放棄されます)。

画像-20211102161547147

仮想エッジ B および C の処理の場合:

  • 点 B の勾配値は、仮想エッジである maxVal と minVal の間にありますが、この点は強いエッジに接続されていないため、破棄されます。
  • 点 C の勾配値は、仮想エッジである maxVal と minVal の間にありますが、この点は強いエッジ A に接続されているため、保持されます。

画像-20211102161705258

注:高しきい値 maxVal と低しきい値 minVal は固定されていないため、さまざまな画像に対して定義する必要があります。

2.キャニー機能の使用:

OpenCV は、Canny エッジ検出を実装する関数 cv2.Canny() を提供します。その構文は次のとおりです。

エッジ = cv2.Canny(画像, しきい値 1, しきい値 2[, spertureSize[, L2gradient]])

  • エッジ: 計算されたエッジ画像

  • 画像: 入​​力 8 ビット画像

  • Threshold1: 処理中の最初のしきい値を示します。

  • Threshold2: 処理中の 2 番目のしきい値を示します

  • apertureSize: Sobel オペレーターの絞りサイズを示します。

  • L2gradient:画像の勾配の大きさ(勾配の大きさ)を計算するためのロゴ。デフォルト値は False です。True の場合、計算にはより正確な L2 ノルム (つまり、2 方向の導関数の二乗和と平方根) を使用します。それ以外の場合は、L1 ノルム (次の絶対値を直接加算します) を使用します。 2 つの方向微分)

    画像-20211102162050473

例:

import cv2

img = cv2.imread('../boat.512.tiff')
rst1 = cv2.Canny(img, 120, 200)
rst2 = cv2.Canny(img, 32, 128)
cv2.imshow('img', img)
cv2.imshow('rst1', rst1)
cv2.imshow('rst2', rst2)
cv2.waitKey()
cv2.destroyAllWindows()

画像-20211102162538397

おすすめ

転載: blog.csdn.net/weixin_57440207/article/details/122647006
おすすめ