012 角点检测 Fast

背景

角点检测是很多图像处理(追踪,实时定位,图像匹配识别)的第一步,现在也有很多算法,但计算量都较大,不适合实时视频处理,Fast算法速度快,且角点检测质量也很高。

角点检测的速度越快,留给其他图像处理的时间就越多。

Schmid 准则:下游图像处理要求从两个不同的位置观看的相同场景应该产生对应于相同的真实世界三维位置的特征。也就是说同一个3D场景下不同视角图片角点检测的结果要相同,且要对应于3D场景中的真实角点。

机器学习派生的角点检测算法只使用了可用处理时间的7%,远低于Harris 探测器的120%,以及SIFT的检测阶段的300%。

应用

  • 实时追踪、定位
  • SLAM (simultaneous localisation and mapping)
  • 图像匹配识别
  • AR标签放置

以前的工作

大多数角点检测算法计算图像的响应函数C,超过一定阈值的点被保留作为角点。

边缘是图像两个区域的边界,在区域的角点处,边缘在各个方向上变化剧烈。一些技术通过分析chain code,寻找曲率最大值,方向或面貌变化,检测和链化边缘寻找角点。另一些技术不做边缘链化,而是寻找曲率变化,或者方向变化后梯度最大的点。

还有一些算法通过检测图片的一小部分(patch)来判断该部分是否包含角点。这些算法效率很高,因为只计算了图像的一部分。当然,这些算法大尺寸特征点图像(如模糊图像)上表现较差。

1 SSD

Moravec计算候选角点周围的一个patch和该patch移动一定距离后两者之间的 sum-of-squared-differences (SSD),这个值越大,说明候选点与周围像素的差异越大,是角点的可能性就越大

2 Harris

Harris计算海森矩阵,这个矩阵里面是一阶微分和二阶微分,然后用矩阵和阈值评价像素点是否为角点
012 角点检测 Fast_第1张图片
他定义的响应函数C为
在这里插入图片描述
这样定义,避免直接计算矩阵特征值。

研究表明, 特征值是图像曲率的近似度量,特征矩阵的特征值越大,C值越大,是角点的可能性越大,k一般在[0.04, 0.16]。
具体计算步骤如下
012 角点检测 Fast_第2张图片
python代码参见ImageProcessing100Wen(问题82-83)

3 Shi and Tomasi

基于仿射图形变换的假设,这两个人认为可以用下面的角点强度函数衡量角点
在这里插入图片描述
Zheng等人发现通过一些估算可以仅使用两个平滑图像(以前要用三个)来加速计算

4 Lowe DoG(Difference of Gaussians)

Lowe 通过将图像与高斯差分(DoG)核在多个尺度上卷积获得尺度不变性,并保留了尺度和空间均为最佳的位置。

使用DoG是因为它是Laplacian of a Gaussian(LoG)的良好近似,并且计算速度更快。

LoG是一个特别稳定的尺度空间内核(stable scale-space kernel)。

边缘是两个区域的边界,在区域的角点处,边界变化非常剧烈,有很多边缘检测算法通过寻找角点来检测边缘。

另一类的角点检测算法通过检测图像的一部分(patch)来验证该点是否为角点。这些算法十分高效,因为只计算了一部分像素点。但他们在具有大范围特征(例如模糊图像)的图像上往往表现不佳,因为这些算法只用到图像的一部分。FAST就是这类算法。

USAN (the Univalue Segment Assimilating Nucleus,单值段同化核)

一些算法将角点当做一个模糊的楔形,寻找楔形的特点(幅度,角度,模糊)与本地图像匹配寻找角点,这种想法被进一步泛化,提出了一种通过计算一个中心点周围像素在某一阈值范围内的像素数来寻找角点。接近中心的像素权重更高。这种方法被称为 USAN (the Univalue Segment Assimilating Nucleus,单值段同化核)。

Trajkovic and Hedley

