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

11장. Canny 와 Edge 비교

좋은 경계 검출의 조건

색칠 공부 책의 밑그림을 그리는 사람에게 세 가지를 부탁한다고 해 봅시다. 사과의 테두리를 빠뜨리지 말 것, 사과가 없는 곳에 쓸데없는 선을 긋지 말 것, 그리고 선을 실제 테두리 자리에 한 줄로만 그을 것. 하나라도 어기면 아이가 색칠하기 어려운 밑그림이 됩니다.

좋은 경계 검출의 세 조건인 잘 찾기, 제자리에, 한 번만을 나란히 놓은 비교 그림

그림의 세 상자가 존 캐니가 1986년 논문에서 세운 세 가지 기준입니다. 초록 상자의 "잘 찾기"는 진짜 경계를 빠뜨리지 않으면서 헛것도 찾지 않는 것입니다. 다홍 상자의 "제자리에"는 찾은 선이 실제 경계 위치에 놓이는 것이고, 보라 상자의 "한 번만"은 경계 하나에 선이 한 줄만 그어지는 것입니다. 여기서 밑그림을 그리는 사람이 경계 검출 방법이고, 세 가지 부탁이 세 기준입니다.

정답 경계, 빠뜨린 결과, 헛것이 많은 결과, 선이 두꺼운 결과를 나란히 놓은 그림

도형 그림으로 세 기준을 어긴 모습을 만들어 보았습니다. 맨 왼쪽은 그림을 그리면서 저장한 정답 경계입니다. 둘째 칸은 기준값을 너무 높게(100, 300) 잡아 바탕과 밝기 차이가 작은 타원과 오른쪽 아래 네모를 통째로 빠뜨렸습니다. 셋째 칸은 노이즈 낀 그림에 블러 없이 Canny 를 걸어 바탕에 헛것이 가득합니다. 넷째 칸은 Sobel 기울기 크기에 임계값만 대어 선이 몇 칸 두께로 뭉툭합니다.

세 기준 견주기

기준어기면 생기는 일밑그림에 빗대면Canny 에서 맡는 단계
잘 찾기경계를 빠뜨리거나 헛것을 찾는다테두리가 비거나 낙서가 생긴다블러(헛것 줄이기), 이력 임계값(빠뜨림 줄이기)
제자리에선이 실제 경계에서 비켜난다사과 옆에 선이 그어진다기울기 크기의 꼭대기 찾기
한 번만선이 두껍거나 두 줄이 된다테두리를 여러 번 덧그린다비최대 억제

짧은 예시

Python
import cv2

# 도형 그림과 그 정답 경계(두께 1)를 흑백으로 읽는다
gray = cv2.imread("ch11_set/shapes.png", cv2.IMREAD_GRAYSCALE)
answer = cv2.imread("ch11_set/shapes_edge.png", cv2.IMREAD_GRAYSCALE)

# Canny 로 경계를 찾는다. 50, 150 은 1차시 실습 5에서 쓴 두 기준값
edges = cv2.Canny(gray, 50, 150)
print("정답 경계 칸 비율:", round(float((answer > 0).mean()), 3))
print("Canny 경계 칸 비율:", round(float((edges > 0).mean()), 3))

교안 PC 에서는 정답이 0.02, Canny 가 0.019 입니다. 경계는 그림의 2% 남짓밖에 되지 않는 가는 선이라는 것을 기억해 두세요. 이 사실이 뒤에서 성능을 잴 때 중요한 실마리가 됩니다.

주의할 점

  • 세 기준은 서로 당깁니다. 빠뜨리지 않으려고 기준을 낮추면 헛것이 늘고, 헛것을 줄이려고 높이면 약한 경계를 빠뜨립니다. 한쪽만 보고 고르지 않습니다.
  • "경계 칸 비율"이 정답과 비슷하다고 잘 찾은 것은 아닙니다. 엉뚱한 자리에 같은 수의 칸을 찾아도 비율은 같습니다. 자리까지 견주는 법은 "성능을 숫자로 재기" 절에서 배웁니다.
← 이전 절11장 · 용어 짚고 가기다음 절 →11장 · Canny 의 네 단계 한눈에