OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝/ 이진화와 모폴로지

영상의 이진화

이진화

  • 영상의 이진화(binarization)는 영상의 각 픽셀을 두 개의 부류로 나누는 작업이다.
    • 예컨대 입력 영상을 주요 객체 영역과 배경으로 나누거나 또는 영상에서 중요도가 높은 관심 영역(ROI, Region Of Interest)과 그렇지 않은 비관심 영역으로 구분하는 용도로 이진화가 사용될 수 있다.
    • 원래 디지털 컴퓨팅 분야에서 이진화는 입력 값을 0 또는 1로 설정하지만 영상의 이진화는 픽셀 값을 0 또는 255로 설정한다.
    • 그러므로 이진화가 적용된 이진 영상은 흰색과 검은색 픽셀로만 구성된다.
  • 영상의 이진화는 기본적으로 영상의 각 픽셀값을 이용한다. 그레이스케일 영상에 대해 이진화를 수행하려면 영상의 픽셀 값이 특정 값보다 크면 255로 설정하고, 작으면 0으로 설정한다.
    • 이때 각 픽셀과의 크기 비교 대상이 되는 값을 임계값(threshold) 또는 문턱치라고 한다.
    • 임계값은 그레이스케일 범위인 0-255 사이의 정수를 지정할 수 있다.

dst(x, y) = \begin{cases} 255 & src(x, y) > T \\ 0 & else \end{cases}

  • OpenCV에서 이진화는 threshold() 함수를 이용하여 수행할 수 있다.
    • threshold() 함수의 동작은 type 인자에 의해 결정된다. type 인자에는 ThresholdTypes 열거형 상수를 지정할 수 있다.
