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] - 参数nOctaveLayers和sigma主要影响图像高斯金字塔的构成.
[3] - contrastThreshold和edgeThreshold 会影响在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
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:该点直径的大小