SUSAN角点检测算法实现(详细版)

前言


一、SUSAN算子是什么?

        SUSAN ( Small univalue segment assimilating nucleus) 算子是一种基于灰度的特征点获取方法, 适用于图像中边缘和角点的检测, 可以去除图像中的噪声, 它具有简单、有效、抗噪声能力强、计算速度快的特点。

1.USAN(核值相似区)

        对于图像中非纹理区域的任一点,在以它为中心的模板窗中存在一 块亮度与其相同的区域,这块区域即为 USAN 区域。


        当一个像素点与圆模板的中心点的灰度值满足相似比较函数时,即判定属于 USAN 区域。图像不同位置处的 USAN 区域是不同的。

①.内部区域的 USAN 面 积大于圆模板的一半;

②.边缘的 USAN 区域面积等于圆模板面积的一半;

③.角点的 USAN 区域面积小于圆 模板面积的一半。


SUSAN角点检测算法实现(详细版)_第1张图片

其中SUSAN 角点检测的相似比较函数为:

SUSAN角点检测算法实现(详细版)_第2张图片

其函数的表达的意思:在属于圆模板中的任何一点的灰度值与圆心的灰度值的灰度差值小于等于某个常数 t ,则说明该点属于 usan 区域。其中 t 称为门限阈值

当圆模板的每个点进行相似比较后统计即可得到 r0 为圆心的USAN面积,其数学表达式为:

n(r0) 越大,即usan区域越大,表示在圆模板内的点 与 圆心的像素值差值很小的点比较多,故可以看出其圆心的特征点属于内部区域。

反之当n(r0)越小,则表示在圆模板内的点 与 圆心的像素值差值很小的点比较少,其特征可能是边缘区域或者角点区域。


2.特征提取响应函数R(r0)

当计算完图像的每个点的 USAN 面积之后,通过响应函数R(r0)进行特征提取,其函数表达式为

SUSAN角点检测算法实现(详细版)_第3张图片

        其中 g 称为几何门限,它决定了输出角点的 USAN 区域的最大值。即圆模板中相似点数的最大值。

由于 n(r0)值大小在 ( 0,圆模板面积 ] , 故 几何门限 g 取值属于其之间,g的取值会影响到提取 特征信息量的大小,一般来说,提取边缘特征信息时,g的取值要大一些,而提取角点特征信息时,需要抑制边缘特征,则g的取值固然要偏小,但过小会存在角点被剔除的情况。


二、SUSAN核心算法的实现

//模版 x 和 y的坐标的偏移量
	int OffSetX[37] =
	{
			-3, -3, -3,
		-2, -2, -2, -2, -2,
	-1, -1, -1, -1, -1, -1, -1,
	 0,  0,  0,  0,  0,  0,  0,
	 1,  1,  1,  1,  1,  1,  1,
		 2,  2,  2,  2,  2,
			 3,  3,  3
	};

	int OffSetY[37] =
	{
			-1, 0, 1,
		-2, -1, 0, 1, 2,
	-3, -2, -1, 0, 1, 2, 3,
	-3, -2, -1, 0, 1, 2, 3,
	-3, -2, -1, 0, 1, 2, 3,
		-2, -1, 0, 1, 2,
			-1, 0, 1
	};

//定义USAN中近似像素数量的阈值,g越小,角点挑选越苛刻,角点数量越少
	int t = 4;//门限阈值 即非核心点的灰度值与核心点的灰度值的灰度差值小于门限阈值才是属于USAN区域
	int g = 18;//几何阈值 即决定不同类型的特征点的门槛
	Mat grayImg_padded;
	//对灰度图像进行填充
	copyMakeBorder(grayImg, grayImg_padded, 3, 3, 3, 3, BORDER_REFLECT);
	int same; 
	for (int i = 3; i < grayImg_padded.rows - 3; i++)
	{
		for (int j = 3; j < grayImg_padded.cols - 3; j++)
		{
			//same表示近似像素的数量
			same = 0;
			for (int k = 0; k < 37; k++)
			{
				//			  1 (条件:|I(r) - I(r0)| <= t)
				// c(r,r0) =  
				//			  0 (条件:|I(r) - I(r0)|  > t)
				if (abs(grayImg_padded.at(i + OffSetX[k], j + OffSetY[k]) - grayImg_padded.at(i, j)) <= t)
					same++;
				// n(r0) = Σc(r,r0)
			}
			//初始角点响应函数
			//			g - n(r0) 条件:g > n(r0) 
			//	R(r0) = 
			//			0		  条件:g <= n(r0) 
			if (same < g)
			{
				grayImg_padded.at(i, j) = g - same;
			}
			else
			{
				grayImg_padded.at(i, j) = 0;
			}
		}
	}


总结

你可能感兴趣的:(图像处理实战,opencv,计算机视觉,算法)