Opencv之SIFT尺度不变特征变换

文章目录

  • 1 理论
    • 1.1 尺度空间极值检测
    • 1.2 关键点定位
    • 1.3 方向分配
    • 1.4 关键点描述
    • 1.5 关键点匹配
  • 2 测试图像
  • 2 实现

1 理论

  只需要用的话,直接跳过理论哇。
  哈里斯角检测这样的检测器,其特点是具有旋转不变性,即:即使图像旋转了,也可以找到相同的角,这是因为转角在旋转的图像中依然是转角。但是,如果缩放图像,则转角可能不是角。例如下图中,当放大小窗口中的转角时,其是平坦的。因此,哈里斯转角不是尺度不变的
Opencv之SIFT尺度不变特征变换_第1张图片
  对此,Lowe等人提出了SIFT算法,即尺度不变特征变换。

1.1 尺度空间极值检测

  不同的窗口需要使用不同的窗口,为此,使用比例空间滤波:
  1)找到具有各种 σ \sigma σ值的图像的高斯拉普拉斯算子:低 σ \sigma σ的高斯核对于较小的转角给出较高的值,高的反之。因此,在整个尺度和空间上找到局部最大值,即 ( x , y , σ ) (x, y,\sigma) (x,y,σ)列表。
  2)寻找方法为高斯插值,其通过具有两个不同 σ \sigma σ的图像的高斯模糊差计算得到,分别设置为 σ \sigma σ k σ k\sigma kσ
  3)找到之后,于图像上搜索比例和空间上的局部极值。
相关参数推荐设置如下:
  octaves = 4 =4 =4,缩放尺度 = 5 =5 =5,初始 σ = 1.6 σ=1.6 σ=1.6 k = 2 k=\sqrt{2} k=2

1.2 关键点定位

  找到潜在的关键点之后,需要对其进行优化:使用标度空间的泰勒级数展开来获得更精确的极值位置,如果该极值处的强度小于阈值 (论文中为0.03),则将其拒绝,用于消除低对比度的关键点;对于边缘,如果一个特征值与另一个特征值的比率大于一个阈值 (论文为10),则被丢弃,用于消除边缘关键点。余下的则是可能的目标点。

1.3 方向分配

  将方向分配给每个关键点,以实现图像旋转的不变性
  1)根据比例在关键点位置附件采取领域,并在该区域中计算梯度大小和方向;
  2)创建一个具有 36 36 36个覆盖 360 360 360度的bin的方向直方图;
  3)提取直方图的最高峰,并将其超过 80 % 80\% 80%的任何峰也视为计算方向。

1.4 关键点描述

  创建关键点描述符
  1)关键点周围采样 16 × 16 16 \times 16 16×16的邻域;
  2)每个邻域分为 16 16 16 4 × 4 4 \times 4 4×4的子块,对于每个子块,创建 8 8 8bin方向直方图。

1.5 关键点匹配

  通过识别两个图像的最近邻,可以匹配两个图像之间的关键点。然后在某些情况下,第二个直接的匹配可能非常接近第一个,可能的原因是由于噪声等。这种情况下,采用最接近距离与第二最接近距离之比,如果大于 0.8 0.8 0.8,将被拒绝。

2 测试图像

2 实现

import numpy as np
import cv2 as cv


def test(img_name):
    img = cv.imread(img_name)
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    sift = cv.SIFT_create()
    # kp = sift.detect(img_gray, None)
    kp, des = sift.detectAndCompute(img_gray, None)
    img1 = cv.drawKeypoints(img_gray, kp, img.copy())
    img2 = cv.drawKeypoints(img_gray, kp, img.copy(), flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    img = np.hstack([img1, img2])
    img = cv.resize(img, None, fx=0.5, fy=0.5)
    cv.imshow("", img)
    cv.waitKey()


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

  输出如下:
Opencv之SIFT尺度不变特征变换_第2张图片

你可能感兴趣的:(Python,Opencv,SIFT,Python,因吉)