이 글에서는 Python의 OpenCV 모듈을 활용해 이미지 형태학적(Morphological) 연산 중 하나인 침식(Erosion)과 팽창(Dilation)을 구현하는 방법을 알아봅니다.
OpenCV는 컴퓨터 비전(Computer Vision) 분야를 위해 설계된 오픈소스 라이브러리로, 원래 인텔(Intel)이 개발했습니다. BSD 오픈소스 라이선스를 따르기 때문에 누구나 자유롭게 사용할 수 있습니다.
OpenCV 설치하기
OpenCV의 기능을 사용하려면 먼저 pip를 통해 패키지를 설치해야 합니다.
sudo pip3 install opencv-python
침식(Erosion)이란 무엇이고, 어떻게 동작할까?
침식은 전경(foreground) 객체의 경계를 깎아내는 연산입니다. 이미지 속 작은 흰색 노이즈를 제거하는 데 주로 사용되며, 서로 붙어 있는 두 객체를 분리하는 용도로도 활용할 수 있습니다.
이미지로부터 커널(kernel)을 생성합니다. 커널은 행렬 형태이며, 크기는 반드시 홀수(3, 5, 7 등)여야 합니다.
이미지의 한 픽셀을 선택합니다. 이 픽셀은 커널 영역 아래의 모든 픽셀이 1일 때만 1로 유지되고, 그렇지 않으면 침식되어 제거됩니다.
그 결과 경계 근처의 모든 픽셀이 제거됩니다.
따라서 전경 객체의 두께가 점점 얇아집니다.
팽창(Dilation)이란 무엇이고, 어떻게 동작할까?
팽창은 객체의 면적을 넓히는 연산입니다. 침식은 흰색 노이즈를 효과적으로 제거하지만 그 과정에서 이미지 전체가 줄어드는 단점이 있습니다. 따라서 침식 후에 팽창을 수행하면 더욱 깔끔한 노이즈 제거 결과를 얻을 수 있습니다. 또한 팽창은 끊어진 객체의 일부를 다시 연결하는 데에도 사용됩니다.
침식과 마찬가지로 홀수 크기(3, 5, 7 등)의 커널 행렬을 생성합니다.
커널 영역 안에 하나라도 1인 픽셀이 존재하면 해당 픽셀을 1로 설정합니다.
그 결과 이미지의 흰색 영역, 즉 전경 객체의 크기가 확대됩니다.
예제 코드
import cv2
import numpy as np
input_image = cv2.imread('TP_logo.jpg', cv2.IMREAD_COLOR)
kernel = np.ones((3,3), np.uint8) # numpy로 3x3 크기의 커널 생성
# 원본 이미지로부터 침식 및 팽창 이미지 생성
erosion_image = cv2.erode(input_image, kernel, iterations=1)
dilation_image = cv2.dilate(input_image, kernel, iterations=1)
cv2.imshow('Input', input_image)
cv2.imshow('Erosion', erosion_image)
cv2.imshow('Dilation', dilation_image)
cv2.waitKey(0) # 키 입력 시 종료
실행 결과