logo

모폴로지 연산

구조화 요소를 이용한 침식·팽창·열림·닫힘

실습 준비

import cv2 as cv
from yeom import to_pil
image = cv.imread("shapes.webp")
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

_, binary = cv.threshold(
    gray,
    60,   # 임계값
    255,  # 임계값보다 밝은 픽셀에 넣을 값
    cv.THRESH_BINARY,
)
to_pil(binary)

임계값 60보다 밝은 픽셀은 흰색 처리. 흰색 영역에는 도형 17개와 배경의 작은 밝은 점이 남는다.

도형 원본과 임계값 60으로 만든 잡음이 포함된 이진 이미지

구조화 요소

모폴로지 연산(morphological operation)은 구조화 요소(structuring element)를 주변 픽셀에 적용하여 이진 객체의 형태를 바꾸는 처리. OpenCV에서는 0이 아닌 픽셀을 흰색 전경으로 취급.

kernel = cv.getStructuringElement(
    cv.MORPH_ELLIPSE,  # 모양. MORPH_RECT, MORPH_CROSS도 사용 가능
    (3, 3),            # 크기
)

kernel
실행 결과
array([[0, 1, 0],
       [1, 1, 1],
       [0, 1, 0]], dtype=uint8)

커널에서 값이 1인 중심과 상하좌우 5개 픽셀이 연산에 참여. 커널이 클수록 한 번의 연산 범위도 확대.

침식과 팽창

침식(erosion)은 커널 영역의 최솟값을 사용. 위의 십자형 커널에서는 5개 픽셀 중 하나라도 검은색(0)이면 결과도 검은색(0). 따라서 흰색 전경 축소.

E(x,y)=(i,j)KminB(x+i,y+j)
  • 객체의 바깥 경계가 안쪽으로 이동
  • 작은 흰색 점과 가는 돌출부 제거
  • 가는 연결 부분의 단절 가능

팽창(dilation)은 커널 영역의 최댓값을 사용. 위의 십자형 커널에서는 5개 픽셀 중 하나라도 흰색(1)이면 결과도 흰색(1). 따라서 흰색 전경 확대.

D(x,y)=(i,j)KmaxB(x+i,y+j)
  • 객체의 바깥 경계가 바깥쪽으로 이동
  • 작은 검은색 구멍과 끊어진 간격 축소
  • 가까운 객체의 결합 가능
eroded = cv.erode(binary, kernel)
dilated = cv.dilate(binary, kernel)

to_pil(cv.hconcat([eroded, dilated]))

이진 이미지와 3×3 침식·팽창 결과 비교

침식으로 도형과 흰색 잡음이 함께 축소. 팽창으로 도형이 굵어지고 작은 흰색 잡음도 확대.

열림과 닫힘

열림(opening)은 침식 후 팽창. 큰 객체의 크기를 대체로 복원하면서 커널보다 작은 흰색 잡음을 제거.

BK=(BK)K

닫힘(closing)은 팽창 후 침식. 객체의 크기를 대체로 복원하면서 작은 검은색 구멍과 끊긴 부분을 메우는 연산.

BK=(BK)K
opened = cv.morphologyEx(
    binary,
    cv.MORPH_OPEN,
    kernel,
)
cleaned = cv.morphologyEx(
    opened,
    cv.MORPH_CLOSE,
    kernel,
)

to_pil(cv.hconcat([opened, cleaned]))

각 단계의 검출 객체 수 비교. cv.findContours()는 이진 이미지에서 객체의 경계를 찾는 함수.

raw_contours, _ = cv.findContours(
    binary,
    cv.RETR_EXTERNAL,
    cv.CHAIN_APPROX_SIMPLE,
)
opened_contours, _ = cv.findContours(
    opened,
    cv.RETR_EXTERNAL,
    cv.CHAIN_APPROX_SIMPLE,
)
cleaned_contours, _ = cv.findContours(
    cleaned,
    cv.RETR_EXTERNAL,
    cv.CHAIN_APPROX_SIMPLE,
)
len(raw_contours) # before
실행 결과
176
len(opened_contours) # after opening
실행 결과
17
len(cleaned_contours) # after closing
실행 결과
17

잡음이 포함된 이진 이미지와 열림·닫힘 결과의 윤곽선 수 비교

이진화 직후에는 배경의 작은 밝은 점까지 객체로 잡혀 176개 검출. 열림 후 실제 도형 수인 17개로 감소. 닫힘은 도형 내부의 작은 틈을 정리하면서 17개 객체를 유지.

퀴즈

문제 1 / 6맞음: 0힌트: 0틀림: 0채점중: 0남음: 6

흰색을 전경으로 보는 이진 이미지의 침식과 팽창에 대한 설명으로 맞는 것을 모두 고르세요.

  • 침식은 흰색 객체의 경계를 안쪽으로 줄인다
  • 팽창은 작은 검은색 구멍이나 간격을 줄일 수 있다
  • 두 연산의 결과는 구조화 요소의 크기와 모양에 관계없이 항상 같다
  • 침식은 흰색 객체를 항상 원래보다 크게 만든다

퀴즈를 풀려면 대화형 기능을 불러와야 합니다.

Previous
Sobel과 Canny 경계 검출