[OpenCV] 모폴로지 – 열기(opening), 닫기(closing)

영상의 침식과 팽창에 대해 잘 모르신다면 여기를 참고하는 것이 좋습니다.

침식과 팽창 연산의 단점

이전 글에서 영상에서 침식(erode)와 팽창(dilate) 연산하여 잡음을 제거하는 작업을 해보았습니다.

이러한 연산의 단점은 기존 영상의 객체 영역을 변형시킨다는 것입니다. 위 예시에서만 보더라도 침식의 경우 글자가 얇아졌고팽창의 경우 글자가 두꺼워졌습니다.

이렇게 영상에 전반적인 영향을 주는 것은 결과적으로는 좋지 않습니다.

열기, 닫기 개념

모폴로지 기법 중에서 열기(Opening)와 닫기(Closing)이라는 연산 방식이 있습니다.
열기는 침식연산 후 팽창연산을 하는 것을 말하며, 닫기는 팽창연산 후 침식연산을 하는 것을 말합니다.
이렇게 열기, 닫기 연산에서 침식 또는 팽창 한것을 다시 되돌리면 어떻게 표시 될까요?

열기 연산을 하나씩 보면 아래와 같습니다.

열기 연산

침식 연산으로 잡음이 제거되어 없어지고 글자가 얇아지지만 팽창연산으로 다시 글자 두께가 원상 복구 됩니다.
팽창연산에서 잡음은 다시 복구되지 않습니다. 침식연산으로 인해 잡음 픽셀 자체가 사라져서 팽창되지 않기 때문입니다.
비슷하게 닫기 연산을 하나씩 보면 아래와 같습니다.

팽창 연산으로 검은 픽셀들이 제거되고, 글자도 두꺼워졌으며 , 이후 침식 연산으로 글자 두께가 원상 복구 됩니다.
열기와 마찬가지로 잡음이 복구되지 않습니다.

열기, 닫기 코드

OpenCV에서는 morphologyEx 함수를 통해 열기 연산과 닫기 연산을 제공합니다.

/** 
@param src 입력 영상
@param dst 출력 영상
@param op 연산 타입
@param kernel 구조 요소
@param anchor 고정점 위치
@param iterations 반복 횟수
@param borderType 가장자리 픽셀 확장 방식
@param borderValue borderType이 BORDER_CONSTANT인 경우 가장자리 픽셀 값
 */
void morphologyEx( InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() );

샘플 코드는 아래와 같습니다.

Mat src1 = imread("address.png", IMREAD_GRAYSCALE);
Mat src2 = imread("address2.png", IMREAD_GRAYSCALE);
if (src1.empty() || src2.empty())
{
	cerr << "image load fail" << endl;
	return -1;
}

Mat matOpen, matClose;
morphologyEx(src1, matOpen, MORPH_OPEN, Mat()); // 열기
morphologyEx(src2, matClose, MORPH_CLOSE, Mat()); // 닫기

imshow("open", matOpen);
imshow("close", matClose);

waitKey();
destroyAllWindows();

실행하면 아래와 같이 출력합니다. 위에서 설명한 영상과 동일한 것을 확인 할 수 있습니다.

이상으로 열기, 닫기에 대해 알아봤습니다.