OpenCV 库中 SIFT 特征提取实现,如:

import cv2

sift = cv2.xfeatures2d.SIFT_create()

img = cv2.imread('test.jpg')
kps, des = sift.detectAndCompute(img, None)

1. SIFT_create() 参数

def SIFT_create(nfeatures=None, 
                nOctaveLayers=None, 
                contrastThreshold=None, 
                edgeThreshold=None, 
                sigma=None):
    """
    SIFT_create([, nfeatures[, 
                   nOctaveLayers[, 
                   contrastThreshold[, 
                   edgeThreshold[, 
                   sigma]]]]]) -> retval
    Use cv.SIFT_create() instead
    """

其中,

[1] - nfeatures:特征点数目(算法对检测出的特征点排名,返回最好的nfeatures个特征点)

[2] - nOctaveLayers:金字塔中每组的层数(算法中会自己计算这个值)

[3] - contrastThreshold:过滤掉较差的特征点的对阈值. contrastThreshold越大,返回的特征点越少.

[4] - edgeThreshold:过滤掉边缘效应的阈值. edgeThreshold越大,特征点越多(被过滤掉的越少).

[5] - sigma:金字塔第0层图像高斯滤波系数.

注:

[1] - 参数nfeatures指定最终返回的特征点数量,并不影响SIFT特征检测的结果.

[2] - 参数nOctaveLayerssigma主要影响图像高斯金字塔的构成.

[3] - contrastThresholdedgeThreshold 会影响在DOG中寻找极值点的过程与结果.

在使用OpenCV SIFT特征检测算子时,如果提取效果不够理想,可根据实际情况调整参数后进行重新提取,如:

import cv2 

sift = cv2.xfeatures2d.SIFT_create(
            nfeatures=500, contrastThreshold=0.01, edgeThreshold=30, sigma=1.6)
kps, des = sift.detectAndCompute(img_cv2, None)

OpenCV 默认参数:

nfeatures =0
nOctaveLayers =3
contrastThreshold = 0.04
edgeThreshold = 10
sigma =1.6

参考:opencv3.1的SIFT特征检测参数图文详解 - 2016.11.04

2. kps 与 des

kps, des = sift.detectAndCompute(img, None)

其中,返回值 des为 128 为向量组成的列表; kps 为关键点列表,每个元素为一个 KeyPoint,其包含信息有:

[1] - angle:角度,表示关键点的方向. 为了保证方向不变形,SIFT算法通过对关键点周围邻域进行梯度运算,求得该点方向. -1为初值.

[2] - class_id:当要对图片进行分类时,可以用 class_id 对每个特征点进行区分. 未设定时为-1,需要自己设定.

[3] - octave:代表是从金字塔哪一层提取的得到的数据.

[4] - pt:关键点的坐标(x, y).

[5] - response:响应程度,代表该点强壮大小,更确切的说,是该点角点的程度.

[6] - size:该点直径的大小

Last modification:March 4th, 2021 at 01:24 pm