대학원 일기

OpenCV-모폴로지(Morphology) 연산 (침식, 팽창, 열림, 닫힘, 그래디언트, 탑햇, 블) 본문

Image processing/OpenCV

OpenCV-모폴로지(Morphology) 연산 (침식, 팽창, 열림, 닫힘, 그래디언트, 탑햇, 블)

대학원생(노예) 2022. 2. 9. 01:01

모폴로지(Morphology) 연산

모폴로지(Morphology)의 뜻은 형태학으로 영사처리에서는 영상을 형태학적 측면에서 다루는 기법이다. 이 기법은 영상의 밝은 영역이나 어두운 영역을 축소하거나 확대하는 연산을 한다. 모폴로지 연산은 노이즈나 구멍 제거, 경계를 수정하는 등의 연산에 효과적이다. 모폴로지 연산은 파이썬에서 OpenCV 라이브러리를 통해 구현할 수 있다.

 

모폴로지 연산의 종류

  • 침식(Erosion)
  • 팽창(Dilation)
  • Opening & Closing
  • Gradient
  • Tophat
  • Blackhat

침식(Erosion), 팽창(Dilation)

침식(Erosion)

기존 객체의 영역을 깎아 내는 연산으로 객체 크기가 감소한다.
- 구조 요소를 입력 영상에 적용하여 정확히 핏이 맞으면 해당 픽셀을 255로, 그 외에는 픽셀을 0으로 변경한다.

- 파이썬에서는 OpenCV 라이브러리의 erode를 통해 구현한다.

침식 연산

  침식의 연산 방법은 아래 사진과 같다.

  입력 영상(이진 영상)에 마스크(커널)를 놓을 때, 입력 영상의 영역 안에서 마스크(커널)가 겹치는 부분을 결과 영상으로 가진다.

 

 

팽창(Dilation)

기존 객체의 영역을 확장하는 연산으로 객체의 크기가 증가한다.
- 구조 요소를 입력 영상에 적용하여 겹치는 부분의 위치에서 구조  요소 크기만큼 픽셀을 255로 그 외에는 픽셀을 0으로 변경한다.

- 파이썬에서는 OpenCV 라이브러리의 dilate를 통해 구현한다.

팽창 연산

  팽창의 연산 방법은 아래 사진과 같다.

    입력 영상(이진 영상)에 마스크(커널)를 놓을 때, 입력 영상의 영역 안에서 마스크(커널)가 겹치는 부분을 결과 영상으로 가진다.

 

침식(erode), 팽창(dilate) 코드

import os 
import cv2
import numpy as np

path = os.path.join('Test_Code/j.jpg')
img = cv2.imread(path)

k = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

erosion_1 = cv2.erode(img, k)
erosion_2 = cv2.erode(erosion_1, k)
erosion_3 = cv2.erode(erosion_2, k)

dilation_1 = cv2.dilate(img, k)
dilation_2 = cv2.dilate(dilation_1, k)
dilation_3 = cv2.dilate(dilation_2, k)

merged_erosion = np.hstack((img, erosion_1, erosion_2, erosion_3))
merged_dilation = np.hstack((img, dilation_1, dilation_2, dilation_3))

cv2.imshow('Erosion', merged_erosion)
cv2.imshow('Dilation', merged_dilation)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

Opening & Closing

Opening(열림)

- Opening 연산은 침식(erode) 적용 후 팽창(dilate)을 적용하며, 흰색의 노이즈(작은 흰색 물체)를 제거하는데 사용한다.

- Opening 연산은 cv2.morphololgyEx(src, op, kernel)에서 op를 cv2.MORPH_OPEN로 주면 구현할 수 있다.

$open$ $=$ $dilate(erode(src))$

Original -> Opening 연산 적용

Opening 연산 코드

import cv2
import numpy as np
import os

from sympy import Ordinal

path = os.path.join('Test_Code/noise.png')
img = cv2.imread(path)

kernel = np.ones((5,5), np.uint8)
result = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

cv2.imshow("Original", cv2.resize(img, (500,500)))
cv2.imshow("Opening Result", cv2.resize(result, (500,500)))

cv2.waitKey(0)
cv2.destroyAllWindows()


Closing(닫힘)

- Closing 연산은 팽창(dilate) 적용 후 침식(erode)을 적용하며, 객체 안의 검은색의 노이즈를 제거하는데 사용한다.
- 회색 오브젝트에 있는 작은 검은색 구멍들을 메우는데 효과적이다.

- Closing 연산은 cv2.morphololgyEx(src, op, kernel)에서 op를 cv2.MORPH_CLOSE로 주면 구현할 수 있다.

$close$ $=$ $erode(dilate(src))$

Original
kernel = (5, 5)
kernel = (8, 8)
kernel = (11, 11)

Closing 연산 코드

import cv2
import numpy as np
import os

path = os.path.join('Test_Code/man.png')
img = cv2.imread(path)

kernel = np.ones((11,11), np.uint8)
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

cv2.imshow("Original", cv2.resize(img, (500,500)))
cv2.imshow("Closing Result", cv2.resize(result, (500,500)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

Gradient 

- Gradient 연산은 경계(edge)를 검출하는 연산이다.

- Gradient 연산은 팽창(Dilation) 연산 결과에서 침식(Erosion) 연산 결과를 빼어 결과를 얻는다.

- Gradient 연산은 밝은 영역의 가장자리를 분리하며 그레이스케일 이미지가 가장 급격하게 변하는 곳에서 가장 높은 결과를 반환한다.

- Gradient 연산은 cv2.morphololgyEx(src, op, kernel)에서 op에 cv2.MORPH_GRADIENT를 하면 된다.

$gradient$ $=$ $erode(src) - dilate(src)$

Original(Gray scale) Son
Gradeint(kernel = 3, 3) Son

 

Gradient 연산 코드

import cv2
import numpy as np
import os

path = os.path.join('Test_Code/Son.jpg')
img = cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2GRAY)

kernel = np.ones((3,3), np.uint8)
result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

cv2.imshow("Original", cv2.resize(img, (500,500)))
cv2.imshow("Gradient Result", cv2.resize(result, (500,500)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

Tophat, Blackhat

- Tophat 연산은 밝은 부분을 강조하고 Blackhat은 어두운 부분을 강조한다.

- 영상의 텍스쳐 정보 또는 윤곽선 정보를 얻을 수 있다.

- 원본 영상과 열림 연산(또는 닫힘 연산)의 결과의 차이로 Tophat(또는 Blackhat)을 얻을 수 있다.

- Tophat 연산은 cv2.morphololgyEx(src, op, kernel)에서 op에 cv2.MORPH_TOPHAT를 하면 된다.

- Blackhat 연산은 cv2.morphololgyEx(src, op, kernel)에서 op에 cv2.MORPH_BLACKHAT를 하면 된다.

Original
Tophat(kernel = 12, 12)
Blackhat(kernel = 12, 12)

좀 더 크게....

Tophat, Blackhat 연산 코드 

import cv2
import numpy as np
import os

path = os.path.join('Test_Code/Moon.jpg')
img = cv2.imread(path)

kernel = np.ones((12,12), np.uint8)
tophat_result = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
blackhat_result = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

cv2.imshow("Original", cv2.resize(img, (500,500)))
cv2.imshow("Tophat Result", cv2.resize(tophat_result, (500,500)))
cv2.imshow("Blackhat Result", cv2.resize(blackhat_result, (500,500)))

cv2.waitKey(0)
cv2.destroyAllWindows()

 

'Image processing > OpenCV' 카테고리의 다른 글

Guided Filtering  (0) 2022.03.26
Comments