OpenCV 비전 실무10장 · Sobel 과 Laplacian 경계 검출6 / 21← 이전목차다음 →MetaContents

10장. Sobel 과 Laplacian 경계 검출

Sobel 연산자

떡볶이 가게 세 곳의 맛을 견줄 때 한 그릇만 먹고 판단하면, 그날 따라 짜게 나온 그릇 때문에 틀릴 수 있습니다. 같은 가게에서 위아래로 이웃한 그릇까지 맛보되 가운데 그릇에 조금 더 무게를 두면 더 믿을 만합니다. Sobel 연산자가 이렇게 합니다. 가로로 빼기([-1, 0, 1])를 하되, 한 줄만 보지 않고 위·가운데·아래 세 줄을 1-2-1 무게로 섞어서 뺍니다.

![빼기 [-1, 0, 1] 과 무게 [1, 2, 1] 을 나란히 놓고, 두 줄을 곱해 Sobel 커널을 만든다는 비교 그림](assets/img/diagram/ch10_sobel_idea.svg)

왼쪽 상자가 변화량을 재는 빼기, 오른쪽 상자가 세 줄을 섞는 무게입니다. 1-2-1 은 6장의 Gaussian 필터에서 본 무게로, 살짝 흐리게 해서 노이즈 한 칸에 덜 흔들리게 합니다. 여기서 한 그릇의 맛이 한 줄의 변화량이고, 이웃 그릇까지 맛보는 일이 1-2-1 무게입니다.

Sobel 의 x 방향 커널과 y 방향 커널을 산호(빼는 칸), 연두(더하는 칸), 크림(0) 으로 칠한 3×3 표 두 개

산호 칸은 빼고, 연두 칸은 더하고, 크림 칸(0)은 쓰지 않습니다. x 방향 커널은 오른쪽 열을 더하고 왼쪽 열을 빼며, 가운데 줄에 2 를 줍니다. y 방향 커널은 같은 표를 눕힌 꼴로, 아래 줄을 더하고 위 줄을 뺍니다. 무게 1-2-1 을 세로로 세우고 빼기 -1, 0, 1 을 가로로 눕혀 칸마다 곱하면 x 방향 커널이 나옵니다(예: 둘째 줄 첫 칸 = 2 × (−1) = −2).

커널로 손계산하기

네모의 왼쪽 변(가로 60)에 걸친 3×3 이웃입니다. 위·가운데·아래 줄이 모두 50, 50, 200 입니다.

단계계산
① 왼쪽 열 × 왼쪽 무게50 × (−1) + 50 × (−2) + 50 × (−1) = −200
② 가운데 열 × 00
③ 오른쪽 열 × 오른쪽 무게200 × 1 + 200 × 2 + 200 × 1 = 800
④ 모두 더하기−200 + 0 + 800 = 600

[-1, 0, 1] 로는 150 이었는데 Sobel 은 600 입니다. 무게 1 + 2 + 1 = 4 를 곱한 만큼 커졌습니다. 값의 크기는 커널마다 다르므로, 숫자 자체보다 "경계에서 크고 고른 면에서 0"이라는 점을 봅니다.

cv2.Sobel 의 인자

순서인자이 장의 보통 값뜻
1srcimg입력 그림. 보통 흑백
2ddepthcv2.CV_64F결과의 자료형. 음수를 담으려면 소수
3dx1 또는 0가로로 몇 번 뺄까. 1 이면 가로 기울기
4dy0 또는 1세로로 몇 번 뺄까. 1 이면 세로 기울기
5ksize3커널 크기. 1, 3, 5, 7 중 하나. 기본값 3

짧은 예시

Python
import cv2

img = cv2.imread("ch10_shapes.png", cv2.IMREAD_GRAYSCALE)

gx = cv2.Sobel(img,          # src: 흑백 그림
               cv2.CV_64F,   # ddepth: 음수까지 담는 64비트 소수
               1,            # dx: 가로로 한 번 뺀다
               0,            # dy: 세로로는 빼지 않는다
               ksize=3)      # ksize: 3×3 커널
print(gx[80, 57:63].tolist())    # 결과: [0.0, 0.0, 600.0, 600.0, 0.0, 0.0] → 밝아지는 왼쪽 변
print(gx[80, 137:143].tolist())  # 결과: [0.0, 0.0, -600.0, -600.0, 0.0, 0.0] → 어두워지는 오른쪽 변

# dx=0, dy=1 이면 세로 기울기
gy = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
print(gy[37:43, 100].tolist())   # 결과: [0.0, 0.0, 600.0, 600.0, 0.0, 0.0] → 네모의 위 변

손계산의 600 이 그대로 나옵니다. 네모의 오른쪽 변은 200 에서 50 으로 어두워지므로 −600 입니다.

주의할 점

  • dx=1, dy=1 을 함께 주면 가로·세로 기울기 두 장이 나오는 것이 아니라, 가로로 빼고 다시 세로로 뺀 전혀 다른 값 한 장이 나옵니다. 두 방향이 필요하면 cv2.Sobel 을 두 번 부릅니다.
  • ksize 는 1, 3, 5, 7 처럼 홀수만 됩니다. 1 을 주면 무게 없이 [-1, 0, 1] 만 씁니다.
← 이전 절10장 · 가로 기울기와 세로 기울기다음 절 →10장 · 음수와 자료형