Program/OPEN_CV

[Open CV] 이진 영상 처리 _ 모폴로지 _ 침식과 팽창

사막여유 2022. 6. 7. 22:28
728x90

 

모폴로지 ( Morphology ) 연산이란?

 - 영상을 형태학적인 측면에서 다루는 기법
   * 영상을 다룰때 모양정보에 대한 것을 다루는 기법

 - 다양한 영상 처리 시스템에서 전처리 ( pre-processing ) 또는 후처리 ( post-processing ) 형태로 널리 사용

 - 수학적 모폴로지 ( mathematical morphology )

 

구조 요소 ( Structuring element )

 - 모폴로지 연산의 결과를 결정하는 커널, 마스크, 윈도우

 * 3x3 정방형 행렬을 정의하고 전체영상을 쭉 스캔하면서 모양정보를 조금씩 Modify 하는 연산

 

 

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

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

 - 침식 연산은 객체 외곽을 깎아내는 연산 -> 객체 크기는 감소 & 배경은 확대 

 

이름 그대로 침식이라는 것은 깍여나가는 것인데 영상에서의 침식은객체 영역이 깎여나가는 형태라고 볼수있고, OpenCV 에서는 흰색 영역을 객체라고 한다.

 

 내부 연산과정을 살펴보면 3x3 정방형 행렬을 영상 전체에 스캔 시키는데

위와같이 3x3 행렬이 객체를 만나게되면 연산을 할 수 있는데

침식은 위와같이 만나는 부분으로는 연산을 할 수가 없어 계속 스캔하다가 

Structuring element 가 객체를 전체적으로 포함되는 부분에서 가장 중앙에 있는 부분을 마킹한다.

그리고 계속 우측으로 스캔하면서 전체적으로 포함되는 부분들은 모두 마킹한다.

그렇게 Structuring element 가 모두 포함되는 구역의 중앙값들을 마킹해서 남겨놓으면 침식연산의 결과로 남게된다.

 

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

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

 - 팽창 연산은 객체 외곽을 확대시키는 연산 -> 객체 크기는 감소 & 배경은 확대

 

 

 

내부 과정을 살펴보면 Structure Element 를 스캔하다가 내부에 객체가 한픽셀이라도 들어오게되면

중앙에 마킹을 남기고 남기는 마킹들을 모아놓으면 팽창 연산의 결과가 남게된다.

 

실제 영상의 침식 연산 결과

 - 객체 영역 ( 흰색 ) 이 점점 줄어듦

 - 작은 크기의 객체 ( 잡음 ) 제거 효과

침식 1회 영상을 보게되면 영상 하단에 보이는 작은 객체들은 3x3 행렬에 의해 삭제되는 것을 볼 수 있는데조금 큰부분의 객체는 살아남은 것도 볼 수 있다. 남은 작은 객체들을 3x3 행렬로 다시 한번 침식해주게되면지워지는 것을 볼 수 있다.

 

실제 영상의 팽창 연산 결과

 - 객체 영역 ( 흰색 ) 이 점점 불어남

 - 객체 내부의 홀 ( 구멍 ) 이 채워짐

 

 

 

모폴로지 침식 연산

cv2.erode ( src, kernel, dst, anchor, iterations, borderType, borderValue )

src : 입력영상

kernel : 구조요소. getStructuringElement() 함수에 의해 생성 가능 ( None 지정시 3x3 사각형 구성요소 사용 )

dst : 출력 영상. src와 동일한 크기와 타입

anchor : 고정점. 기본값은 ( -1,-1 )

iterations : 반복 횟수. 기본값은 1.

borderType : 가장자리 픽셀 확장방식. 기본값은 cv2.BORDER_CONSTANT

borderVlaue : cv2.BORDER_CONSTANT인 경우, 확장된 가장자리 픽셀을 채울건지 

 

모폴로지 팽창 연산

cv2.dilate ( src, kernel, dst, anchor, iterations, borderType, borderValue )

src : 입력영상

kernel : 구조요소. getStructuringElement() 함수에 의해 생성 가능 ( None 지정시 3x3 사각형 구성요소 사용 )

dst : 출력 영상. src와 동일한 크기와 타입

anchor : 고정점. 기본값은 ( -1,-1 )

iterations : 반복 횟수. 기본값은 1.

borderType : 가장자리 픽셀 확장방식. 기본값은 cv2.BORDER_CONSTANT

borderVlaue : cv2.BORDER_CONSTANT인 경우, 확장된 가장자리 픽셀을 채울건지 

 

모폴로지 구조 요소 ( 커널 ) 생성

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

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

 - cv2.MORPH_RECT : 사각형모양

 - cv2.MORTH_CROSS : 십자가 모양

 - cv2.MORTH_ELLIPSE : 사각형에 내접하는 타원 

ksize : 구조 요소 크기 ( width, height ) 튜플

anchor : MORPH_CROSS 모양의 구조 요소에서 고정점 좌표
              ( -1, -1 ) 을 지정하면 구조 요소의 중앙을 고정점으로 사용

retval : 0과 1로 구성된 cv2.CV_8UC1 타입 행렬. numpy.ndarray
            ( 1의 위치가 구조 요소 모양을 결정 )

 

 

실제 회로구조 이미지를 로드하여  5x3 행렬을 만들고 침식과 팽창을 진행하면

좌: 입력영상 중앙 : 침식연산 우: 팽창연산

 

팽창 연산 결과이미지를 보면 우측 하단에는 아직 끊어져있는 부분이 보인다.

이 부분 즉, 세로 부분만 팽창을 시켜서 회로를 연결하고자 한다면

getStructuringElement 함수에서 x 방향은 1 , y 방향으로는 7픽셀씩 연산하는 행렬을 생성하여 진행한다.

 

 

위와같이 회로가 연결된 것을 볼 수 있다.

 

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

https://bit.ly/3L3avNW

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

728x90