ソーベル vs キャニー エッジ検出器

テスト画像をロボットビジョンの背後にある完全なエッジ検出パイプライン — グレースケール、ガウシアンぼかし、ソーベル勾配、非極大抑制、キャニーヒステリシス — に通し、各ステップにカーソルを合わせて1つのピクセルの背後にある数式を確認しよう。

インタラクティブシミュレーションを読み込んでいます...

なぜ先にぼかすのか、なぜしきい値が2つ必要なのか 🖖

微分演算は、入力に含まれる変化をノイズもろとも増幅する。未処理の画像をそのまま微分すると、わずか一画素の濃度変動までエッジのように現れてしまう。そこで先にガウス関数との畳み込みを行うと(ステップ2)、本物のエッジに当たる大きな濃度変化はほぼ保ったまま、ノイズを平均化して除ける。実用的な勾配ベースの検出器が、微分の前に必ず平滑化を行うのはこのためである。ソーベルカーネルは、偏微分 ∂I/∂x と ∂I/∂y の変数分離可能な近似になっている。微分方向と直交する軸には 1-2-1 の重みを付け、中央の行または列を推定に強く反映させる。こうして得た勾配の大きさにしきい値を一つだけ設けると、無理な選択を迫られる。低くすれば出力にノイズの斑点が現れ、高くすればコントラストの弱いエッジが途切れて破線状になる。ヒステリシス処理(ステップ6)は、一つではなく二つのしきい値を使って、この問題を避ける。高しきい値(Thigh)では、確実性の高いエッジを検出する。低しきい値(Tlow)を適用するのは、すでに強いエッジに接している画素だけである。これにより、本物の輪郭は一時的に薄くなる区間でも途切れず、ノイズが新たな輪郭の起点になることはない。単一のしきい値では判定がちらつく場面で、領域拡張法によるセグメンテーションやシュミットトリガー回路にも用いられている、同じ二重しきい値の考え方である。

一枚の画像への二つの問い 🖖

ソーベルとキャニーは同じ画像に異なる問いを投げかける。ソーベルは勾配マップを作り、各ピクセルにそこで明るさがどれだけ急に変化するかの数値を与えるため、境界は太くグレースケールの、柔らかな光のように現れる。キャニーは同じ勾配から決断を迫る——非極大抑制は各尾根の幅方向で最も明るいピクセルだけを残し、その光を鋭い1ピクセル幅の線へと細線化し、それをエッジか否かに分類する。勾配タブとキャニータブを切り替えれば、ぼやけたマップが澄んだ輪郭へと崩れていく様子が見える。

キャニーのエッジに潜む本質的なトレードオフ 🖖

ジョン・キャニーは手探りでレシピにたどり着いたのではない。1986年の論文で彼はエッジ検出を三つの目標——本物のエッジを検出し、正確に位置を定め、エッジごとに一度だけ反応する——を持つ最適化問題として定式化し、変分法で解いた。その解はほぼ正確にガウス関数の一階微分となり、だからこそ本ツールの各ステップはあの平滑化に支えられている。彼が併せて証明した落とし穴は、ぼかしを広げるほど検出と位置特定が互いに引き合う点だ——σを大きくすると微弱なエッジは見つかるが位置がぼやけ、両方で最良となるσは存在しない。σを動かして確かめよう。

