본문 바로가기
AI, 논문, 데이터 분석

[OpenCV] Morphology (침식 / 팽창 / 열림과 닫힘)

by doraemin_dev 2025. 1. 22.

모폴리지(morphology)

영상 처리에서 형태학(모폴로지)

  • 영상의 객체들의 형태(shape)를 분석하고 처리하는 기법
  • 영상의 경계, 골격, 블록 등의 형태를 표현하는데 필요한 요소 추출
  • 영상 내에 존재하는 객체의 형태를 조금씩 변형시킴으로써 영상 내에서 불필요한 잡음 제거하거나 객체를 뚜렷하게 함

침식연산

  • 객체의 크기 축소 및 배경 확장
  • 영상 내에 존재하는 잡음 같은 작은 크기의 객체 제거 가능
  • 소금-후추 잡음과 같은 임펄스 잡음 제거

 

 

 

[실습]

이진화(binary)만으로는 잡음을 충분히 제거할 수 없지만, 침식을 추가로 사용하면, 더 효과적으로 노이즈를 제거할 수 있습니다.

import numpy as np, cv2


image = cv2.imread("chap07/images/morph.jpg", cv2.IMREAD_GRAYSCALE)
if image is None: raise Exception("영상파일 읽기 오류")

data = [0, 1, 0,                                               # 마스크 선언 및 초기화
        1, 1, 1,
        0, 1, 0]

mask = np.array(data, np.uint8).reshape(3, 3)
th_img = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)[1]
dst2 = cv2.erode(th_img, mask)
# dst2 = cv2.morphologyEx(th_img, cv2.MORPH_ERODE, mask)         # OpenCV의 침식 함수

cv2.imshow("image", image)
cv2.imshow("binary image", th_img)
cv2.imshow("OpenCV erode", dst2)
cv2.waitKey(0)

팽창 연산

  • 객체의 최외곽 화소를 확장시키는 기능
    → 객체 크기 확대, 배경 축소
  • 객체 팽창으로 객체 내부의 빈 공간도 메워짐
    → 객체 내부 잡음 제거

 

[실습]

import numpy as np, cv2


image = cv2.imread("chap07/images/morph.jpg", cv2.IMREAD_GRAYSCALE)
if image is None: raise Exception("영상파일 읽기 오류")

mask = np.array([[0, 1, 0],                         # 마스크 초기화
                 [1, 1, 1],
                 [0, 1, 0]]).astype("uint8")

th_img = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)[1]
dst2 = cv2.morphologyEx(th_img, cv2.MORPH_DILATE, mask)
# dst2 = cv2.dilate(th_img, mask)

cv2.imshow("OpenCV dilate", dst2)
cv2.waitKey(0)

열림 연산과 닫힘 연산

침식 연산과 팽창 연산의 순서를 조합하여 수행

열림 연산: 침식 연산→ 팽창 연산

  • 침식 연산으로 인해서 객체는 축소되고, 배경 부분의 미세한 잡음 제거
  • 팽창 연산으로 인해서 축소되었던 객체들이 다시 원래 크기로

닫힘 연산 : 팽창 연산 → 침식 연산

  • 팽창 연산으로 객체가 확장되어서 객체 내부의 빈 공간이 메워짐
  • 침식 연산으로 다음으로 확장되었던 객체의 크기가 원래대로 축소

 

[실습]

import numpy as np, cv2

image = cv2.imread("chap07/images/morph.jpg", cv2.IMREAD_GRAYSCALE)
if image is None: raise Exception("영상파일 읽기 오류")

mask = np.array([[0, 1, 0],                 # 마스크 초기화
                 [1, 1, 1], 
                 [0, 1, 0]]).astype("uint8")

th_img = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)[1]   # 영상 이진화

dst1 = cv2.morphologyEx(th_img, cv2.MORPH_OPEN, mask) # OpenCV의 열림 함수
dst2 = cv2.morphologyEx(th_img, cv2.MORPH_CLOSE, mask, iterations = 1) # OpenCV의 닫힘 함수

cv2.imshow("OpenCV opening", dst1)
cv2.imshow("OpenCV closing", dst2)
cv2.waitKey(0)