視覚信号処理IIコーナー検出


コーナー検出


ビデオの特徴(feature)とは、ビデオから抽出できる有用な情報を指す.
平均輝度、ヒストグラム、エッジ、直線成分、コーナーなどが特徴かもしれません
コーナー(corner)はエッジ方向が急激に変化する部分であり、三角形の頂点や鉛筆の芯などが鋭く突き出た部分がコーナーになる.
フィーチャーポイント(feature point)は、コーナーのように一点で表すことができるフィーチャーポイントです.
ビデオでコーナーを探す基本的な考え方は、ビデオで小さなウィンドウを移動する場合、コーナーのすべての方向のビデオの変化が大きくなければならないことです.下図に示します.
Moravec(人名)
画像中の各画素位置について、ウィンドウが垂直、水平、左対角線、右対角線の4方向に1画素ずつ移動したときの画像変化量(SSD)Eを算出し、その画素の画像変化量値にEの最小値を設定し、コーナーポイントとして設定した最小(E)値を用いて領域最大の最小値を検索する.

ハリス角検出器


Moraveメソッドの修正と補足
画像の特定の位置(x,y)Δx和Δy画素との輝度差は、以下の式で表される.
E(Δx,Δy)関数のすべての方向の値が大きい場合は、点(x,y)を角と見なすことができます.
ハリスはE(Δx,Δy)テイラー級数(Taylor級数)、高乳値分析(特徴値分析)などの数学的手法を用いて、その値が顕著であるか否かを全方向で検証し、コーナー応答関数Rを導出する.
コーナー応答関数定義では、定数kは、通常、0.04〜0.06の間の値を用いる.
ハリスによって定義されるコーナー応答関数Rは、入力ビデオの各画素において定義される実数値である.
Rが0より大きい正の値の場合、コーナーポイントとみなされます
Rが0に近いエラーの場合、フラット領域
Rが0より小さい負数は、負数と判定する

OpenCVは、ハリス角応答関数値を計算するためにcornerHarris()を提供する

例1ハリス角検出器


隣接するピクセルサイズ、sobel maskサイズ、定数を設定できます.
抽出結果floatデータ型
実数値を正規化する必要がある(normalize)
しきい値が120より大きい画素に対して非最大値隠しを実行し、コーナーを検出する
void corner_harris()
{
	Mat src = imread("keyboard.bmp", IMREAD_GRAYSCALE);
		
	if (src.empty())
	{
		cerr << "Image load failed" << endl;
		return;
	}

	Mat harris;
	cornerHarris(src, harris, 3, 3, 0.04); // 3, 3의 sobel mask 사용

	Mat harris_norm; //정규화 과정
	normalize(harris, harris_norm, 0, 255, NORM_MINMAX, CV_8U);

	Mat dst;
	cvtColor(src, dst, COLOR_GRAY2BGR);

	for (int j = 1; j < harris.rows - 1; j++) //코너 추출
	{
		for (int i = 1; i < harris.cols - 1; i++)
		{
			if (harris_norm.at<uchar>(j, i) > 120)
			{
				if (harris.at<float>(j, i) > harris.at<float>(j - 1, i) &&
					harris.at<float>(j, i) > harris.at<float>(j + 1, i) &&
					harris.at<float>(j, i) > harris.at<float>(j, i - 1) &&
					harris.at<float>(j, i) > harris.at<float>(j, i + 1))
				{
					circle(dst, Point(i, j), 5, Scalar(0, 0, 255), 2);
				}
			}
		}
	}

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

	waitKey(0);
	destroyAllWindows();
}

int main()
{
	corner_harris();
	return 0;
}
harris_normハリス角応答関数の値を0〜255の階調画像に標準化する.
dstウィンドウで領域最大の点を選択し、結果を赤い円で表示します.

FAST検出


FAST検出
単純な画素値比較によりコーナーを検出する高速コーナー検出方法.
コーナーが存在するか否かは、画像内の各画素の周囲の16画素と輝度とを比較することによって決定される.
周囲16個の画素のうち、点pよりも明るいまたは十分に暗い9個以上の画素が連続して存在する場合、角として定義される.
数学的に表され、点p上の輝度はIpで表される.
周囲16個の画素のうち、Ip+tより大きい9個の画素が連続して現れる場合、点pは暗い領域の先端が突き出た角である.
逆に、周囲16個の画素のうち、Ip−t未満の画素が9個以上連続して現れると、ドットpは、明るい領域で突出したコーナーと見なされる.
ここで、tは、十分な明るさまたは十分な暗さを調整するためのしきい値を表す.

例2 FASTコーナー検出


OpenCVはFAST()を提供し、FAST角検出方法を採用する.
エッジコーナーピクセルで最も適切なコーナー
ピクセルを選択するための他の非最大抑制操作を推奨します
検出されたすべてのコーナーに半径5の円を作成
void corner_fast()
{
	Mat src = imread("keyboard.bmp", IMREAD_GRAYSCALE);
			
	if (src.empty())
	{
		cerr << "Image load failed" << endl;
		return;
	}

	vector<KeyPoint> keypoints;
	FAST(src, keypoints, 60, true);

	Mat dst;
	cvtColor(src, dst, COLOR_GRAY2BGR);

	for (KeyPoint kp : keypoints)
	{
		Point pt(cvRound(kp.pt.x), cvRound(kp.pt.y));
		circle(dst, pt, 5, Scalar(0, 0, 255), 2);
	}

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

	waitKey(0);
	destroyAllWindows();
}

int main()
{
	corner_fast();
	return 0;
}

通常、一部のコーナーポイントの周囲のピクセルもコーナーとして検出されます.
境界部分またはエッジ部分で複数のコーナーが検出されました