Edge detector

エッジとは、輝度が1方向で急激に変化する画像上の位置である。エッジ検出は基本的な画像処理操作であり、その中核をなす要素 — 画像勾配 — は、コーナー検出、オプティカルフロー、そして直接法SLAMの基盤となっている。

まずグレースケール化とスムージング

エッジ検出は(ほとんどのSLAMフロントエンド処理と同様に)グレースケール画像上で行われる。勾配計算には輝度のみが必要であり、1チャンネルは3チャンネルより3倍高速に処理でき、色は照明条件によって一貫性がない。標準的な変換は輝度公式 I=0.299R+0.587G+0.114BI = 0.299R + 0.587G + 0.114B である。

微分は雑音を増幅するため、勾配計算の前にガウシアンブラーで画像を平滑化する — これは以下のカーネルとの畳み込みである:

G(x,y)=12πσ2exp ⁣(x2+y22σ2)G(x,y) = \frac{1}{2\pi\sigma^2}\exp\!\left(-\frac{x^2+y^2}{2\sigma^2}\right)

σ\sigma の選択が検出するエッジのスケールを決める。小さい σ\sigma は細かい詳細(と雑音)を保持し、大きい σ\sigma は粗い構造だけを残す。

Sobel演算子

Sobel演算子は、2つの 3×33 \times 3 カーネルとの畳み込みによって画像勾配を計算する:

Kx=[101202101],Ky=[121000121]K_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}, \qquad K_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix}

勾配の大きさは I=(KxI)2+(KyI)2|\nabla I| = \sqrt{(K_x * I)^2 + (K_y * I)^2} であり、勾配の方向は atan2(KyI,KxI)\mathrm{atan2}(K_y * I,\, K_x * I) である。Sobelは微分(パターン [1,0,1][-1, 0, 1])とそれに垂直な方向のスムージング(重み [1,2,1][1, 2, 1])を組み合わせており、これにより単純な差分よりも雑音への耐性が高くなる。

Cannyエッジ検出器

Canny検出器は、生の勾配を細く、良く局在化されたエッジ曲線に変換する多段階アルゴリズムである:

  1. ガウシアンスムージングで雑音を抑制する。
  2. Sobel勾配(大きさと方向)を計算する。
  3. 勾配方向に沿った非最大値抑制により、リッジを1ピクセル幅に細くする。あるピクセルが残るのは、その大きさが勾配方向に沿った両隣のピクセルの大きさを超える場合に限られる。
  4. 高い閾値と低い閾値を用いたヒステリシス閾値処理: 強いエッジ(高い閾値を超えるもの)は保持され、弱いエッジ(低い閾値と高い閾値の間)は強いエッジに接続されている場合のみ保持される。これにより連続した輪郭を保持しつつ、孤立した雑音応答を排除する。
import cv2
edges = cv2.Canny(gray, threshold1=50, threshold2=150)  # low, high

両方の検出器はOpenCVでは1行で呼び出せる(cv::Sobelcv::Canny)が、畳み込みと勾配がどのように機能するかを内面化するために、一度は自前で実装してみる価値がある。

よくある落とし穴

SLAMにおける意義

Sobelによって計算される画像勾配は、ハリス構造テンソルとLucas-Kanadeオプティカルフローへの入力であり、そのためエッジ検出はSLAMフロントエンドの特徴点機構への足がかりである。エッジ自体も直接使用される。線/エッジ特徴は、テクスチャの少ない人工的な環境において点を補完する(例:PL-SLAM)。LSD-SLAMのような直接法は、測光的な位置合わせのために高勾配(エッジ的な)ピクセルに暗黙的に依存している。

関連ノート