Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- dataframe
- 백준
- 자료구조
- openCV
- 파이썬
- String Method
- queue
- MySQL
- Selenium
- 정보처리기사 c언어
- Algorithm
- 가상환경
- aws jupyter notebook
- Matplotlib
- python
- 노마드코딩
- pandas
- javascript
- type hint
- 프로그래머스
- 알고리즘 스터디
- 데이터시각화
- programmers
- 알고리즘
- 코딩테스트
- NumPy
- Stack
- 알고리즘스터디
- Join
- 선그래프
Archives
- Today
- Total
조금씩 꾸준히 완성을 향해
[OpenCV/Python] 모폴로지(Morphology) 연산 - 침식(erode), 팽창(dilate), 열림(open), 닫힘(close) 본문
Python/OpenCV
[OpenCV/Python] 모폴로지(Morphology) 연산 - 침식(erode), 팽창(dilate), 열림(open), 닫힘(close)
all_sound 2022. 11. 13. 16:21# 모폴로지 연산
- Morphology : 형태 또는 모양에 관한 학문
- 모폴로지 변환의 팽창(dilation)과 침식(erosion)을 기본 연산으로 사용해 고급 형태학을 적용하는 변환 기법
- 그레이 스케일 영상, 이진영상 모두 적용 가능
- 구조 요소( Structuring Element)
- 다양한 형태를 가지지만 주로 정방형을 사용
- 구조 요소에 따라 형태가 달라짐
▶ cv2.getStrucuringElement()
- shape : element의 모양
- morph_rect 사각형
- morph_cross 십자 모양
- morph_ellipse 타원형 모양
- ksize : structuring element 사이즈
=> rectangle을 일반적으로 가장 많이 사용
# shape 확인 및 비교
kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(5,5))
kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, ksize=(5,5))
kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, ksize=(5,5))
print('-kernel rect')
print(kernel_rect)
print('-kernel cross')
print(kernel_cross )
print('-kernel ellipse')
print(kernel_ellipse)
plt.style.use('grayscale')
plt.figure(figsize=(12, 4))
ax1 = plt.subplot(131)
ax2 = plt.subplot(132)
ax3 = plt.subplot(133)
ax1.imshow(kernel_rect)
ax2.imshow(kernel_cross)
ax3.imshow(kernel_ellipse)
ax1.set_title('rectangle')
ax2.set_title('cross')
ax3.set_title('ellipse')
ax1.axis('off')
ax2.axis('off')
ax3.axis('off')
plt.show()
# 침식 (erosion)
- 객체 영역을 깎아냄 -> 축소
kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(3,3))
kernel_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, ksize=(3,3))
kernel_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, ksize=(3,3))
img = np.zeros((12,12), dtype=np.uint8)
img[3, 5:7]= 255
img[4:9, 2:10] = 255
img[8, 5:7]= 0
dst1 = cv2.erode(img, kernel_rect, iterations=1) # iterations: 횟수
dst2 = cv2.erode(img, kernel_cross, iterations=1)
dst3 = cv2.erode(img, kernel_ellipse, iterations=1)
imgs = [img, dst1, dst2, dst3]
titles = ['original', 'erode_rect', 'erode_cross', 'erode_ellipse']
plt.style.use('grayscale')
plt.figure(figsize=(15, 5))
plt.style.use('grayscale')
for i in range(4):
ax = plt.subplot(1, 4, i+1)
ax.imshow(imgs[i])
ax.set_title(titles[i])
ax.axis('off')
plt.show()
# 팽창 (dilate)
- 객체 영역을 덧붙임 -> 확대
dst1 = cv2.dilate(img, kernel_rect, iterations=1)
dst2 = cv2.dilate(img, kernel_cross, iterations=1)
dst3 = cv2.dilate(img, kernel_ellipse, iterations=1)
dst4 = cv2.dilate(img, kernel_rect, iterations=2)
dst5 = cv2.dilate(img, kernel_cross, iterations=2)
dst6 = cv2.dilate(img, kernel_ellipse, iterations=2)
imgs = [img, dst1, dst2, dst3, dst4, dst5, dst6]
titles = ['original', 'rect_iter_1', 'cross_iter_1', 'ellipse_iter_1',
'rect_iter_2', 'cross_iter_2','ellipse_iter_2']
plt.style.use('grayscale')
plt.figure(figsize=(14, 7))
for i in range(7):
ax = plt.subplot(2, 4, i+1)
ax.imshow(imgs[i])
ax.set_title(titles[i])
ax.axis('off')
# 열림 (open)
- 침식 + 팽창
dst1 = cv2.erode(img, kernel_rect, iterations=1)
dst2 = cv2.dilate(dst1, kernel_rect, iterations=1)
imgs = [img, dst1, dst2]
titles = ['original', 'erosion', 'dilate']
plt.style.use('grayscale')
plt.figure(figsize=(12, 4))
for i in range(3):
ax = plt.subplot(1, 3, i+1)
ax.axis('off')
ax.set_title(titles[i])
ax.imshow(imgs[i])
plt.show()
# 닫힘 (close)
- 팽창 + 침식
dst1 = cv2.dilate(img, kernel_rect, iterations=1)
dst2 = cv2.erode(dst1, kernel_rect, iterations=1)
imgs = [img, dst1, dst2]
titles = ['original', 'dilate', 'erosion',]
plt.style.use('grayscale')
plt.figure(figsize=(12, 4))
for i in range(3):
ax = plt.subplot(1, 3, i+1)
ax.axis('off')
ax.set_title(titles[i])
ax.imshow(imgs[i])
plt.show()
# 기타 모폴로지 연산 - 빼기 연산
- morph_gradient : 팽창-침식
- morph_tophat : 원본-열기
- morp_blackhat : 닫기-원본
erode1 = cv2.erode(img, kernel_rect, iterations=1)
dilate1 = cv2.dilate(img, kernel_rect, iterations=1)
open1 = cv2.dilate(erode1, kernel_rect, iterations=1)
close1 = cv2.erode(dilate1, kernel_rect, iterations=1)
gradient = dilate1 - erode1 #그라디언트
tophat = img - open1 #열기에서 사라진 부분 추출
blackhat = close1 - img #닫기에서 사라진 부분 추출
imgs = [gradient, tophat, blackhat]
titles = ['gradient', 'tophat', 'blackhat',]
plt.style.use('grayscale')
plt.figure(figsize=(12, 4))
for i in range(3):
ax = plt.subplot(1, 3, i+1)
ax.axis('off')
ax.set_title(titles[i])
ax.imshow(imgs[i])
plt.show()
# 함수로 구현
open1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=1)
close1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=1)
gradient1 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel, iterations=1)
tophat1 = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel, iterations=1)
blackhat1 = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel, iterations=1)
# 실습
- 다운받은 이미지를 열기, 닫기, 팽창, 침식을 적절히 활용하여 홀과 노이즈 제거
src = cv2.imread('morphology.jpg')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, ksize=(3,3))
erode = cv2.erode(src, kernel, iterations=5) # iterations 5번 반복
# 노이즈들은 제거했으나 부작용으로 홀이 커짐 (침식됨)
dilate = cv2.dilate(src, kernel, iterations=5)
# 홀은 메꾸어주나 밖에 있는 노이즈들이 커지는 부작용
# dilation + erosion
erode2 = cv2.erode(dilate, kernel, iterations=8) # iterations 8번 반복
# dilation + erosion + dilation
dilate2 = cv2.dilate(erode2, kernel, iterations = 2) # iterations 2번 반복
# 결과 확인
imgs = [src, erode, dilate, erode2, dilate2]
titles = ['src', 'erode', 'dilate', 'erode2', 'dilate2']
plt.style.use('grayscale')
plt.figure(figsize=(20, 10))
for i in range(5):
ax = plt.subplot(1, 5, i+1)
ax.axis('off')
ax.set_title(titles [i])
ax.imshow(imgs[i])
plt.show()
- 노이즈만 추출
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)
tophat = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel, iterations = 5)
blackhat = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel, iterations = 5)
imgs = [closing, opening, tophat, blackhat, tophat+blackhat]
titles = ['closing', 'opening', 'tophat', 'blackhat', 'tophat+blackhat']
plt.style.use('grayscale')
plt.figure(figsize=(20, 10))
for i in range(5):
ax = plt.subplot(1, 5, i+1)
ax.axis('off')
ax.set_title(titles [i])
ax.imshow(imgs[i])
plt.show()
- 모폴로지 테두리만 추출
gradient = cv2.morphologyEx(opening, cv2.MORPH_GRADIENT, kernel)
plt.style.use('grayscale')
plt.figure(figsize=(5, 5))
plt.axis('off')
plt.imshow(gradient)
'Python > OpenCV' 카테고리의 다른 글
[OpenCV/Python] Edge 검출 - 캐니 엣지검출기(Canny Edge Detector), 허프 변환(Hough Transform) (0) | 2022.11.15 |
---|---|
[OpenCV/Python] Labeling(라벨링) - connectedComponents, connectedComponentsWithStats (0) | 2022.11.15 |
[OpenCV/Python] Edge 필터링 (Sobel, Laplacian) (0) | 2022.11.13 |
[OpenCV/Python] 블러 필터링(Blur, GaussianBlur, Bilateral Filter, MedianBlur) (0) | 2022.11.13 |
[OpenCV/Python] 이벤트 처리 (키보드, 마우스, 트랙바) (0) | 2022.11.13 |