ThresholdTypes 설명
THRES_BINARY dst(x, y) = \begin{cases} maxval & src(x, y) > thresh \\ 0 & else \end{cases}
THRES_BINARY_INV dst(x, y) = \begin{cases} 0& src(x, y) > thresh \\ maxval & else \end{cases}
THRES_TRUNC dst(x, y) = \begin{cases} thresh & src(x, y) > thresh \\ src(x, y) & else \end{cases}
THRES_TOZERO dst(x, y) = \begin{cases} src(x, y) & src(x, y) > thresh \\ 0 & else \end{cases}
THRES_TOZERO_INV dst(x, y) = \begin{cases} 0 & src(x, y) > thresh \\ src(x, y) & else \end{cases}
THRES_OTSU 오츠(Otsu) 알고리즘을 이용한 자동 임계값 결정
THRES_TRIANGLE 삼각(triangle) 알고리즘을 이용한 자동 임계값 결정
  • threshold() 함수를 이용하여 영상을 이진화하려면 maxval 인자에 255를 지정하고 type 인자에 THRES_BINARY 또는 THRES_BINARY_INV를 지정한다.
    • THRES_BINARY_INV 방법으로 이진화하는 것은 THRES_BINARY 방법으로 이진화를 수행한 후 영상을 반전하는 것과 동일하다.
  • ThresholdTypes 열거형 상수 중 THRES_OTSU와 THRES_TRIANGLE는 임계값을 자동으로 결정할 때 사용한다.
    • 두 방법 모두 픽셀 값 분포를 분석하여 임계값을 자동으로 결정하고, 결정된 임계값을 이용하여 임계값 연산을 수행한다.
    • 두 상수는 보통 논리합 연산자(|)를 이용하여 다른 ThresholdTypes 상수와 함께 사용된다.
  • 자동 이진화를 수행할 경우 threshold() 함수 내부에서 임계값을 자체적으로 계산하여 사용하기 때문에 threshold(0 함수의 세 번째 인자로 전달한 thresh 값은 사용되지 않는다.
    • 자동 임계값 결정 방법은 CV_8UC1 타입의 영상에만 적용할 수 있다.

적응형 이진화

  • threshold() 함수는 지정한 임계값을 영상 전체 픽셀에 동일하게 적용하여 이진화 영상을 생성한다. 이러한 방식을 전역 이진화(global binarization)라고 한다.
    • 그런데 영상의 특성에 따라 적녁 이진화를 어려운 경우가 있는데, (아래 이미지와 같이 불균일한 조명 환경에서 촬영된 영상의 경우) 이런 경우 각 픽셀마다 서로 다른 임계값을 사용하는 적응형 이진화(adaptive binarization)기법을 사용하는 것이 효과적이다.

  • 적응형 이진화는 영상의 모든 픽셀에서 정해진 크기의 사각형 블록 영역을 설정하고, 블록 영역 내부의 픽셀 값 분포로부터 고유의 임계값을 결정하여 이진화하는 방식이다.
    • 이때 (x, y) 좌표에서의 임계값 T(x, y)는 다음 수식을 이용하여 결정한다.

T(x, y) = \mu(x, y) - C

  • 위 수식에서 \mu(x, y) 는 (x, y) 주변 블록 영역의 픽셀값 평균이고 C는 임계값의 크기를 조정하는 상수이다.
    • 블록 내부 픽셀 값의 평균 \mu(x, y) 는 일반적인 산술 평균을 사용하거나 또는 가수이산 함수 형태의 가중치를 적용한 가중 평균을 사용한다.
    • 상수 C는 영상의 특성에 따라 사용자가 결정한다.
  • OpenCV에서 적응형 이진화는 adpativeThreshold() 함수를 이용하여 수행할 수 있다.
    • adpativeThreshold() 함수는 각 픽셀 주변의 blocksize x blocksize 영역에서 평균을 구하고, 평균에서 상수 C를 뺀 값을 해당 픽셀의 임계값으로 사용한다.
    • 이때 블록 영역의 평균을 구하는 방식은 adaptiveMethod 인자를 통해 설정할 수 있다. adaptiveMethod 인자에 ADAPTIVE_THRESH_MEAN_C를 지정하면 산술평균을 이용하고, ADAPTIVE_THRESH_GAUSSIAN_C를 지정하면 가우시안 마스크를 적용하여 가우시안 가중 평균을 계산한다.

모폴로지 연산

이진 영상의 침식과 팽창

  • 모폴로지(morphology)는 형태 또는 모양에 관한 학문을 의미하는데, 영상 처리 분야에서 모폴로지는 객체의 형태 및 구조에 대해 분석하고 처리하는 기법을 의미하며, 수학적 모폴로지(mathematical morphology)라고도 한다.
    • 모폴로지 기법은 그레이스케일 영상과 이진 영상에 대해 모두 적용할 수 있지만 주로 이진 영상에서 객체의 모양을 단순화시키거나 잡음을 제거하는 용도로 사용된다.
  • 모폴로지 연산을 정의하려면 먼저 구조 요소(structuring element)를 정의해야 한다.
    • 구조 요소는 마치 필터링에서 사용되는 마스크처럼 모폴로지 연산의 동작을 결정하는 작은 크기의 행렬이다.
    • 구조 요소는 다양한 크기와 모양으로 정의할 수 있으며, 다양한 구조 요소의 예를 아래 그림에 표현하였다.
    • 필요에 따라 원하는 구조 요소를 선택하여 사용할 수도 있지만, 대부분의 모폴로지 연산에서는 아래 그림의 4번째에 있는 3×3 정방형 구조요소를 사용한다.

  • 영상의 모폴로지 기법 중 가장 기본이 되는 연산은 침식(erosion)과 팽창(dilation)이다.
    • 침식 연산은 객체 영역의 외곽을 골고루 깎아내는 연산으로 전체적으로 객체 영역은 축소되고 배경 영역은 확대된다.
    • 침식 연산은 구조 요소를 영상 전체에 대해 스캔하면서, 구조 요소가 객체 영역 내부에 완전히 포한될 경우 고정점 위치 픽셀을 255로 설정한다.
    • 이진 영상의 팽창 연산은 객체 외곽을 확대하는 연산이다. 팽창 연산을 수행하면 객체 영역은 확대되고, 배경 영역은 줄어든다.
    • 팽창 연산은 구조 요소를 영상 전체에 대해 이동시키면서, 구조 요소와 객체 영역이 한 픽셀이라도 만날 경우 고정점 위치 픽셀을 255로 설정한다.
  • 작은 크기의 영상에서 3×3 정방형 구조요소를 이용하여 침식과 팽창 연산을 수행한 예시가 아래 그림과 같다.
    • (a)는 12×12 크기의 입력 이진 영상을 확대하여 나타낸 것이며, 이 영상에는 흰색으로 표시된 객체가 하나 있다. (b)는 3×3 정방형 구조 요소이다.
    • (a) 영상에 대해 (b) 구조 요소를 이용하여 침식 연산을 수행한 결과가 (c)에 나타났다. 침식 연산에 의해 객체 모양이 상하좌우 모든 방향에 대해 1픽셀 정도 깎인 것 같이 변경되었다. 특히 객체 윗 부분의 튀어나온 부분은 매끈하게 제거 되었다.
    • (a) 영상에 팽창 연산을 수행한 결과는 (d)와 같다. 객체 영역이 상하좌우 모든 방향에 대해 1픽셀 정도 확대된 것 같이 변경되었다. 특히 객체 하단의 패인 부분이 깔끔하게 매워졌다.

  • OpenCV에서 구조 요소는 원소 값이 0 또는 1로 구성된 CV_8UC1 타입의 Mat 행렬로 표현된다.
    • 구조 요소 행렬에서 값이 1인 원소만을 이용하여 구조 요소의 모양을 결정한다.
    • OpenCV는 널리 사용되는 모양의 구조 요소 행렬을 간단하게 생성할 수 있도록 getStructuringElement() 함수를 제공한다.
  • getStructuringElement() 함수는 지정한 모양과 크기에 해당하는 구조 요소 행렬을 반환한다.
    • shape은 구조 요소의 모양을 결정하는 역할을 하며, MorphShapes 열거형 상수 중 하나를 지정할 수 있다.
    • 구조 요소의 크기는 ksize 인자를 통해 지정하며, 보통 가로와 세로 크기를 모두 홀수로 지정한다.
MorphShapes 설명
MORPH_RECT 사각형 모양의 구조 요소
MORPH_CROSS 십자가 모양의 구조 요소
MORPH_ELLIPSE 타원 모양의 구조 요소. 지정한 구조 요소 크기의 사각형에 내접하는 타원을 이용한다.
  • OpenCV에서 영상의 침식연산은 erode() 함수를 이용하여 수행한다.
    • erode() 함수의 kernel에는 getStructuringElement() 함수로 생성한 구조 요소 행렬을 지정할 수 있다.
    • 다만 kernel 인자에 Mat() 또는 noArray()를 지정하면 3×3 정방형 구조 요소를 사용하여 침식 연산을 수행한다.
  • OpenCV에서 영상의 팽창 연산을 수행하려면 dilate() 함수를 사용한다.
    • dilate() 함수의 인자 구성과 사용법은 erode와 동일하다.
void erode_dilate()
{
Mat src = imread("milkdrop.bmp", IMREAD_GRAYSCALE);

if (src.empty())
{
cerr << "Image load failed!" << endl;
return;
}

Mat bin;
threshold(src, bin, 0, 255, THRESH_BINARY | THRESH_OTSU);

Mat dst1, dst2;
erode(bin, dst1, Mat());
dilate(bin, dst2, Mat());

imshow("src", src);
imshow("bin", bin);
imshow("erode", dst1);
imshow("dilate", dst2);

waitKey();
destroyAllWindows();
}

이진 영상의 열기와 닫기

  • 모폴로지 기법 중 열기(opening)과 닫기(closing) 연산은 침식과 팽창을 이용하여 구현할 수 있는 연산이다.
    • 열기 연산은 입력 영상에 대해 침식 연산을 먼저 수행한 후 그 다음에 팽창 연산을 수행하는 연산이며, 닫기 연산은 팽창 연산을 먼저 수행한 후 그 다음에 침식 연산을 수행하는 연산이다.
  • 열기와 닫기 연산은 각각 침식과 팽창이 한 번 씩 적용되기 때문에 객체 영역의 크기가 바뀌지는 않지만 침식과 팽창 연산을 적용하는 순서에 따라 서로 다른 효과가 발생한다.
    • 열기 연산은 침식 연산을 먼저 수행하기 때문에 한두 픽셀짜리 영역이 제거된 후, 팽창 연산이 수행되므로 이진 영상에 존재하는 작은 크기의 객체가 효과적으로 제거된다. 
    • 반면 닫기 연산은 팽창 연산을 먼저 수행하기 때문에 객체 내부의 작은 구멍이 메워지게 된다.
  • 작은 크기의 영상에서 3×3 정방형 구조 요소를 이용하여 열기와 닫기를 수행한 결과는 아래 그림과 같다.
    • (a)는 원본영상이며, (b)는 열기 연산의 결과, (c)는 닫기 연산의 결과이다.

  • OpenCV에서 모폴로지 열기와 닫기 연산은 morphologyEx() 함수를 이용하여 수행할 수 있다.
    • morphologyEx() 함수는 열기와 닫기 뿐만 아니라 침식과 팽창과 같은 일반적인 모폴로지 연산도 수행할 수 있는 범용적인 모폴로지 연산 함수이다.
  • morphologyEx() 함수는 세 번째 연산 인자인 op를 이용하여 모폴로지 연산 방법을 지정한다. op 인자에는 MorphTypes 열거형 상수 중 하나를 지정할 수 있으며, 이진 영상에 대해 자주 사용하는 MorphTypes 상수에 대해 아래 표로 정리하였다.
    • MORPH_GRADIENT 상수는 팽창 결과 영상에서 침식 결과 영상을 빼는 연산을 수행하며 객체의 외곽선이 추출되는 효과가 있다.
MorphTYpes 설명
MORPH_ERODE 침식 연산
MORPH_DILATE 팽창 연산
MORPH_OPEN 열기 연산
MORPH_CLOSE 닫기 연산
MORPH_GRADIENT

모폴로지 그래디언트 계산
dst = dilate(src, element) – erode(src, element)

[ssba]

The author

지성을 추구하는 사람/ suyeongpark@abyne.com

댓글 남기기

This site uses Akismet to reduce spam. Learn how your comment data is processed.