Python과 OpenCV – 12 : Morphological Transformations

이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops 입니다.

Morphological Transformations, 즉 형태변환은 흑과 백으로 구성된 바이너리 이미지에 대해 수행되는 연산으로 이미지가 나타내는 형태에 대한 변환을 발생시킵니다. 변환의 종류에는 Erosion(침식), Dilation(확장), Opening, Closing 등이 있습니다.

변환 종류별로 하나씩 살펴보겠습니다.

먼저 Erosion에 대한 예제입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/j.png', 0)
kernel = np.ones((6,6), np.uint8)
result = cv2.erode(img,kernel, iterations=1)

plt.subplot(121),plt.imshow(img, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result, cmap='gray'),plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 아래와 같습니다.

다음은 Dilation에 대한 예제입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/j.png', 0)
kernel = np.ones((7,7), np.uint8) 
result = cv2.dilate(img,kernel, iterations=1)

plt.subplot(121),plt.imshow(img, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result, cmap='gray'),plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 다음과 같습니다.

다음은 Opening 연산입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/opening.png', 0)
kernel = np.ones((6,6), np.uint8) 
result = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

plt.subplot(121),plt.imshow(img, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result, cmap='gray'),plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 다음과 같은데, 침식 연산을 먼저 수행하고 다음에 확장 연산을 수행한 결과와 같습니다.

다음은 Closing 연산입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/closing.png', 0)
kernel = np.ones((5,5), np.uint8) 
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

plt.subplot(121),plt.imshow(img, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result, cmap='gray'),plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 다음과 같은데, 먼저 확장 연산을 수행하고 다음에 침식 연산을 수행한 결과와 같습니다.

다음은 Morphological Gradient 연산입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/j.png', 0)
kernel = np.ones((5,5), np.uint8) 
result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

plt.subplot(121),plt.imshow(img, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result, cmap='gray'),plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 다음과 같은데, 확장 연산의 결과에서 침식 연산의 결과를 빼낸 이미지와 같습니다.

다음은 Top Hat 연산입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/j.png', 0)
kernel = np.ones((9,9), np.uint8) 
result = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

plt.subplot(121),plt.imshow(img, cmap='gray'),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(result, cmap='gray'),plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 다음과 같습니다.

다음은 Black Hat 연산입니다.

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('./data/j.png', 0)
kernel = np.ones((9,9), np.uint8) 
result = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(result, cmap='gray'), plt.title('Result')
plt.xticks([]), plt.yticks([])
plt.show()

결과는 다음과 같습니다.

지금까지의 형태변환을 수행할때 사용한 커널 행렬 즉, Structuring Element는 numpy의 사각형 모양의 단위 행렬을 사용했는데.. 필요에 따라 원이나 십자가, 타원 모양의 행렬도 생성하여 형태변환을 수행할 수 있습니다. 아래의 예제는 이러한 다양한 Structuring Element를 생성하는 예제입니다.

import cv2

print(cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)))
print()

print(cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)))
print()

print(cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)))

위는 모두 5×5 행렬 3개를 생성하고 있는데, 각각의 결과는 다음과 같습니다.


[[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]]

[[0 0 1 0 0]
[1 1 1 1 1]
[1 1 1 1 1]
[1 1 1 1 1]
[0 0 1 0 0]]

[[0 0 1 0 0]
[0 0 1 0 0]
[1 1 1 1 1]
[0 0 1 0 0]
[0 0 1 0 0]]

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다