今回はエッジ検出を試してみる。

OpenCV のエッジ検出には、Sobel、Laplacian、Canny の3種類がある。

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


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);

	// Sobelフィルタ
	cv::Mat img_sobel_x;
	cv::Sobel(img_gray, img_sobel_x, CV_32F, 1, 0);
	cv::convertScaleAbs(img_sobel_x, img_sobel_x);
	cv::Mat img_sobel_y;
	cv::Sobel(img_gray, img_sobel_y, CV_32F, 0, 1);
	cv::convertScaleAbs(img_sobel_y, img_sobel_y);
	cv::Mat img_sobel = (img_sobel_x + img_sobel_y) / 2;
	cv::namedWindow("sobel");
	imshow("sobel", img_sobel);

	// Laplacian
	cv::Mat img_laplacian;
	cv::Laplacian(img_gray, img_laplacian, CV_32F);
	cv::convertScaleAbs(img_laplacian, img_laplacian);
	cv::namedWindow("laplacian");
	imshow("laplacian", img_laplacian);

	// Cannyアルゴリズム
	cv::Mat img_canny;
	cv::Canny(img_gray, img_canny, 50, 200);
	cv::namedWindow("canny");
	imshow("canny", img_canny);

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


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

こちらはSobelフィルターによるエッジ検出。これは一次微分を用いてエッジ検出を行うもの。 方向を指定する必要があり、横方向を指定すると、横向きの線などが検出されない。 そのため横と縦と別々に処理し、結果を合成するなどの考慮が必要になる。 上のサンプルコードでもそのようにしている。
速度は一番速い。
opencv16

次にLaplacian。 Laplacianは二次微分を用いてエッジ検出を行う。 方向を指定する必要がないため処理がシンプルになる。
opencv17

最後にCanny。 Cannyは閾値を指定する必要がある。この閾値は自動で設定されないため、閾値がまずいと線が消えてしまう。次の画像でもいくつかの線が消えてしまっている。
opencv18

以上です。