Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 모폴로지 - 침식과 팽창 - cv2.erode, cv2.dilate, cv2.getStructuringElement

AI 꿈나무 2020. 10. 10. 20:43
반응형

황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다.

 

예제 코드 출처 :  황선규 박사님 github홈페이지

 

『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』

예제 소스 코드는 아래 링크를 참고하세요

sunkyoo.github.io


 

 

[파이썬 OpenCV] 이진 영상 처리 - 지역 이진화 - cv2.adaptiveThreshold

황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다. 예제 코드 출처 :  황선규 박사님 github홈페이지 『OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝』 �

deep-learning-study.tistory.com

 이전 포스팅에서는 지역 이진화 방법에 대해 공부해보았습니다.

 이번에는 모폴로지에 대해 공부하겠습니다.

모폴로지 - Morphology

 모폴로지는 형태학이라는 의미를 갖고 있습니다.

 영상을 형태학적인 측면으로 접근하는 것이 모폴로지 입니다.

 모양에 대한 정보에 더 집중을 합니다.

 다양한 영상 처리 시스템에서 전처리 또는 후처리 형태로 널리 이용됩니다.

 

이진 영상

 

 구조 요소(structuring element)는 모폴로지 연산의 결과를 결정하는 커널, 마스크, 윈도우 입니다.

 모폴로지는 필터링과 비슷한 연산을 내부에서 진행합니다.

 모폴로지에서는 필터가 structucturing element 라고 합니다.

 다양한 형태가 있지만 주로 정방형 행렬(3X3)을 이용합니다.

 필터와 마찬가지로 중앙에 고정점(Anchor)이 있습니다.

 

1. 이진 영상의 침식(erosion) 연산

 구조 요소가 객체 영역 내부에 완전히 포함될 경우 고정점 픽셀을 255로 설정합니다.

 침식 연산은 객체 외각을 깍아내는 연산입니다.

 객체 크기는 감소하고 배경은 확대 됩니다.

 

침식 연산 결과

 

 객체 영역(흰색)이 점점 줄어듭니다.

 작은 크기의 객체(잡음)제거 효과가 있습니다.

 

 내부 연산은 구조 요소로 전체 영상을 스캔합니다.

 구조 요소안에 객체로 가득 찼을 시에 앵커 포인터에 마킹을 합니다.

 전체 영상을 스캐하며서 마킹을 한뒤에 마킹된 부분만 남기고 다 제거합니다.

 

2. 이진 영상의 팽창(dilation) 연산

 객체가 커지는 연산입니다.

 구조 요소와 객체 영역이 한 픽셀이라도 만날 경우 고정점 픽셀을 255로 설정합니다.

 팽창 연산은 객체 외곽을 확대시키는 연산입니다.

 객체 크기는 감소되고 배경은 확대됩니다.

  

 

 객체 영역(흰색)이 점점 커집니다.

 객체 내부의 홀(구멍)이 채워지게 됩니다.

 구조 요소 크기와 모양을 어떻게 적용하냐에 따라 다른 형태로 채워나가는 것을 확인할 수 있습니다.

 

3. 모폴로지 침식 연산 함수 - cv2.erode

 OpenCV에서 제공하는 모폴로지 침식 연산 함수를 알아보겠습니다.

 

cv2.erode(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None) -> dst

• src: 입력 영상
• kernel: 구조 요소. getStructuringElement() 함수에 의해 생성 가능. 만약 None을 지정하면 3x3 사각형 구성 요소를 사용.
• dst: 출력 영상. src와 동일한 크기와 타입
• anchor: 고정점 위치. 기본값 (-1, -1)을 사용하면 중앙점을 사용.
• iterations: 반복 횟수. 기본값은 1
• borderType: 가장자리 픽셀 확장 방식. 기본값은 cv2.BORDER_CONSTANT.
• borderValue: cv2.BORDER_CONSTANT인 경우, 확장된 가장자리 픽셀을 채울 값.

 kernel에 None을 지정하면 3x3 사각형 구성 요소를 사용합니다.

 kernel을 만드는 함수를 이용해서 만든 kernel을 입력해도 됩니다.

 iteration은 침식 연산을 얼마나 반복할 것인지에 대한 정보입니다.

 

4. 모폴로지 팽창 연산 함수 - cv2.dilate

 모폴로지 팽창 연산 함수에 대해 알아보겠습니다.

 

cv2.dilate(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None) -> dst

• src: 입력 영상
• kernel: 구조 요소. getStructuringElement() 함수에 의해 생성 가능. 만약 None을 지정하면 3x3 사각형 구성 요소를 사용.
• dst: 출력 영상. src와 동일한 크기와 타입
• anchor: 고정점 위치. 기본값 (-1, -1)을 사용하면 중앙점을 사용.
• iterations: 반복 횟수. 기본값은 1.
• borderType: 가장자리 픽셀 확장 방식. 기본값은 cv2.BORDER_CONSTANT.
• borderValue: cv2.BORDER_CONSTANT인 경우, 확장된 가장자리 픽셀을 채울 값

 사용법은 침식 연산 함수와 동일합니다.

 

5. 모폴로지 구조 요소(커널) 생성 함수 - cv2.getStructuringElement

 모폴로지 구조 요소를 생성해주는 함수가 있습니다.

 이를 이용하면 크기와 모양을 설정하고 고정점 위치도 임의대로 결정할 수 있습니다.

 

cv2.getStructuringElement(shape, ksize, anchor=None) -> retval

• shape: 구조 요소 모양을 나타내는 플래그

• ksize: 구조 요소 크기. (width, height) 튜플.
• anchor: MORPH_CROSS 모양의 구조 요소에서 고정점 좌표. (-1, -1)을 지정하면 구조 요소의 중앙을 고정점으로 사용.
• retval: 0과 1로 구성된 cv2.CV_8UC1 타입 행렬. numpy.ndarray. (1의 위치가 구조 요소 모양을 결정.)

6. 이진 영상의 침식과 팽창 예제

 예제 코드는 황선규 박사님의 깃허브를 참고했습니다. sunkyoo.github.io/opencv4cvml/

 

src = cv2.imread('circuit.bmp', cv2.IMREAD_GRAYSCALE)

if src is None:
    print('Image load failed!')
    sys.exit()

se = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3)) # 가로 5, 세로 3
dst1 = cv2.erode(src, se)

# 만약 수직선이 단선됬을 때 위아래로 연결하고 싶다.
# 그러면 1x5 커널을 생성하면 됍니다.
dst2 = cv2.dilate(src, None) # 3x3 팽창 의미는 한픽셀정도만 팽창


cv2.imshow('src', src)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
cv2.destroyAllWindows()

원본 영상

 

침식

 

팽창

 

 구조 요소의 크기와 모양에 따라 원하는 형태로 모폴로지를 할 수 있습니다.

 예를 들어 상하 수직선을 이어주고 싶다면 구조 요소의 크기를 가로 1, 세로5 설정해주면 됩니다.

 

반응형