[opencv-python]Erosion과 Dilation

2019. 7. 7. 06:48Python-이론/python-opencv

Erosion과 Dilation

Erosion과 Dilation은 이미지 변환 방법입니다. 

 

Eriosion은 and 연산을 통해서 가장 낮은 어두운 값을 변형시킵니다. 아래의 이미지를 보면 0, 1은 and 연산으로 0이 된다. 1, 1은 and 연산으로 1이 된다. 기존의 1의 개수가 1/2이 되어 줄어들었다. 

Dilation은 Erosion과 달리 값들을 or연산을 해주어서 팽창시킬 수 있게 할 수 있다. 

 

코드

import numpy as np
import cv2


def morph():
    img = cv2.imread("../resource/Images/nike.jpg", cv2.IMREAD_GRAYSCALE)

    kernel = np.ones((3, 3), np.uint8)

    erosion = cv2.erode(img, kernel, iterations=1)
    dilation = cv2.dilate(img, kernel, iterations=2)

    cv2.imshow("original", img)
    cv2.imshow("ersoion", erosion)
    cv2.imshow("dilation", dilation)

    cv2.waitKey(0)
    cv2.destroyAllWindows()


morph()

kernel 
1로 채워진 3*3의 배열을 커널로 만든다. 

 

cv2.erode(img, kernel, iterations)

cv2.dilate(img, kernel, iterations)

img는 이미지입니다. 

kernel은 erosion을 위한 커널입니다

iteration은 erode를 반복해서 몇 번 실행할지 적어준다. 

 

erosion의 경우 너무 많이 반복해주면 글자가 사라질 수 있고 

dilation의 경우 글자가 너무 굵어질 수 있다. 

 

결과

왼쪽은 ersoion이고 가운데는 original 오른쪽은 dilation의 결과이다. 

 

Opening과 closing

Opening과 Closing은 erosion과 dilation을 활용하여 noisy를 없앨 수 있는 방법이다. 

 

Opening: erosion을 수행한 후 dilation을 바로 적용해준다.  -> 작은 noisy를 없애는 데 사용한다.

Closing: dilation을 수행한 후 erosion을 바로 적용해줍니다. -> 전반적인 이미지가 깨끗해집니다. 

 

이러한 기능은 opencv의 morphologyEX를 사용하여 구현할 수 있습니다. 

'

이 함수에도 다양한 operation을 제공해줄 수 있습니다. 

cv2.MORPH_CLOSE: closing 연산을 진행한다. 
cv2.MORPH_OPEN: opening 연산을 진행한다. 

cv2.MORPH_BLACKHAT: closing과 원본 이미지의 차이를 보여준다. 

cv2.MORPH_TOPHAT: opening과 원본 이미지의 차이를 보여준다. 

cv2.MORPH_GRADIENT: Deliation과 erosion이미지의 차이를 보여준다. 

코드

import numpy as np
import cv2


def morph():
    img1 = cv2.imread("../resource/Images/nike.jpg", cv2.IMREAD_GRAYSCALE)

    kernel = np.ones((5, 5), np.uint8)

    gaussian = cv2.medianBlur(img1, 5)

    closing = cv2.morphologyEx(gaussian, cv2.MORPH_CLOSE, kernel)
    opening = cv2.morphologyEx(gaussian, cv2.MORPH_OPEN, kernel)
    diff = cv2.morphologyEx(gaussian, cv2.MORPH_BLACKHAT, kernel)
    diff2 = cv2.morphologyEx(gaussian, cv2.MORPH_TOPHAT, kernel)

    cv2.imshow("closing", closing)
    cv2.imshow("open", opening)
    cv2.imshow("BLACK", diff)
    cv2.imshow("TOPHAT", diff2)

    cv2.waitKey(0)
    cv2.destroyAllWindows()


morph()

 

결과

open closing
BLACK TOPHAT 순서로 되어 있다. 

추가로 Gradient를 적용하면 

아래와 같이 볼 수 있다. 

 

kernel모형에 맞게 만들어주기 

위에서 kernel를 numpy를 통해 임의로 만들어 주었습니다. opencv에서는 kernel을 모형에 맞게 만들 수 있게 제공해주고 있습니다. 

예를 들어 직사각형, 십자가, 타원

 

코드 

import numpy as np
import cv2


def makekernel():
    rect = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))

    print(rect)
    print(ellipse)
    print(cross)


makekernel()

구현 방법은 getStructuringElement를 사용하여 만들 수 있다. 

첫인자는 만들 모형이고 

두 번째 인자는 사이즈이다. 

 

출력시켜주면 아래와 같이 우리가 안 만들어 주어도 openCv의 함수를 통해 편하게 kernel을 만들 수 있다.