【opencv-python】SIFT特征提取+匹配

  • 概念
    SIFT称为尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。
    SIFT的特点
    ①SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持一定程度的稳定性;
    ②区分性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;
    ③多量性,即使少数的几个物体也可以产生大量的SIFT特征向量;
    ④高速性,经优化的SIFT匹配算法甚至可以达到实时的要求;
    ⑥可扩展性,可以很方便的与其他形式的特征向量进行联合。

  • SIFT、HOG特征的计算过程

    • SIFT
      • 尺度空间极值检测
        搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
        关键点定位
        在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
        方向确定
        基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
        关键点描述
        在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。
import cv2
from matplotlib import pyplot as plt
'''sift特征点检测+特征匹配'''


def cross_check(img1, img2):

    # 创建sift特征检测对象
    sift = cv2.SIFT_create()

    # 检测特征点 描述符
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)

    # 采用match匹配时会包含错误匹配,可以剔除掉一部分
    BF = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)   # 交叉最佳匹配
    matches = BF.match(des1, des2)
    img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches, img1)
    return img3


def knn_match(img1, img2):
    ratio = 0.40

    # 创建sift特征检测对象
    sift = cv2.SIFT_create()

    # 检测特征点 描述符
    kp1, des1 = sift.detectAndCompute(img1, None)
    kp2, des2 = sift.detectAndCompute(img2, None)

    BF = cv2.BFMatcher()
    matches = BF.knnMatch(des1, des2, k=2)  # k邻近匹配
    # 如果两个匹配相距的距离足够大,则认为是一个正确的匹配
    good = []
    for m, n in matches:
        if m.distance < ratio * n.distance:
            good.append([m])
    img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, img1)
    return img3


if __name__ == '__main__':
    img1 = cv2.imread('imgs/rabbit-1.jpg', 1)
    img2 = cv2.imread('imgs/rabbit-1.jpg', 1)

    img3 = cross_check(img1, img2)
    # img3 = knn_match(img1, img2)

    plt.imshow(img3)
    plt.show()

你可能感兴趣的:(数字图像处理,python,opencv,计算机视觉)