全プロセスの詳細解説

  1. チェッカーボードのテスト画像のピクセル (31, 3) における勾配強度 9 ステップ

    チェッカーボードのテスト画像 — 純粋な黒と白、正方形の幅 32 ピクセル — において、3×3 のぼかしカーネル、σ = 1.0、Tlo = 30、Thi = 80 とします。最初の垂直境界の直前にある最後の白列のピクセル (31, 3) における勾配強度を導出し、それが属するエッジが何ピクセル幅になるかを求めてください。

    1. まずグレースケール化を行いますが、この画像では何も変化しません。3 つの重みの合計はちょうど 1 になるため、赤・緑・青の値が等しいピクセルは元の値を保持します。白は 255 のまま、黒は 0 のままであり、以下に示す数値はすべてこの 2 つの値のみから導かれます。

    2. ガウス重みは距離の 2 乗に伴って減少します。σ = 1 のとき、中心は 1、辺を共有する 4 ピクセルは e-0.5 = 0.6065、4 つの角は e-1 = 0.3679 となります。合計の 4.8976 で全体を割ることで、これらは加重平均となります。

    3. 行 3 は水平な帯の充分内側に位置するため、そこにある任意のウィンドウの 3 行は同一であり、カーネルの垂直構造は相殺されます。重要となるのは列の合計のみであり、それはわずか 2 つしかありません。

    4. 境界をまたぐぼかしを考えます。x = 31 では、ウィンドウは白 2 列と黒 1 列を覆います。x = 32 では、白 1 列と黒 2 列を覆います。255 から 0 への急激な変化は、255, 185, 70, 0 という階段状の変化(ランプ)になります。丸められたこれらの中央の 2 つの値が、インスペクタに表示される値です。

    5. Sobelフィルタは左列に -1, -2, -1、右列に +1, +2, +1 の重みをかけ、中央列には何もかけません。3 つの行がすべて等しいため、これらの重みは単純に 4 という 1 つの係数にまとまります。したがって、畳み込み全体は両側の列の差の 4 倍になります。

    6. 垂直方向の勾配は、左右対称な理由から消滅します。ピクセルの上の行と下の行は同じ 3 つの数値であるため、+1, +2, +1 の和と -1, -2, -1 の和が項ごとに打ち消し合います。このエッジの勾配は完全に水平方向のみであり、これにより次のステップが容易になります。

    7. 2 つを合成すると、強度(マグニチュード)は単純に水平方向のものと一致します。

    8. ぼかしを行わない場合に同じエッジが得られる結果と比較してみます。同じカーネル全体で 255 の単純な段差が生じます。平滑化によって 280 カウント、利用可能な応答の 27% をわずかに超える分が失われていますが、これはノイズ耐性のための代償であり、丸め誤差ではなく意図的なトレードオフです。

    9. 次に、右に 1 列移動して同様に計算します。x = 32 では、ウィンドウの値は 185, 70, 0 となるため、差は再び -185 となり、強度は再び 740 になります。さらに両側に 1 列外側へ進むと、差はおよそ -70 に落ち込み、強度は 280 に減少します。

    解答

    740 — そしてエッジの幅は 2 ピクセルになります。非極大抑制では、勾配に沿った両隣のピクセルの強度に対して、自身の強度が ≥ である場合にそのピクセルを保持します。ここでは勾配は x 方向に向いているため、ピクセル 31 は左側の 280 および右側の 740 と比較され、ピクセル 32 は 740 および 280 と比較されます。両者は互いに同点となり、同点は ≥ の条件を満たすため、両方が生存します。740 という値は Thi = 80 の 9 倍を超えているため、どちらも白として出力されます。どんな閾値の組み合わせであってもこれらを分離することはできません。なぜなら閾値処理が原因ではないからです。本当の境界は x = 31.5、すなわち最後の白ピクセルと最初の黒ピクセルのちょうど中間に存在し、対称的なぼかしによって勾配はその半整数に関して対称に保たれます — 探すべき単一の極大値が存在しないのです。パラメータ調整を行う前にこの点を知っておく価値があります。エッジマップにおける二重線は、閾値処理の失敗による場合もあれば計算上の理由による場合もあり、ここでは正方形の幅がたまたま整数ピクセルである画像での 740 = 740 に起因しています。

参考文献 (1)

例題

  • きれいな図形 - 初期状態では、Cannyタブで σ = 1.4、しきい値は 30 と 80。単純な幾何図形では、一画素幅の輪郭が最も線画らしく見える。
  • チェッカーボードの勾配 - 勾配マップで処理を止める唯一のプリセット。判定結果ではなく、太い灰色の光彩が表示される。例題と同じ設定で、σ = 1.0、Tlo = 30、Thi = 80。
  • 回路パターン - σ = 0.8。ここでは最もぼかしが弱く、細い銅配線を保てる。しきい値は「顔」と同じなので、両者の違いは σ だけである。
  • 平滑化した顔 - σ = 2.5、カーネルは 5×5。同じしきい値の「回路基板」と比べ、ぼかしは三倍。細かな質感は消えて構造が残るが、エッジの位置もその分ぼやける。