์ด๋ฏธ์ง์์์ ๋ชจํด๋ก์ง(ํํํ)์ ๊ฐ์ฒด์ ํํ ๋ฐ ๊ตฌ์กฐ๋ฅผ ๋ถ์ํ๊ณ ์ฒ๋ฆฌํ๋ ๊ฒ์ผ๋ก ์ฃผ๋ก ๋ฐ์ด๋๋ฆฌ ์ด๋ฏธ์ง์์ ๊ฐ์ฒด์ ๊ฒฝ๊ณ๋ฅผ ์กฐ์ ํ๊ฑฐ๋, ๋ ธ์ด์ฆ๋ฅผ ์ ๊ฑฐํ๋๋ฐ ์ฌ์ฉ๋๋ฉฐ, ๊ตฌ์กฐ ์์๋ผ๋ ํน์ ํํ์ ํจ๊ป ์ฐ์ฐ์ด ์ด๋ฃจ์ด์ง๋ค.
๋ชจํด๋ก์ง๋ ์ด๋ฏธ์ง ๋ด์ ์์ ๋ ธ์ด์ฆ๋ ํน์ด์ ๋ค์ ์ ๊ฑฐํ๊ณ , ๊ฐ์ฒด์ ํํ๋ฅผ ๋๋ ทํ๊ฒ ํ๋๋ฐ ๋์์ ์ค๋ค. ๋ํ ํต๊ณํ์ ์ฐ์ฐ์ผ๋ก ์ฐพ์ง ๋ชปํ๋ ๊ฐ์ฒด๋ฅผ ์ฐพ์ ์ ์์ด ์ตํฉ์ ์ผ๋ก ๋ง์ด ํ์ฉ๋๋ค.
๊ตฌ์กฐ ์์๋ ๋ชจํด๋ก์ง ์ฐ์ฐ์ ์ํํ ๋ ์ฌ์ฉํ๋ ์์ ๋ฐ์ด๋๋ฆฌ ํ์์กฐ ์ด๋ฏธ์ง์ด๋ค.
๋ํ์ ์ผ๋ก ์ง์ฌ๊ฐํ, ์, ๋ง๋ฆ๋ชจ ๋ฑ์ ํํ๊ฐ ์๋ค. ๊ตฌ์กฐ ์์์ ํฌ๊ธฐ์ ํํ์ ๋ฐ๋ผ ๋ชจํด๋ก์ง ์ฐ์ฐ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ค.

