[OpenCV] 영상의 이진화 – threshold

이번 글에서는 그레이스케일 영상의 이진화에 대해 간략한 설명과 threshold 함수의 사용법에 대해 알아보겠습니다.

설명

영상의 이진화는 픽셀을 검은색 또는 흰색같이 두 개의 값으로 나누는 작업을 말합니다. 영상에서 의미가 있는 관심 영역(ROI)과 비관심 영역을 구분할 때 이진화가 사용됩니다.

예를 들어 특정 색상의 세포를 구분할 때, 수도쿠에 입력된 글자를 인식할 때 이진화를 사용합니다.

그레이스케일에서는 영상을 이진화 시킬 때 특정값 T를 정해놓고 픽셀 값이 특정값보다 크면 255작으면 0으로 설정합니다. 수식으로 보면 아래와 같습니다. 

영상을 연산할 때 255 또는 0으로 나누는 특정값 T를 임계값이라고도 합니다.

함수

opencv에서는 이러한 이진화 작업에 대해 threshold 함수를 제공해줍니다.

/** 
@param src 이볅 영상
@param dst 출력 영상
@param thresh 임계값
@param maxval type에 THRESH_BINARY, THRESH_BINARY_INV 입력 시 영상의 최대값
@param type 임계값 연산 타입(see #ThresholdTypes).

@return 사용된 임계값
 */
double threshold( InputArray src, OutputArray dst, double thresh, double maxval, int type );

type에 들어가는 임계값의 열거형 상수는 아래와 같습니다.

ThresholdTypes 열거형 상수설명
THRESH_BINARY
THRESH_BINARY_INV
THRESH_TRUNC
THRESH_TOZERO
THRESH_TOZERO_IVN
THRESH_OTSU오츠 알고리즘을 이용한 자동 임계값 설정
THRESH_TRIANGLE삼각 알고리즘을 이용한 자동 임계값 설정
예제 코드

아래와 같이 세포 사진을 이진화 하는 예제 코드를 만들어 보겠습니다.

neutrophils.png

우선 아래와 같이 세포 사진을 읽고, 임계값을 표시하기 위해 main함수에 아래와 같이 코딩합니다.

Mat src = imread("neutrophils.png", IMREAD_GRAYSCALE);
if (src.empty())
{
	cerr << "image open fail" << endl;
	return -1;
}

imshow("src", src);
imshow("dst", src);

// 트랙바 만들기
createTrackbar("Threshold", "dst", 0, 255, trackbar_neutrophils, &src);
setTrackbarPos("Threshold", "dst", 0);

waitKey();
destroyAllWindows();

return 0;

그리고 trackbar_neutrophils 콜백함수를 만들어줍니다.

void trackbar_neutrophils(int pos, void* userdata)
{
	Mat *pSrc = (Mat *)userdata;
	if (pSrc == nullptr)
		return;

	Mat dst;

	threshold(*pSrc, dst, pos, 255, THRESH_BINARY);
	imshow("dst", dst);
}

위 코드를 실행되면 아래와 같이 프로그램이 실행되는 것을 볼 수 있습니다.

이상으로 영상의 이진화 threshold에 대해 알아보았습니다.