11장. Canny 와 Edge 비교
세 알고리즘 견주기
길에 금을 긋는 세 사람을 떠올려 봅시다. 첫째는 붓을 넓게 휘둘러 굵은 선을 긋고, 둘째는 금의 양쪽에 선을 두 줄 긋고, 셋째는 자를 대고 가는 선 한 줄을 긋습니다. 10장의 Sobel, Laplacian 과 이 장의 Canny 가 이렇게 다른 선을 남깁니다.
초록 상자의 Sobel 은 기울기 크기에 임계값 하나를 대므로 경계 둘레의 비탈까지 남아 선이 굵습니다. 다홍 상자의 Laplacian 은 두 번 뺀 값이 경계 양쪽에서 +, − 로 크게 나오므로, 10장처럼 영교차(0 을 지나는 곳)를 찾지 않고 크기에 임계값만 대면 선이 두 줄로 생기기 쉽습니다. 보라 상자의 Canny 는 비최대 억제와 이력 임계값 덕분에 한 줄입니다. 여기서 붓이 Sobel, 두 줄 긋는 사람이 Laplacian, 자를 대는 사람이 Canny 입니다.
씨앗 1111 로 노이즈(표준편차 20)를 더한 도형 그림에 세 방법을 걸었습니다. 세 방법 모두 5×5 가우시안 블러를 먼저 했습니다. Sobel 은 선이 굵고, Laplacian 은 선이 점점이 끊기고 바탕에 점이 남으며, Canny 는 가는 한 줄입니다.
세 방법 견주기
| 견줄 것 | Sobel + 임계값 | Laplacian + 임계값 | Canny |
|---|---|---|---|
| 쓰는 값 | 기울기 크기 | 두 번 뺀 값의 크기 | 깎인 기울기 크기 |
| 선 두께 | 굵다(몇 칸) | 두 줄이 되기 쉽다 | 한 줄 |
| 노이즈 | 블러를 하면 버틴다 | 가장 약하다(두 번 빼면 노이즈가 커진다) | 블러와 기준값에 따라 다르다 |
| 끊김 | 기준 하나라 약한 선이 끊긴다 | 끊기기 쉽다 | 이력 임계값이 메운다 |
| 정할 숫자 | 임계값 하나 | 임계값 하나 | 기준값 둘 |
| 속도 | 실수 계산과 NumPy 비교가 든다 | 같다 | OpenCV 함수 하나라 빠르다 |
| 쓰는 곳 | 경계의 세기 자체가 필요할 때 | 아주 가는 무늬, 초점 재기 | 물체의 테두리 선 |
짧은 예시
import cv2
import numpy as np
gray = cv2.imread("ch11_set/shapes.png", cv2.IMREAD_GRAYSCALE)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# Sobel: 10차시처럼 gx, gy 를 재고 cv2.magnitude 로 크기를 구해 100 을 넘는 칸
gx = cv2.Sobel(blur, cv2.CV_64F, 1, 0)
gy = cv2.Sobel(blur, cv2.CV_64F, 0, 1)
sobel = np.where(cv2.magnitude(gx, gy) > 100, 255, 0).astype(np.uint8)
# Laplacian: 두 번 뺀 값의 절댓값이 20 을 넘는 칸
lap = np.where(np.abs(cv2.Laplacian(blur, cv2.CV_64F)) > 20, 255, 0).astype(np.uint8)
canny = cv2.Canny(blur, 50, 150)
for name, e in [("Sobel", sobel), ("Laplacian", lap), ("Canny", canny)]:
print(f"{name:9}: 경계 칸 비율 {round(float((e > 0).mean()), 3)}")교안 PC 에서는 Sobel 0.038, Laplacian 0.008, Canny 0.015 가 나옵니다. 정답 경계(0.02)의 두 배 가까운 Sobel 은 선이 굵다는 것을 숫자로도 보여 줍니다. Laplacian 과 Canny 가 정답보다 적은 까닭은 경계를 빠뜨렸기 때문입니다. Canny 는 블러 뒤에 오른쪽 아래의 약한 네모를 놓쳤고, Laplacian 은 노이즈 없는 그림에서 기준 20 을 넘는 칸이 적어 여러 테두리가 끊겼습니다.
주의할 점
- 세 방법을 견줄 때는 블러를 똑같이 걸어야 공평합니다. 한쪽만 블러하면 블러의 효과를 방법의 차이로 잘못 읽습니다.
- Sobel 과 Laplacian 의 임계값, Canny 의 기준값을 무엇으로 잡느냐에 따라 순위가 바뀔 수 있습니다. 비교 결과에는 쓴 값을 함께 적습니다.