| ์ฐ์ฐ | ์ ์ | ํน์ง |
|---|---|---|
| ์นจ์ | ์ด๋ฏธ์ง์์ ๊ตฌ์กฐ ์์๊ฐ ์์ ํ ํฌํจ๋์ง ์๋ ๋ถ๋ถ์ ์ ๊ฑฐ | - ๊ฐ์ฒด์ ๊ฒฝ๊ณ๋ฅผ ์ค์ - ์์ ๊ฐ์ฒด๋ ๋์ถ๋ถ๋ฅผ ์ ๊ฑฐ - ์ ๊ฒฝ ํฝ์ ์ ๊ฐ์ |
| ํฝ์ฐฝ | ์ด๋ฏธ์ง์ ๊ตฌ์กฐ ์์๊ฐ ๊ฒน์น๋ ๋ชจ๋ ๋ถ๋ถ์ ์ถ๊ฐ | - ๊ฐ์ฒด์ ๊ฒฝ๊ณ๋ฅผ ํ์ฅ - ์์ ํ์ด๋ ๊ตฌ๋ฉ์ ๋ฉ์ - ์ ๊ฒฝ ํฝ์ ์ ์ฆ๊ฐ |
| ์ด๋ฆผ | ์นจ์ ํ ํฝ์ฐฝ | - ๋
ธ์ด์ฆ ์ ๊ฑฐ - ์์ ๊ฐ์ฒด๋ ๋์ถ๋ถ๋ฅผ ์ ๊ฑฐ - ํฐ ๊ฐ์ฒด์ ํํ๋ ๊ฑฐ์ ๊ทธ๋๋ก ์ ์ง |
| ๋ซํ | ํฝ์ฐฝ ํ ์นจ์ | - ์์ ํ์ด๋ ๊ฐ๊ทน์ ๋ฉ์ - ๊ฐ์ฒด ๋ด๋ถ์ ์์ ๊ตฌ๋ฉ์ ์ ๊ฑฐ - ๊ฐ์ฒด์ ํํ๋ฅผ ๊ฐํ |
import cv2
import numpy as np
import matplotlib.pyplot as plt
# ์๋ณธ ํ๋ ฌ
original = np.array([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
], dtype=np.uint8)
# ๊ตฌ์กฐ ์์
SE = np.array([
[1, 1],
[1, 1]
], dtype=np.uint8)
# ์นจ์์ฐ์ฐ
erosion = cv2.erode(original, SE, iterations=1)
# ํฝ์ฐฝ์ฐ์ฐ
dilation = cv2.dilate(original, SE, iterations=1)
# ๊ฒฐ๊ณผ ํ์
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.imshow(original, cmap='gray')
plt.title('Original')
plt.subplot(1, 3, 2)
plt.imshow(erosion, cmap='gray')
plt.title('Erosion')
plt.subplot(1, 3, 3)
plt.imshow(dilation, cmap='gray')
plt.title('Dilation')
plt.tight_layout()
plt.show() 
ํฝ์ฐฝ ์ฐ์ฐ์ ๊ฒฐ๊ณผ์ ์นจ์ ์ฐ์ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋บ ๊ฒ์ผ๋ก ์ ์๋๋ฉฐ ์ด๋ฏธ์ง์ ๊ฒฝ๊ณ๋ ์ค๊ณฝ์ ๊ฐ์งํ๊ฑฐ๋ ์ธ๊ณฝ์ ๊ฐ์กฐํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
ํฝ์ฐฝ๊ณผ ์นจ์์ ์ฐจ์ด๋ ๋ฐ๊ธฐ๋ ์์, ํฝ์
๊ฐ์ ๋ณํ๋ฅผ ๋ํ๋ด๊ฒ ๋๋ ๊ฒ์ด๋ฏ๋ก ์ด ๊ฒฝ๊ณ๊ฐ์กฐ ์ฐ์ฐ์ ๊ทธ๋ ๋์ธํธ ์ฐ์ฐ์ด๋ผ ๋ถ๋ฆฐ๋ค.. (์ด์ฐ ํท๊ฐ๋ ค..)
img = cv2.imread('moon.jpg', cv2.IMREAD_GRAYSCALE)
SE = np.array([
[0, 1, 0],
[1, 1, 1],
[0, 1, 0]
], dtype=np.uint8)
erosion = cv2.erode(img, SE, iterations=1)
dilation = cv2.dilate(img, SE, iterations=1)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, SE)
# ๊ฒฐ๊ณผ ํ์
plt.figure(figsize=(16, 4))
plt.subplot(1, 4, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 4, 2)
plt.imshow(erosion, cmap='gray')
plt.title('Erosion')
plt.subplot(1, 4, 3)
plt.imshow(dilation, cmap='gray')
plt.title('Dilation')
plt.subplot(1, 4, 4)
plt.imshow(gradient, cmap='gray')
plt.title('Morphological Gradient')
plt.tight_layout()
plt.show()
์๋ณธ ์ด๋ฏธ์ง์ ์ด๋ฏธ์ง์ ํน์ ๋ชจํด๋ก์ง ์ฐ์ฐ์ ์ ์ฉํ ๊ฒฐ๊ณผ ์ฌ์ด์ ์ฐจ์ด๋ฅผ ํ์ํ๋๋ฐ ์ฌ์ฉ๋๋ฉฐ ๋ฐ๊ฑฐ๋ ์ด๋์ด ์ง์ญ์ ์์ ๋ณํ๋ ๋ ธ์ด์ฆ๋ฅผ ๊ฐ์งํ๋๋ฐ ์ ์ฉํ๋ค.
์นจ์์ฐ์ฐ ํ์ ์ด๋ฏธ์ง์ ์๋ณธ ์ด๋ฏธ์ง์์ ์ฐจ์ด๋ฅผ ๋ํ๋ ๋๋ค. ์ด ์ฐ์ฐ์ ๋ฐ์ ๋ฐฐ๊ฒฝ ์์ ์์ ์ด๋์ด ๊ฐ์ฒด๋ ๋ ธ์ด์ฆ๋ฅผ ๊ฐ์กฐํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
ํฝ์ฐฝ์ฐ์ฐ ํ์ ์ด๋ฏธ์ง์ ์๋ณธ ์ด๋ฏธ์ง์์ ์ฐจ์ด๋ฅผ ๋ํ๋ ๋๋ค. ์ด ์ฐ์ฐ์ ์ด๋์ด ๋ฐฐ๊ฒฝ ์์ ์์ ๋ฐ์ ๊ฐ์ฒด๋ ๋ ธ์ด์ฆ๋ฅผ ๊ฐ์กฐํ๋ ๋ฐ ์ฌ์ฉ๋๋ค.
img = cv2.imread('moon.jpg', cv2.IMREAD_GRAYSCALE)
SE = np.ones([9,9])
# ๋
ธ์ด์ฆ ์ถ๊ฐ
noises = 100 # ๋
ธ์ด์ฆ๋ก ์ถ๊ฐํ ์ ์ ์
for _ in range(noises):
x = np.random.randint(0, img.shape[1]) # ๋๋คํ x ์ขํ
y = np.random.randint(0, img.shape[0]) # ๋๋คํ y ์ขํ
img[y, x] = 255 # ํด๋น ์ขํ์ ํฝ์
๊ฐ์ 0 (๊ฒ์์)์ผ๋ก ๋ณ๊ฒฝ
# ํฑํ ์ฐ์ฐ
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, SE)
# ๋ธ๋ํ ์ฐ์ฐ
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, SE)
# ๊ฒฐ๊ณผ ํ์
plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original')
plt.subplot(1, 3, 2)
plt.imshow(tophat, cmap='gray')
plt.title('Top Hat')
plt.subplot(1, 3, 3)
plt.imshow(blackhat, cmap='gray')
plt.title('Black Hat')
plt.tight_layout()
plt.show()

