今回は画像を2値化を行う。

2値化とは、濃淡のある画像をある閾値で白か黒に置き換える処理のことで、閾値の決定方法はいくつか存在する。

今回は大津のアルゴリズムを用いて最適な閾値を自動的に決定する方法と、手動で閾値を決定する方法を示す。

手動で閾値を決定する方法では、ウィンドウにスライダーを付け、スライダーを動かすことによって画像が動的に変更される。このスライダーはOpenCVが提供するコントロールである。

main.cpp を以下のように書き換える。

void onTrackbar(int thresh, void* pimg_gray)
{
	cv::Mat img_gray = *(cv::Mat*)pimg_gray;
	cv::Mat img_threshold;
	cv::threshold(img_gray, img_threshold, thresh, 255, CV_THRESH_BINARY);
	imshow("threshold_manual", img_threshold);
}

int main(int argc, char* argv[])
{
	// オリジナル画像の読み込み
	cv::Mat img_org = cv::imread("test1.JPG");
	cv::namedWindow("original");
	imshow("original", img_org);

	// グレースケール
	cv::Mat img_gray;
	cv::cvtColor(img_org, img_gray, CV_BGR2GRAY);
	cv::namedWindow("grayscale");
	imshow("grayscale", img_gray);

	// 画像の二値化(大津)
	cv::Mat img_threshold;
	cv::threshold(img_gray, img_threshold, 0, 255, CV_THRESH_OTSU | CV_THRESH_BINARY);
	cv::namedWindow("threshold_otsu");
	imshow("threshold_otsu", img_threshold);

	// 画像の二値化(手動)
	cv::namedWindow("threshold_manual");
	int value = 0;
	cv::createTrackbar("threshold", "threshold_manual", &value, 255, onTrackbar, &img_gray);
	cv::setTrackbarPos("threshold", "threshold_manual", 60);

	cv::waitKey(0);
	cv::destroyAllWindows();
	return 0;
}


実行すると、ダイアログが3つ表示される。これは元画像。
opencv9

threshold_otsu が大津のアルゴリズムを使ったもの。この例では閾値は140くらいだと思うが、「Harry Potter」の文字が若干読みにくい。「Graphic Designer」に至っては判別できない。
opencv11

こちらはスライダーを用いた手動で閾値を設定するもの。初期値を60にしたところ。「Graphic Designer」は読めるが、「Harry Potter」の文字が白く飛んでしまった。
opencv12

閾値をいくらにしても「Harry Potter」、「Graphic Designer」のどちらかが読めなくなってしまう。 opencv13

以上です。