计算机视觉——图像特征之FAST角点检测(OpenCV/Python)

FAST角点定义

FAST角点定义为:若某像素点与周围邻域足够多的像素点处于不同区域,则该像素可能为角点。考虑灰度图像,即若某像素点的灰度值比周围邻域足够多的像素点的灰度值大或小,则该点可能为角点。

算法步骤

  • 对于图像中一个像素点 p p p,其灰度值为 I _ p I\_p I_p
  • 以该像素点为中心考虑一个半径为3的离散化的Bresenham圆,圆边界上有16个像素(如下图所示)
  • 设定一个合适的阈值 t t t,如果圆上有n个连续像素点的灰度值小于 I _ p − t I\_p-t I_pt或者大于 I _ p + t I\_p+t I_p+t,那么这个点即可判断为角点(n的值可取12或9)

circle.jpg

一种快速排除大部分非角点像素的方法就是检查周围1、5、9、13四个位置的像素,如果位置1和9与中心像素P点的灰度差小于给定阈值,则P点不可能是角点,直接排除;否则进一步判断位置5和13与中心像素的灰度差,如果四个像素中至少有3个像素与P点的灰度差超过阈值,则考察邻域圆上16个像素点与中心点的灰度差,如果有至少9个超过给定阈值则认为是角点。

角点分类器

  • 选取需要检测的场景的多张图像进行FAST角点检测,选取合适的阈值n(n<12),提取多个特征点作为训练数据
  • 对于特征点邻域圆上的16个像素 x i n 1 , 2 , … , 16 x \\in {1,2,…,16 } xin1,2,,16,按下式将其划分为3类
    在这里插入图片描述
  • 对每个特征点定义一个bool变量 K p K_p Kp,如果 p p p是一个角点,则 K p K_p Kp为真,否则为假
  • 对提取的特征点集进行训练,使用ID3算法建立一颗决策树,通过第 x x x个像素点进行决策树的划分,对集合 P P P,得到熵值为
    H ( P ) = ( c + c ^ ) l o g 2 ( c + c ^ ) − c l o g 2 c − c ^ l o g 2 c ^ H(P)=(c+ \hat{c})log_2 (c+\hat{c})-clog_2 c - \hat{c}log_2 \hat{c} H(P)=(c+c^)log2(c+c^)clog2cc^log2c^
    其中 c c c为角点的数目, c ^ \hat{c} c^为非角点的数目。由此得到的信息增益为
    Δ H = H ( P ) − H ( P d ) − H ( P s ) − H ( P b ) \Delta H = H(P) - H(P_d) - H(P_s) - H(P_b) ΔH=H(P)H(Pd)H(Ps)H(Pb)
    选择信息增益最大位置进行划分,得到决策树
  • 使用决策树对类似场景进行特征点的检测与分类

非极大值抑制

对于邻近位置存在多个特征点的情况,需要进一步做非极大值抑制(Non-Maximal Suppression)。给每个已经检测到的角点一个量化的值 V V V,然后比较相邻角点的 V V V值,保留局部邻域内 V V V值最大的点。 V V V值可定义为

  • 特征点与邻域16个像素点灰度绝对差值的和
  • V = m a x ( Σ x ∈ S b r i g h t ∣ I p r i g h t a r r o w x − I p ∣ − t , Σ x ∈ S d a r k ∣ I p → x − I p ∣ − t ) V = max(\Sigma_{x \in S_{bright}} |I_{p\\rightarrow x} - I_p| - t, \Sigma_{x \in S_{dark}} |I_{p\rightarrow x} - I_p| - t) V=max(ΣxSbrightIprightarrowxIpt,ΣxSdarkIpxIpt)
    式中, S b r i g h t S_{bright} Sbright是16个邻域像素点中灰度值大于 I p + t I_p+t Ip+t的像素点的集合,而 S d a r k S_{dark} Sdark表示的是那些灰度值小于 I p − t I_p−t Ipt的像素点。

算法特点

  • FAST算法比其他角点检测算法要快
  • 受图像噪声以及设定阈值影响较大
  • 当设置 n < 12 n<12 n<12时,不能用快速方法过滤非角点
  • FAST不产生多尺度特征,不具备旋转不变性,而且检测到的角点不是最优

代码实现

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

# 1.读取图像
img = cv.imread("4.jpg")

# 2.Fast角点检测
# 2.1创建一个Fast对象,传入阀值,注意:可以处理彩色空间图像
fast = cv.FastFeatureDetector_create(threshold=30)

# 2.2检测图像上的关键点
kp = fast.detect(img, None)

# 2.3在图像上绘制关键点
img2 = cv.drawKeypoints(img, kp, None, color=(0, 0, 255))

# 2.4输出默认参数
print("Threshold:{}".format(fast.getThreshold()))
print("nonmaxSuppression:{}".format(fast.getNonmaxSuppression()))
print("neighborhood:{}".format(fast.getType()))
print("Total Keypoints with nonmaxSuppression:{}".format(len(kp)))

# 2.5关闭非极大值抑制
fast.setNonmaxSuppression(0)
kp = fast.detect(img, None)

print("Total Keypoints without nonmaxSuppression:{}".format(len(kp)))

# 2.6绘制为进行非极大值抑制效果
img3 = cv.drawKeypoints(img, kp, None, color=(0, 0, 255))

# 3.绘制图像
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(10, 8), dpi=100)
axes[0].imshow(img[:, :, ::-1])
axes[0].set_title("原图")
axes[1].imshow(img2[:, :, ::-1])
axes[1].set_title("加入非极大值抑制")
axes[2].imshow(img3[:, :, ::-1])
axes[2].set_title("未加入非极大值抑制")
plt.show()

在这里插入图片描述

  • 29
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知来者逆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值