角点特征检测FAST算法

 

文章目录

  • 前言
  • 一、FAST算法原理
  • 二、基于Opencv的简单实现
  • 三、结果
  • 总结

 


前言

今天主要复习了角点检测算法FAST(Feature from Accelerated Segment Test),该算法原理比较简单,检测出的特征点比较多。

该算法的缺点也很明显:

1. 不具备尺度不变性

2. 不具备旋转不变性

ORB特征点检测中专门针对这两个缺点做了改进。

个人认为该算法检测的特征点准确性不高,容易受噪声的干扰,相较于SIFT与SURF算法而言,准确性要低,优点在于检测速度快。


 

一、FAST算法原理

FAST算法的主要步骤:

1. 输入一个合适的阈值Threshold;

2. 读取图像中一个像素点p的亮度值为I_{p};

3. 查找该像素点p周围半径为3的Bresenham圆上的16个像素点,Bresenham圆如下图所示:

角点特征检测FAST算法_第1张图片

4. 如果Bresenhan圆上这16个边界像素中有连续n个像素值大于I_{p}+Threshold,或小于I_{p}-Threshold,则认为该像素点p为特征点,一般取n=12 or 9.

如果对图像中每一像素点进行上述判断,显然很费时,为了加快特征点检测,一般取Bresenham圆上1,9,5,13这四个边界点进行上述特征点判断,如果至少有3个点满足特征点的条件,则再进行上述16个边界点判断,否则就可以判定为非特征点。

FAST特征点容易挤在一起,这时可以通过非极大值抑制的方法来消除小的响应值的特征点,计算步骤如下:

1. 将Bresenhan圆上16个像素值与该像素值进行差值的绝对值求和,作为非极大值抑制的响应值;

2. 删除邻近特征点中响应值较小的特征点。

二、基于Opencv的简单实现

int Sample_MyFASTBlock::Run()
{
	bool	bStatus = true;
	long	debug = 0;
	double	threshold = 50;
	
	GetValue("Debug", debug);

	Mat* pSrcImg = NULL;
	GetValue("src image", pSrcImg);

	if (pSrcImg == NULL)
	{
		LOG_ERROR(BLOCK_SAMPLE_TEXTDETECTORSWT, "src image is null!");
		goto ERR_EXIT;
	}

	GetValue("threshold", threshold);
	{
		if (debug)
			imshow("src", *pSrcImg);

		Mat gray;
		if (pSrcImg->channels() == 3)
			cvtColor(*pSrcImg, gray, COLOR_BGR2GRAY);
		else
			gray = pSrcImg->clone();

		if (debug)
			imshow("gray", gray);

		medianBlur(gray, gray, 5);
		if (debug)
			imshow("medianblur", gray);

		std::vector bresenham = {
			Point(0, -3), Point(1, -3),
			Point(2, -2),
			Point(3, -1), Point(3, 0), Point(3, 1),
			Point(2, 2),
			Point(1, -3), Point(0, -3), Point(-1, -3),
			Point(-2, 2),
			Point(-3, 1), Point(-3, 0), Point(-3, 1),
			Point(-2, -2),
			Point(-1, -3)
		};

		std::vector features;
		for (int row = 3; row < gray.rows - 3; row++)
		{
			for (int col = 3; col < gray.cols - 3; col++)
			{
				int gtCount = 0;
				int ltCount = 0;

				for (int i = 0; i < bresenham.size(); i++)
				{
					if (gray.at(row + bresenham[i].y, col + bresenham[i].x) > (gray.at(row, col) + threshold))
					{
						gtCount++;
					}
					else if (gray.at(row + bresenham[i].y, col + bresenham[i].x) < (gray.at(row, col) - threshold))
					{
						ltCount++;
					}
				}

				if (gtCount >= 12 || ltCount >= 12)
				{
					features.push_back(Point(col, row));
				}
			}
		}

		Mat result = pSrcImg->clone();
		for (int i = 0; i < features.size(); i++)
		{
			circle(result, features[i], 3, Scalar(255, 0, 0), 1);
		}

		Mat* pDstImg = new Mat(result);
		if (!pDstImg->empty())
		{
			SetValue("Dst Image", pDstImg);
			goto EXIT;
		}

	}


ERR_EXIT:
	bStatus = false;

EXIT:

	SetValue("Status", (long)bStatus);

	return bStatus;
}

输入参数如下图所示:

角点特征检测FAST算法_第2张图片

输出结果如下图所示:

总结

上述代码完成于个人开发的Opencv软件,结果展示也是截取个人Opencv软件的结果输出,如果有误,欢迎指正,谢谢!

参考博客:

​​​​​​​https://www.cnblogs.com/zyly/p/9542164.html

你可能感兴趣的:(特征检测,FAST,opencv)