Opencv之用于角点检测的Fast算法

文章目录

  • 1 理论
    • 1.1 使用Fast进行特征检测
    • 1.2 让机器学习一个角检测器
    • 1.3 非最大抑制
  • 2 测试图像
  • 3 实现

1 理论

1.1 使用Fast进行特征检测

  步骤如下:
  1)选择图像中是否要识别为兴趣点的像素 p p p,使其强度为 l p l_p lp
  2)选择适当的阈值 t t t
  3)考虑被测像素周围 16 16 16个像素的圆圈,如下图:
Opencv之用于角点检测的Fast算法_第1张图片
  4)如果圆中存在一组 n n n个连续的像素,它们均比 l p + t l_p + t lp+t亮,或者比 l p − t l_p - t lpt暗,则像素 p p p是一个角。 n n n被选取为 12 12 12
  5)使用高速测试以排除大量的非角区域:此测试只检测1、9、5和13处的像素,如果第一个1和9太亮或太暗,则继续检测5和13。如果 p p p是一个角,则其中至少三个全部比 l p + t l_p + t lp+t亮或者比 l p − t l_p - t lpt暗;反之不满足。然后,对满足条件的像素继续检测,即条件4,但是缺点有以下:
    5.1)不会拒绝 n < 12 n<12 n<12的候选对象;
    5.2)像素的选择不是最佳的,因为其效率取决于问题的顺序和角落外观的分布;
    5.3)高速测试的结果被丢弃了;
    5.4)彼此相邻的检测到多个特征。
  目前机器学习的方法解决了前三个问题,最后一个问题则使用非最大抑制来解决。

1.2 让机器学习一个角检测器

  1)选择一组图像进行训练,最好从目标应用程序中进行训练;
  2)在每个图像中运行Fast算法,以查找特征点;
  3)对于每个特征点,将其周围的16个像素存储为适量;对所有图像执行此操作,以获得特征向量 P P P
  4)这16个像素中的每个像素 x x x可以是以下三种状态之一:
S p → x = { d , I p → x ≤ I p − t      ( darker ) ; s , I p − t < I p → x < I p + t      ( similar ) ; b , I p + t ≤ I p → x      ( brighter ) . S_{p \rightarrow x} = \left\{ \begin{aligned} &d, I_{p \rightarrow x} \leq I_{p} - t &\ \ \ \ (\text{darker});\\ &s, I_p-tSpx=d,IpxIpts,Ipt<Ipx<Ip+tb,Ip+tIpx    (darker);    (similar);    (brighter).  4.1)取决于这些这些状态, P P P可以分为 3 3 3个子集, P d P_d Pd P s P_s Ps P b P_b Pb
  4.2)定义一个新的布尔变量 K p K_p Kp,如果 p p p是一个角,则为True;反正为False。
  4.3)使用ID3算法,使用变量 K p K_p Kp查询每个子集,以获取有关真实类的知识;
  4.4)递归地将其应用于所有子集,直至熵为零;
  4.5)创建的决策树将用于其他图像的快速检测。

1.3 非最大抑制

  在相邻位置检测多个兴趣点:
  1)计算所有检测到的特征点的得分函数 V V V,其中 V V V p p p与16个周围像素值之间的绝对差之和;
  2)考虑两个相邻的关键点并计算它们的 V V V值;
  3)丢弃较低 V V V值的兴趣点。

2 测试图像

3 实现

import numpy as np
import cv2 as cv


def test(img_path):
    img = cv.imread(img_path)
    img_gray = cv.imread(img_path, 0)
    fast = cv.FastFeatureDetector_create()
    kp = fast.detect(img_gray, None)
    img1 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
    print("Threshold: {}".format(fast.getThreshold()))
    print("nonmaxSuppression:{}".format(fast.getNonmaxSuppression()))
    print("neighborhood: {}".format(fast.getType()))
    print("Total Keypoints with nonmaxSuppression: {}".format(len(kp)))
    # 关闭非极大抑制
    fast.setNonmaxSuppression(0)
    kp = fast.detect(img_gray, None)
    print("Total Keypoints without nonmaxSuppression: {}".format(len(kp)))
    img2 = cv.drawKeypoints(img, kp, None, color=(255, 0, 0))
    img = np.hstack([img, img1, img2])
    img = cv.resize(img, None, fx=0.5, fy=0.5)
    cv.imshow("", img)
    cv.waitKey()


if __name__ == '__main__':
    test_img_path = "miao.png"
    test(test_img_path)

  输出如下:


参考文献:
【1】Opencv中文文档

你可能感兴趣的:(Python,Opencv,角点检测,Fast算法,因吉)