Python
[Python] openCV : Morphology
SangRok Jung
2022. 11. 17. 12:02
반응형
Morpholgy 연산
- Morpholgy란 형태 또는 모양에 관한 학문을 의미
- 영상에서의 Morpholgy는 영상에서 객체의 형태 및 구조에 대해 분석하고 처리하는 기법
- 수학적 Morpholgy라고도 함
- 그레이스케일 영상, 이진 영상 모두 적용 가능.
- 주로 이진 영상에서의 형태 변환에 사용.
- 구조 요소 이용(STRUCTURING ELEMENT).
- 다양한 형태를 가짐.
- 정방형을 주로 사용.
- 구조요소에 따라 형태가 달라짐.
- 다양한 형태를 가짐.
▶ 침식
객체 영역을 깍아 냄 → 축소
cv2.erode(img, kernel, iterations=1)
- parameter
- img : Erosion을 수행할 원본 이미지.
- kernel : Erosion을 위한 Kernel.
- iterations : Erosion 반복 횟수.
▶ 팽창
객체 영역을 덧붙임 → 확대
cv2.dilate()
- parameter
- img : dilation 수행할 원본 이미지
- kernel : dilation 위한 kerne
- iterations : dilation 반복 횟수
▶ 열기(open)
침식 + 팽창
▶ 닫기(close)
팽창 + 침식
▶ TOPHAT
원본 - opening
▶ BLACKHAT
closing - 원본
Morpholgy¶
getStructuringElement()¶
shape : element의 모양
MORPH_RECT : 사각형
MORPH_CROSS : 십자 모양
MORPH_ELLIPSE : 타원형 모양
KSIZE : STRUCTURING ELEMENT 사이즈
In [1]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/lena.jpg', cv2.IMREAD_GRAYSCALE)
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) #타원
plt.style.use("grayscale")
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(131)
ax2 = plt.subplot(132)
ax3 = plt.subplot(133)
ax1.imshow(kernal)
ax2.imshow(kernal_cross)
ax3.imshow(kernal_ellipse)
plt.show()
In [31]:
img = np.zeros(shape=(12, 12), dtype=np.uint8)
img[2:3, 5:7] = 1
img[3:8, 2:10] = 1
img[8:9, 2:5] = 1
img[8:9, 7:10] = 1
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
img2 = cv2.erode(img, kernal)
img3 = cv2.erode(img, kernal_cross)
img4 = cv2.erode(img, kernal_ellipse)
plt.style.use("grayscale")
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(141)
ax2 = plt.subplot(142)
ax3 = plt.subplot(143)
ax4 = plt.subplot(144)
ax1.imshow(img)
ax2.imshow(img2)
ax3.imshow(img3)
ax4.imshow(img4)
plt.show()
In [32]:
img = np.zeros(shape=(12, 12), dtype=np.uint8)
img[2:3, 5:7] = 1
img[3:8, 2:10] = 1
img[8:9, 2:5] = 1
img[8:9, 7:10] = 1
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
img2 = cv2.dilate(img, kernal)
img3 = cv2.dilate(img, kernal_cross)
img4 = cv2.dilate(img, kernal_ellipse)
plt.style.use("grayscale")
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(141)
ax2 = plt.subplot(142)
ax3 = plt.subplot(143)
ax4 = plt.subplot(144)
ax1.imshow(img)
ax2.imshow(img2)
ax3.imshow(img3)
ax4.imshow(img4)
plt.show()
open(열기)¶
침식 + 팽창
In [35]:
img = np.zeros(shape=(12, 12), dtype=np.uint8)
img[2:3, 5:7] = 1
img[3:8, 2:10] = 1
img[8:9, 2:5] = 1
img[8:9, 7:10] = 1
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
img2 = cv2.erode(img, kernal)
img3 = cv2.erode(img, kernal_cross)
img4 = cv2.erode(img, kernal_ellipse)
img2 = cv2.dilate(img2, kernal)
img3 = cv2.dilate(img3, kernal_cross)
img4 = cv2.dilate(img4, kernal_ellipse)
plt.style.use("grayscale")
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(141)
ax2 = plt.subplot(142)
ax3 = plt.subplot(143)
ax4 = plt.subplot(144)
ax1.imshow(img)
ax2.imshow(img2)
ax3.imshow(img3)
ax4.imshow(img4)
plt.show()
close(닫기)¶
팽창+침식
In [37]:
img = np.zeros(shape=(12, 12), dtype=np.uint8)
img[2:3, 5:7] = 1
img[3:8, 2:10] = 1
img[8:9, 2:5] = 1
img[8:9, 7:10] = 1
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
img2 = cv2.dilate(img, kernal)
img3 = cv2.dilate(img, kernal_cross)
img4 = cv2.dilate(img, kernal_ellipse)
img2 = cv2.erode(img2, kernal)
img3 = cv2.erode(img3, kernal_cross)
img4 = cv2.erode(img4, kernal_ellipse)
plt.style.use("grayscale")
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(141)
ax2 = plt.subplot(142)
ax3 = plt.subplot(143)
ax4 = plt.subplot(144)
ax1.imshow(img)
ax2.imshow(img2)
ax3.imshow(img3)
ax4.imshow(img4)
plt.show()
morphologyEx()¶
닫기, 열기, gradient, blackhat, tophat 실행 가능
In [43]:
img = np.zeros(shape=(12, 12), dtype=np.uint8)
img[2:3, 5:7] = 1
img[3:8, 2:10] = 1
img[8:9, 2:5] = 1
img[8:9, 7:10] = 1
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
close1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernal, iterations=1)
open1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernal, iterations=1)
gradient1 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernal, iterations=1)
blackhat1 = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernal, iterations=1)
tophat1 = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernal, iterations=1)
plt.style.use("grayscale")
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(231)
ax2 = plt.subplot(232)
ax3 = plt.subplot(233)
ax4 = plt.subplot(234)
ax5 = plt.subplot(235)
ax6 = plt.subplot(236)
ax1.imshow(img)
ax2.imshow(close1)
ax3.imshow(open1)
ax4.imshow(gradient1)
ax5.imshow(blackhat1)
ax6.imshow(tophat1)
plt.show()
실습 : 노이즈 제거, 노이즈 추출, 모폴로지 테두리 추출¶
In [128]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/morphology.jpg', cv2.IMREAD_GRAYSCALE)
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (30,30)) #사각형
kernal2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal3 = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
# 노이즈 제거
open1 = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernal, iterations=1)
close1_end = cv2.morphologyEx(open1, cv2.MORPH_CLOSE, kernal, iterations=1)
# 노이즈 추출ㅁ
tophat1 = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernal2, iterations=7)
blackhat1 = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernal3, iterations=1)
noise = tophat1 + blackhat1
# 모폴로지 테두리 추출
grd = cv2.morphologyEx(close1_end, cv2.MORPH_GRADIENT, kernal2, iterations=1)
plt.style.use("grayscale")
plt.figure(figsize=(12,8))
ax1 = plt.subplot(141)
ax2 = plt.subplot(142)
ax3 = plt.subplot(143)
ax4 = plt.subplot(144)
ax1.imshow(src)
ax2.imshow(close1_end)
ax3.imshow(noise)
ax4.imshow(grd)
ax1.axis('off')
ax2.axis('off')
ax3.axis('off')
ax4.axis('off')
plt.show()
방법2¶
In [119]:
src = cv2.imread('./image/morphology.jpg', cv2.IMREAD_GRAYSCALE)
kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(3,3))
closing = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel, iterations = 5)
opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel, iterations = 5)
gradient = cv2.morphologyEx(opening, cv2.MORPH_GRADIENT, kernel)
#gradient = cv2.morphologyEx(opening, cv2.MORPH_GRADIENT, kernel, iterations = 5)
tophat = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel, iterations = 5)
blackhat = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel, iterations = 5)
cv2.imshow('closing', closing)
cv2.imshow('opening', opening)
cv2.imshow('gradient', gradient)
cv2.imshow('tophat', tophat)
cv2.imshow('blackhat', blackhat)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.waitKey(1)
Out[119]:
-1
레나 영상 morphologyEx 적용¶
In [30]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('./image/lena.jpg', cv2.IMREAD_GRAYSCALE)
kernal = cv2.getStructuringElement(cv2.MORPH_RECT, (30,30)) #사각형
kernal2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) #사각형
kernal3 = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7)) #사각형
kernal_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3)) #십자
kernal_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) #타원
# 노이즈 제거
open1 = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernal, iterations=1)
close1_end = cv2.morphologyEx(open1, cv2.MORPH_CLOSE, kernal, iterations=1)
# 노이즈 추출
tophat1 = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernal2, iterations=7)
blackhat1 = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernal3, iterations=1)
noise = tophat1 + blackhat1
# 모폴로지 테두리 추출
grd = cv2.morphologyEx(close1_end, cv2.MORPH_GRADIENT, kernal2, iterations=1)
# open
open_cross = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernal_cross, iterations=7)
open_elipse = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernal_ellipse, iterations=7)
open_rect = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernal2, iterations=7)
# close
close_cross = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernal_cross, iterations=7)
close_elipse = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernal_ellipse, iterations=7)
close_rect = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernal2, iterations=7)
plt.style.use("grayscale")
plt.figure(figsize=(24,40)) #width, height
ax1 = plt.subplot(4,3,1)
ax2 = plt.subplot(4,3,2)
ax3 = plt.subplot(4,3,3)
ax4 = plt.subplot(4,3,4)
ax5 = plt.subplot(4,3,5)
ax6 = plt.subplot(4,3,6)
ax7 = plt.subplot(4,3,7)
ax8 = plt.subplot(4,3,8)
ax9 = plt.subplot(4,3,9)
ax10 = plt.subplot(4,3,10)
ax11 = plt.subplot(4,3,11)
ax12 = plt.subplot(4,3,12)
ax1.imshow(src)
ax2.imshow(close1_end)
ax3.imshow(grd)
ax4.imshow(tophat1)
ax5.imshow(blackhat1)
ax6.imshow(noise)
ax7.imshow(open_cross)
ax8.imshow(open_elipse)
ax9.imshow(open_rect)
ax10.imshow(close_cross)
ax11.imshow(close_elipse)
ax12.imshow(close_rect)
ax1.axis('off')
ax2.axis('off')
ax3.axis('off')
ax4.axis('off')
ax5.axis('off')
ax6.axis('off')
ax4.axis('off')
ax5.axis('off')
ax6.axis('off')
ax7.axis('off')
ax8.axis('off')
ax9.axis('off')
ax10.axis('off')
ax11.axis('off')
ax12.axis('off')
ax1.set_title("original")
ax2.set_title("rect 30, open")
ax3.set_title("rect 30, open -> rect 30, close")
ax4.set_title("rect 3, tophat")
ax5.set_title("rect 7, blackhat")
ax6.set_title("rect 3, tophat + rect 7, blackhat")
ax7.set_title('corss 3, open, iter=7')
ax8.set_title('elipse 3, open, iter=7')
ax9.set_title('rect 3, open, iter=7')
ax10.set_title('cross 3, close, iter=7')
ax11.set_title('elipse 3, close, iter=7')
ax12.set_title('rect 3, close, iter=7')
plt.show()
In [35]:
src = cv2.imread('./image/lena.jpg', 0)
ret, dst = cv2.threshold(src, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
i = 2 # 2 이상부터 입이 없어진다
kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(3,3))
erode = cv2.morphologyEx(dst, cv2.MORPH_ERODE, kernel, iterations = i)
dilate = cv2.morphologyEx(dst, cv2.MORPH_DILATE, kernel, iterations = i)
closing = cv2.morphologyEx(dst, cv2.MORPH_CLOSE, kernel, iterations = i)
opening = cv2.morphologyEx(closing, cv2.MORPH_OPEN, kernel, iterations = i)
gradient = cv2.morphologyEx(opening, cv2.MORPH_GRADIENT, kernel)
tophat = cv2.morphologyEx(dst, cv2.MORPH_TOPHAT, kernel, iterations = i)
blackhat = cv2.morphologyEx(dst, cv2.MORPH_BLACKHAT, kernel, iterations = i)
plt.style.use("grayscale")
plt.figure(figsize=(24,30)) #width, height
ax1 = plt.subplot(4,2,1)
ax2 = plt.subplot(4,2,2)
ax3 = plt.subplot(4,2,3)
ax4 = plt.subplot(4,2,4)
ax5 = plt.subplot(4,2,5)
ax6 = plt.subplot(4,2,6)
ax7 = plt.subplot(4,2,7)
ax1.imshow(erode)
ax2.imshow(dilate)
ax3.imshow(closing)
ax4.imshow(opening)
ax5.imshow(gradient)
ax6.imshow(tophat)
ax7.imshow(blackhat)
ax1.axis('off')
ax2.axis('off')
ax3.axis('off')
ax4.axis('off')
ax5.axis('off')
ax6.axis('off')
ax4.axis('off')
ax5.axis('off')
ax6.axis('off')
ax7.axis('off')
ax1.set_title("Erode, rect(3, 3), iter=2")
ax2.set_title("Dilate, rect(3, 3), iter=2")
ax3.set_title("Close, rect(3, 3), iter=2")
ax4.set_title("Closing -> Open, rect(3, 3), iter=2")
ax5.set_title("opening -> Gradient, rect(3, 3), iter=2")
ax6.set_title("Tophat, rect(3, 3), iter=2")
ax7.set_title('Blackhat, rect(3, 3), iter=2')
# plt.show()
# cv2.imshow('blackhat', blackhat)
# cv2.imshow('tophat', tophat)
# cv2.imshow('gradient', gradient)
# cv2.imshow('closing', closing)
# cv2.imshow('opening', opening)
# cv2.imshow('dilate', dilate)
# cv2.imshow('erode', erode)
# cv2.imshow('dst', dst)
# cv2.waitKey()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
Out[35]:
Text(0.5, 1.0, 'Blackhat, rect(3, 3), iter=2')
BlurFilter, openCV, GaussianBlur(), BILATERALFILTER(), medianBlur(), laplacian(), sobel(), magnitude(), unshapmask filter
반응형