모폴로지(Morphology)

모폴로지는 형태학적인 측면에서 이미지를 다루는 기법을 말한다. 다양한 영상 처리 시스템에서 전처리 (Pre-processing) 또는 후처리(Post-processing) 형태로 사용한다. 모폴로지 연산의 예를 들자면,이진화 된 이미지에서 노이즈를 제거하거나, 구멍을 채운다거나, 끊어진 선을 이어 붙일 때 등에 사용될 수 있다.

이 포스팅에서는 침식팽창 그리고 열기닫기 연산에 대해서 알아볼텐데, 이러한 연산들을 수행하기 위해서는 우선 구조적 요소에 대해서 알아야 한다.

구조적 요소 (Structuring element)

구조적 요소란 원본 이미지에 적용되는 커널(Kernel)이라고 할 수 있는데, 이 구조적 요소가 이미지내 서브픽셀들에 일치하는지 일치하지 않는지를 계산하게 된다. 영상처리에서 구조적요소는 커널, 마스크, 윈도우 모두 같은 의미로 사용된다. 일반적으로 3*3 배열을 사용하지만, 다양한 형태로 지정할 수 있다.

구조적 요소 함수를 통해 다음과 같이 3*3 커널을 만들수 있다.

val kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_RECT, Size(3.0, 3.0))

침식(Erosion)

침식은 이미지의 모든 픽셀을 스캔하며 구조적 요소와 완전히 일치하는 픽셀에 대해 마킹을 하는 기법을 의미 한다. 이렇게 연산한 결과는 객체의 테두리가 깎이는 효과가 있다. 다음 영상을 확인하자.

OpenCV에서는 이러한 침식 연산을 erode라는 함수로 제공한다.

Imgproc.erode(
   Mat src, Mat dst, 
   Mat kernel, Point anchor, 
   int iterations, int borderType, Scalar borderValue
)
src : 입력 영상
dst : 출력 영상
kernel : 구조적 요소, 빈 Mat()를 넣으면 3*3이 기본값으로 설정
anchor : 고정점 위치
iterations : 반복 횟수, 기본값 1
borderType : 가장자리 픽셀 확장 방식. 기본값 BORDER_CONSTANT
borderValue : 확장된 가장자리 픽셀을 채울 값 

쌀알 이미지에 단계적으로 침식연산을 적용한 결과는 다음과 같다.

팽창(Dilation)

팽창은 이미지의 모든 픽셀을 스캔하며 구조적 요소와 한 픽셀이라도 일치하는 픽셀에 대해 마킹을 하는 기법을 의미 한다. 이렇게 연산한 결과는 객체의 테두리를 팽창시키는 효과가 있다. 다음 영상을 확인하자.

OpenCV에서는 이러한 팽창 연산을 dilate라는 함수로 제공한다.

Imgproc.dilate(
   Mat src, Mat dst, 
   Mat kernel, Point anchor, 
   int iterations, int borderType, Scalar borderValue
)
src : 입력 영상
dst : 출력 영상
kernel : 구조적 요소, 빈 Mat()를 넣으면 3*3이 기본값으로 설정
anchor : 고정점 위치
iterations : 반복 횟수, 기본값 1
borderType : 가장자리 픽셀 확장 방식. 기본값 BORDER_CONSTANT
borderValue : 확장된 가장자리 픽셀을 채울 값 

쌀알 이미지에 단계적으로 팽창연산을 적용한 결과는 다음과 같다.

열기(Opening)와 닫기(Closing) 연산

열기와 닫기는 특별한 것이 아니고 침색과 팽창을 조합하여 사용하는 기법을 의미 한다.

열기연산 = 침식연산 후 팽창연산
닫기연산 = 팽창연산 후 침식연산

다음의 이미지가 있다고 가정하자.

이 이미지에 열기연산과 닫기연산을 각각 적용해보면 다음과 같은 결과로 나타난다

왼쪽이 열기연산, 오른쪽이 닫기연산

범용 모폴로지 연산

OpenCV에서는 개별적인 모폴로지 연산 방법도 제공하지만 위에서 다룬 연산을 하나로 해결할 수 있는 범용적인 모폴로지 연산함수도 제공한다.

Imgproc.morphologyEx(...)

매개변수는 거의 동일하다. 다만 모폴로지 연산 플래그를 지정해야 한다.

Imgproc.MORPH_ERODE // 침식
Imgproc.MORPH_DILATE // 팽창
Imgproc.MORPH_OPEN // 열기
Imgproc.MORPH_CLOSE // 닫기

쌀알 카운팅 개선하기

이전 포스팅에서 지역 이진화레이블링을 통해 쌀알 카운팅을 시도했다.

실제로 레이블링 된 객체들 카운트를 보면 실제 쌀알보다 더 많은 쌀알이 카운팅이 되었는데, 노이즈 및 붙어 있는 쌀알들 때문이였다. 열기연산으로 가볍게 노이즈를 제거하고, 붙어있는 쌀알도 분리한 모습이다.

 

 

Buy me a coffeeBuy me a coffee
카테고리: AndroidOpenCV

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.