您的位置:首页 > 运维架构

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

2021-04-27 19:59 681 查看

文章目录

  • 2 测试图像
  • 3 实现
  • 1 理论

    1.1 使用Fast进行特征检测

      步骤如下:
      1)选择图像中是否要识别为兴趣点的像素 p p p,使其强度为 l p l_p lp​;
      2)选择适当的阈值 t t t
      3)考虑被测像素周围有 16 16 16个像素的圆圈,如下图:

      4)如果圆中存在一组 n n n个连续的像素,它们均比 l p + t l_p + t lp​+t亮,或者比 l p − t l_p - t lp​−t暗,则像素 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 lp​−t暗;反之不满足。然后,对满足条件的像素继续检测,即条件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-t<I_{{p \rightarrow x}}<I_p+t &\ \ \ \ (\text{similar});\\ &b, I_p+t\leq I_{{p \rightarrow x}} &\ \ \ \ (\text{brighter}). \end{aligned} \right. Sp→x​=⎩⎪⎨⎪⎧​​d,Ip→x​≤Ip​−ts,Ip​−t<Ip→x​<Ip​+tb,Ip​+t≤Ip→x​​    (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中文文档

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: