OpenCV 비전 실무9장 · Morphology: 침식, 팽창, 열기, 닫기5 / 21← 이전목차다음 →MetaContents

9장. Morphology: 침식, 팽창, 열기, 닫기

침식

바닷가의 모래성을 떠올려 봅시다. 파도가 한 번 밀려왔다 가면 모래성의 바깥쪽이 한 겹 깎여 나갑니다. 큰 성은 조금 작아질 뿐이지만, 옆에 쌓아 둔 모래 한 줌은 통째로 쓸려 갑니다. 침식이 바로 이 일을 합니다. 흰 덩어리의 가장자리를 한 겹 깎고, 도장보다 작은 흰 점은 아예 지웁니다.

도장 놓기, 모두 흰가, 결과 쓰기의 세 단계 흐름도

그림의 세 단계를 모든 칸에 되풀이합니다. 도장의 가운데를 지금 칸에 맞추고, 도장의 1 자리에 겹친 칸이 모두 흰색인지 보고, 모두 흰색이면 흰색, 하나라도 검정이면 검정을 씁니다. 여기서 파도가 도장이고, 파도에 닿아 깎이는 모래가 "도장 안에 검은 칸이 섞인" 흰 칸입니다.

손으로 계산해 보기

8×8 그림에 4×4 흰 네모, 네모 오른쪽에 튀어나온 한 칸, 따로 떨어진 점 하나를 두고 3×3 네모 도장으로 침식합니다.

8×8 원본과 3×3 도장으로 침식한 결과를 0 과 1 로 적은 손계산 그림

왼쪽의 다홍 테두리 두 개가 도장을 댄 자리입니다. 네모 안쪽(세로 2, 가로 2)에 댄 도장은 아홉 칸이 모두 1 이라 1 이 남습니다. 튀어나온 칸(세로 3, 가로 5)에 댄 도장 안에는 0 이 여섯 칸이나 있어 0 이 됩니다. 오른쪽 결과에는 네모 한가운데의 2×2 네 칸만 남았습니다.

도장을 댄 칸(세로, 가로)도장 안 아홉 칸 가운데 1모두 1 인가결과
(2, 2) 네모 안쪽9그렇다1
(1, 1) 네모 귀퉁이4아니다0
(3, 5) 튀어나온 칸3아니다0
(6, 6) 떨어진 점1아니다0

흰 칸이 18개에서 4개로 줄었습니다. 4×4 네모는 둘레가 한 겹 깎여 2×2 가 되고, 튀어나온 칸과 떨어진 점은 사라졌습니다.

짧은 예시

Python
import cv2
import numpy as np

img = np.zeros((8, 8), np.uint8)
img[1:5, 1:5] = 255     # 4×4 흰 네모
img[3, 5] = 255         # 오른쪽에 튀어나온 한 칸
img[6, 6] = 255         # 따로 떨어진 점
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# erode = 깎아 내다. (그림, 구조 요소)
eroded = cv2.erode(img, se)
print((eroded // 255).tolist())        # 255 를 1 로 바꿔 찍는다
print("흰 칸:", int((img == 255).sum()), "→", int((eroded == 255).sum()))
# 결과: 흰 칸 18 → 4

주의할 점

  • 침식은 흰 덩어리를 가늘게 만듭니다. 잡티만 지우고 싶어도 물체까지 한 겹 깎이므로, 실제로는 다음에 볼 팽창과 묶어(열기) 씁니다.
  • 그림 가장자리 밖의 칸을 OpenCV 의 침식은 흰색으로 쳐서 계산합니다. 그래서 가장자리에 닿은 흰 덩어리는 가장자리 쪽으로는 깎이지 않습니다.
← 이전 절9장 · 구조 요소다음 절 →9장 · 팽창