๋ฐ์ด๋๋ฆฌ ์ด๋ฏธ์ง์์ ํน์ ํจํด์ ์ฐพ๋ ๋ฐ ์ฌ์ฉ๋๋ ์ฐ์ฐ์ผ๋ก, ๋ ๊ฐ์ ๊ตฌ์กฐ ์์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋๋ ํํธ ํ๋๋ ๋ฏธ์ค๋ฅผ ์ฐพ์ ์ฐ์ฐ์ ์ํํ๊ฒ ๋๋ค.
์ฌ๊ธฐ์ ์ ํํธ ๊ตฌ์กฐ์์, ๋ ๋ฏธ์ค ๊ตฌ์กฐ ์์, ๋ ์ด๋ฏธ์ง ์ ์ฌ์งํฉ์ ๋๋ค.
import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread('moon.jpg', cv2.IMREAD_GRAYSCALE)
# SE, 1์ ํํธ, -1์ ๋ฏธ์ค
SE = np.array([
[-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]
], dtype=np.uint8)
# ํํธ๋ฏธ์ค ์ฐ์ฐ
hitormiss = cv2.morphologyEx(image, cv2.MORPH_HITMISS, SE)
# ๊ฒฐ๊ณผ ํ์
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original')
plt.subplot(1, 2, 2)
plt.imshow(hitormiss, cmap='gray')
plt.title('Hit-or-Miss')
plt.tight_layout()
plt.show()

