OpenCV 비전 실무11장 · Canny 와 Edge 비교5 / 21← 이전목차다음 →MetaContents

11장. Canny 와 Edge 비교

1단계 블러와 2단계 기울기

비탈길에 자갈이 잔뜩 깔려 있으면, 발바닥으로 느끼는 기울기가 자갈 하나하나 때문에 들쭉날쭉합니다. 자갈을 고르게 쓸어 낸 뒤에야 "여기서부터 오르막"이 또렷이 느껴집니다. Canny 의 1단계 블러가 자갈을 쓸어 내는 일이고, 2단계가 비탈의 세기와 방향을 재는 일입니다.

블러, 가로·세로 기울기, 크기, 방향 네 갈래의 네 단계 흐름도

그림처럼 블러로 노이즈를 줄인 뒤 10장의 Sobel 로 가로 기울기(gx)와 세로 기울기(gy)를 재고, 두 값을 합쳐 크기를, 두 값의 비율로 방향을 구합니다. Canny 는 방향을 0도, 45도, 90도, 135도 네 갈래로 반올림해서 씁니다. 여기서 자갈이 노이즈, 비탈의 세기가 기울기 크기, 오르막 쪽이 기울기 방향입니다.

10차시에서 가져올 것

낱말10차시에서 배운 뜻Canny 에서 쓰는 곳
기울기옆 칸끼리 밝기를 뺀 값경계 후보를 찾는 재료
gx, gy가로로, 세로로 잰 기울기(cv2.Sobel)크기와 방향 계산
기울기의 크기gx 와 gy 를 합친 세기(cv2.magnitude)3·4단계에서 견주는 값
기울기의 방향밝기가 가장 가파르게 바뀌는 쪽(cv2.phase)3단계에서 어느 이웃과 견줄지 정한다
블러를 먼저 하는 까닭노이즈도 옆 칸과 차이가 커서 기울기가 크게 나온다1단계

기울기 크기 두 가지

cv2.Canny 는 크기를 두 가지로 잴 수 있습니다. gx = 30, gy = 40 인 칸으로 계산해 봅니다.

방법식계산결과
기본값(L1)\gx\+ \gy\30 + 4070
L2gradient=True√(gx² + gy²)√(900 + 1600) = √250050

L1 은 절댓값을 더하기만 해서 빠르지만 조금 크게 나옵니다. L2 는 10장의 피타고라스 크기와 같습니다.

방향을 네 갈래로 반올림하기

0도, 45도, 90도, 135도 네 갈래의 방향 구역과 각 방향에서 견줄 이웃 두 칸을 그린 그림

왼쪽 그림은 방향 0~180도를 네 구역으로 나눈 것입니다. 22.5도보다 작거나 157.5도 이상이면 0도, 22.5~67.5도면 45도, 67.5~112.5도면 90도, 112.5~157.5도면 135도로 반올림합니다. 오른쪽의 3×3 칸 네 장은 방향마다 3단계에서 견줄 이웃 두 칸(다홍)을 보여 줍니다. 0도는 왼쪽·오른쪽, 90도는 위·아래, 45도와 135도는 대각선 이웃입니다.

짧은 예시

Python
import numpy as np

# 칸 세 개의 (gx, gy) 로 방향을 구하고 네 갈래로 반올림한다
for gx, gy in [(100, 5), (60, 70), (-50, 80)]:
    # arctan2: 두 값의 비율로 각도를 구한다. degrees 로 도 단위로 바꾸고 0~180 으로 접는다
    angle = np.degrees(np.arctan2(gy, gx)) % 180   # 그림 전체라면 10차시의 cv2.phase 를 쓴다
    # 45 로 나눠 반올림하고 4 로 나눈 나머지에 45 를 곱하면 0, 45, 90, 135 가운데 하나
    rounded = int(np.round(angle / 45) % 4 * 45)
    print(f"gx={gx:4}, gy={gy:3} → {round(float(angle), 1):5}도 → {rounded}도")

교안 PC 에서는 2.9도 → 0도, 49.4도 → 45도, 122.0도 → 135도가 나옵니다. 그림의 y 축은 아래로 갈수록 커지므로, 45도는 오른쪽 아래를 가리킵니다.

주의할 점

  • 방향은 경계선의 방향이 아니라 경계선과 직각인 쪽입니다. 세로로 선 경계는 밝기가 가로로 바뀌므로 방향이 0도입니다.
  • 블러를 너무 세게 하면 약한 경계의 기울기까지 작아져 놓칩니다. 실습 4에서 블러 크기마다 견줘 봅니다.
← 이전 절11장 · Canny 의 네 단계 한눈에다음 절 →11장 · 3단계 비최대 억제