以目标点为圆,计算该圆直径上的两点(f_p、f_p’)和圆心的像素差,以此作为响应函数,C在角点处的值大概率比其他地方大
在这里插入图片描述
也可以算更多的点

FAST: Features from Accelerated Segment Test

012 角点检测 Fast_第3张图片
如上图所示,FAST算法通过在以候选角点为中心的Bresenham圆上寻找16个连续的点,如果有n个点的值大于Ip + threshold,或者小于Ip - threshold,p就是角点。
为了加快计算,n取12,先计算1,5,9,13这四个点,如果有连续三个点的值都大于Ip + threshold,或者小于Ip - threshold,则p为候选角点,进一步做全角点测试,否则直接排除。

缺点

  • n小于12时无法通用
  • 像素点的选取和顺序隐含了特征点分布的假设,也就是说有一些角点不能匹配
  • 前四次的测试结果被弃用了
  • 多个特征被检测出彼此邻近
机器学习改善角点检测

第一步其实就是先用Fast算法算出图片的角点。

第二步,用x表示像素p的Bresenham圆上的某一个点,x in [1, 16],对于某个x,可以将图像三值化

012 角点检测 Fast_第4张图片
这样所有像素点组成了一个集合P,定义P的熵为
012 角点检测 Fast_第5张图片
在这里插入图片描述

因为提前计算过角点,所以角点数是知道的。对于某个x,比如x_s,可以将集合分成下面三个
在这里插入图片描述
然后不断地分割(说实话,没明白他怎么继续分,第一次分了以后Ps_d里面点的x不都是x_s了吗),直到各个子集合的熵为0,这就意味着这些子集的点要么全都是角点,要么全都不是。整个决策过程是一个二叉树。

数据没有覆盖所有的有效角点,所以这个角点检测器没有segment test detector精确。

机器学习这个主要是为了解决Fast的前三个缺陷。

具体实现参见https://docs.opencv.org/master/df/d0c/tutorial_py_fast.html

非极大值抑制

在这里插入图片描述
计算每个角点的V,取其中最大的,就可以消除临近的角点,解决Fast的第四个问题
012 角点检测 Fast_第6张图片
可以看出角点检测确实很快,但它的抗噪声能力较差,因为高速是通过减少像素点分析获得的。

python实现

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

fig, ax = plt.subplots(2, 2, figsize=(8, 8))


def plot_img(i, j, img_d, fast_d, len_k):
    # T: Threshold, S: nonmaxSuppression, K: Total keypoints
    ax[i][j].set_title('T: {}, S: {}, K: {}'.format(
        fast_d.getThreshold(), fast_d.getNonmaxSuppression(), len_k
    ))

    ax[i][j].imshow(cv.cvtColor(img_d, cv.COLOR_BGR2RGB))


img = cv.imread('../images/girl.jpg', 0)

# Initiate FAST object with default values
fast = cv.FastFeatureDetector_create(threshold=10, nonmaxSuppression=False)

# find and draw the keypoints
kp = fast.detect(img, None)

img1 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))

plot_img(0, 0, img1, fast, len(kp))

# enable nonmaxSuppression
fast.setNonmaxSuppression(True)
kp = fast.detect(img, None)

img2 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
plot_img(0, 1, img2, fast, len(kp))

# threshold = 20
fast.setThreshold(20)
kp = fast.detect(img, None)

img3 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
plot_img(1, 0, img3, fast, len(kp))

# threshold = 40
fast.setThreshold(40)
kp = fast.detect(img, None)

img4 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
plot_img(1, 1, img3, fast, len(kp))

[axi.axis('off') for axi in ax.ravel()]

plt.show()

012 角点检测 Fast_第7张图片

https://www.edwardrosten.com/work/rosten_2006_machine.pdf(Machine learning for high-speed corner detection)
https://github.com/gzr2017/ImageProcessing100Wen
https://docs.opencv.org/master/df/d0c/tutorial_py_fast.html

你可能感兴趣的:(图像处理,opencv,机器学习,fast,角点检测,图像处理)