9장. Morphology: 침식, 팽창, 열기, 닫기
크기와 횟수
사포로 나무를 다듬는 장면을 떠올려 봅시다. 거친 사포(큰 도장)로 문지르면 한 번에 많이 깎이고, 고운 사포(작은 도장)로 여러 번 문질러도 많이 깎입니다. 너무 세게 문지르면 다듬으려던 조각까지 닳아 없어집니다. 모폴로지의 세기는 도장의 크기와 되풀이 횟수(iterations) 두 가지로 정합니다.
초록 상자는 도장 크기로, 클수록 한 번에 많이 깎고 많이 부풀립니다. 다홍 상자의 횟수는 같은 연산을 몇 번 되풀이할지입니다. 보라 상자처럼 너무 세면 덩어리가 사라지거나 서로 붙어 버립니다. 여기서 거친 사포가 큰 도장, 여러 번 문지르기가 iterations 입니다.
검은 바탕에 큰 네모, 원, 굵기 2 칸의 가는 선, 작은 점 둘, 4 칸 떨어진 두 원, 고리를 그린 가상의 도형 판입니다. 윗줄의 침식에서 3×3 은 가는 선을 실처럼 가늘게 하고 작은 점을 지웁니다. 9×9 는 가는 선과 고리까지 지워 버리고 큰 도형만 작아진 채 남습니다. 아랫줄의 팽창에서 9×9 는 두 원을 하나로 붙이고, 고리의 가운데 구멍을 작게 만듭니다.
크기와 횟수를 바꾸면
| 손잡이 | 작게 하면 | 크게 하면 | 알아 둘 것 |
|---|---|---|---|
| 도장 크기 | 조금씩 손질된다 | 한 번에 많이 깎이거나 부푼다 | 3×3 에서 시작한다 |
iterations | 1 이 기본값이다 | 같은 연산을 그만큼 되풀이한다 | 3×3 네모 도장 2번은 5×5 네모 도장 1번과 결과가 같다 |
| 너무 센 침식 | - | 가는 선, 작은 물체가 사라진다 | 지킬 물체의 굵기보다 작게 |
| 너무 센 팽창 | - | 가까운 물체가 붙고 구멍이 메워진다 | 물체 사이 틈보다 작게 |
3×3 도장은 한 번에 가장자리 한 칸씩, 5×5 는 두 칸씩 깎습니다. 그래서 3×3 으로 두 번 깎으면 5×5 로 한 번 깎은 것과 같습니다. 일반적으로 크기 k 의 네모 도장은 한 번에 (k − 1) ÷ 2 칸씩 깎습니다. 9×9 면 (9 − 1) ÷ 2 = 4 칸입니다.
짧은 예시
import cv2
import numpy as np
shapes = cv2.imread("ch09_shapes.png", cv2.IMREAD_GRAYSCALE)
k3 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
k5 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
# iterations=2: 3×3 침식을 두 번 되풀이한다
twice = cv2.erode(shapes, k3, iterations=2)
once5 = cv2.erode(shapes, k5)
# array_equal: 두 배열의 모양과 모든 칸이 같으면 True
print("3×3 두 번 == 5×5 한 번:", np.array_equal(twice, once5))
# 결과: True주의할 점
- 네모가 아닌 도장(십자, 타원)은 여러 번 되풀이하면 큰 도장 한 번과 모양이 조금 다를 수 있습니다. 같다고 믿지 말고 결과를 봅니다.
- 세기를 정할 때는 약한 값(3×3, 1번)에서 시작해 결과 그림을 보며 한 단계씩 올립니다. 너무 센 값에서 시작하면 무엇이 사라졌는지 알아채기 어렵습니다.