| ์ฐ์ฐ | ์์ | ์์ ์ค๋ช | ์ฌ์ฉ ๋ถ์ผ |
|---|---|---|---|
| ์นจ์ (Erosion) | ์๋ณธ ์ด๋ฏธ์ง ( A )์์ ๊ตฌ์กฐ ์์ ( B )๋ฅผ ๋นผ๋ ์ฐ์ฐ. | ์ด๋ฏธ์ง์ ๊ฒฝ๊ณ ์ถ์, ์์ ๋ ธ์ด์ฆ๋ ๊ฐ์ฒด ์ ๊ฑฐ. | |
| ํฝ์ฐฝ (Dilation) | ์๋ณธ ์ด๋ฏธ์ง ( A )์ ๊ตฌ์กฐ ์์ ( B )๋ฅผ ๋ํ๋ ์ฐ์ฐ. | ์ด๋ฏธ์ง์ ๊ฒฝ๊ณ ํ์ฅ, ์์ ๊ตฌ๋ฉ ์ฑ์ฐ๊ธฐ. | |
| ์ด๋ฆผ (Opening) | ์นจ์ ์ฐ์ฐ ํ ํฝ์ฐฝ ์ฐ์ฐ์ ์ ์ฉ. | ์์ ๋ ธ์ด์ฆ๋ ๊ฐ์ฒด ์ ๊ฑฐ ํ ์๋์ ํฐ ๊ฐ์ฒด ๋ณต์. | |
| ๋ซํ (Closing) | ํฝ์ฐฝ ์ฐ์ฐ ํ ์นจ์ ์ฐ์ฐ์ ์ ์ฉ. | ์์ ๊ตฌ๋ฉ ์ฑ์ฐ๊ธฐ ํ ์๋์ ํฐ ๊ฐ์ฒด์ ๊ฒฝ๊ณ ๋ณต์. | |
| ๊ทธ๋ ๋์ธํธ (Gradient) | ํฝ์ฐฝ ์ฐ์ฐ๊ณผ ์นจ์ ์ฐ์ฐ์ ์ฐจ์ด. | ์ด๋ฏธ์ง์ ๊ฒฝ๊ณ๋ ์ธ๊ณฝ์ ๊ฐ์กฐ. | |
| ํฑํ (Top-Hat) | ์๋ณธ ์ด๋ฏธ์ง์ ์ด๋ฆผ ์ฐ์ฐ ๊ฒฐ๊ณผ์ ์ฐจ์ด. | ๋ฐ์ ๋ฐฐ๊ฒฝ ์์ ์์ ์ด๋์ด ๊ฐ์ฒด๋ ๋ ธ์ด์ฆ ๊ฐ์กฐ. | |
| ๋ธ๋ํ (Black-Hat) | ์๋ณธ ์ด๋ฏธ์ง์ ๋ซํ ์ฐ์ฐ ๊ฒฐ๊ณผ์ ์ฐจ์ด. | ์ด๋์ด ๋ฐฐ๊ฒฝ ์์ ์์ ๋ฐ์ ๊ฐ์ฒด๋ ๋ ธ์ด์ฆ ๊ฐ์กฐ. | |
| ํํธ๋ฏธ์ค (Hit-or-Miss) | ์๋ณธ ์ด๋ฏธ์ง์์ "ํํธ" ํจํด์ ํด๋นํ๋ ๋ถ๋ถ๊ณผ "๋ฏธ์ค" ํจํด์ ํด๋นํ์ง ์๋ ๋ถ๋ถ์ ์ฐพ๋ ์ฐ์ฐ. | ๋ฐ์ด๋๋ฆฌ ์ด๋ฏธ์ง์์ ํน์ ํจํด์ ์์น๋ฅผ ์ฐพ๋ ๋ฐ ์ฌ์ฉ. |