10장. Sobel 과 Laplacian 경계 검출
경계란 무엇인가
지도의 등고선을 떠올려 봅시다. 등고선이 촘촘히 붙은 곳은 땅이 가파르게 오르는 비탈이고, 듬성듬성한 곳은 평지입니다. 등산객은 등고선이 몰린 곳을 보고 "여기서 절벽이 시작된다"고 압니다. 그림에서도 밝기가 오래 그대로이다가 한순간에 크게 바뀌는 곳이 있습니다. 그곳이 물체의 테두리, 곧 경계입니다.
왼쪽 그림의 다홍 선이 가로줄 80 이고, 오른쪽 갈색 선은 그 줄의 밝기를 왼쪽부터 차례로 그린 밝기 단면입니다. 바탕(50)에서 네모(200)로 들어가는 가로 60 에서 밝기가 한 칸 만에 50 에서 200 으로 뛰고, 네모가 끝나는 가로 140 에서 다시 50 으로 떨어집니다. 원(140)도 같은 계단을 만듭니다. 여기서 등고선이 몰린 비탈이 밝기 계단이고, 비탈의 자리가 경계입니다. 비유와 다른 점이 하나 있습니다. 산은 오르막과 내리막이 비탈의 모양으로 구별되지만, 그림의 경계는 밝아지는 쪽인지 어두워지는 쪽인지를 숫자의 부호(+, −)로 구별합니다.
경계를 찾는 까닭은 세 가지입니다. 테두리만 남겨도 네모인지 원인지 알 수 있고, 물체의 둘레를 선으로 딸 수 있고, 그 선을 다음 단계(12장의 윤곽선, 프로젝트의 차선 찾기)의 재료로 씁니다. 색이 조금 바래거나 조명이 바뀌어도 테두리의 자리는 그대로 남기 때문에 쓸모가 큽니다.
경계의 종류
| 종류 | 밝기 단면의 모양 | 그림에서 보이는 곳 |
|---|---|---|
| 계단 경계 | 한 칸 만에 뛴다 (50 → 200) | 도형의 테두리, 글자의 가장자리 |
| 비탈 경계 | 여러 칸에 걸쳐 서서히 바뀐다 | 흐린 사진의 테두리, 그림자의 끝 |
| 줄 경계 | 올랐다가 바로 내려온다 (50 → 200 → 50) | 가는 선, 도로의 차선 |
| 경계 아님 | 거의 평평하다 | 벽, 하늘, 바닥처럼 고른 면 |
짧은 예시
import cv2
# 연습용 도형 그림을 흑백으로 읽는다. OpenCV 로 그려 만든 가상의 그림이다
img = cv2.imread("ch10_shapes.png", cv2.IMREAD_GRAYSCALE)
print(img.shape) # 결과: (240, 320)
# 가로줄 80 에서 네모의 왼쪽 변(가로 60) 둘레 여덟 칸
print([int(v) for v in img[80, 56:64]]) # 결과: [50, 50, 50, 50, 200, 200, 200, 200]가로 59 까지는 50, 가로 60 부터는 200 입니다. 이 사이가 경계입니다. 사람 눈에는 네모의 테두리로 보이지만, 컴퓨터에게는 "숫자가 갑자기 뛰는 자리"일 뿐입니다.
주의할 점
- 경계는 밝기의 크기가 아니라 바뀌는 정도로 찾습니다. 밝은 네모의 한가운데는 밝기가 200 으로 크지만, 옆 칸도 200 이라 경계가 아닙니다.
- 컬러 그림은 흑백으로 바꾼 뒤 경계를 찾는 것이 보통입니다. 색은 다른데 밝기가 비슷한 두 물체 사이의 경계는 흑백에서 약해질 수 있습니다.