SIFT的全稱是Scale Invariant Feature Transform,尺度不變特徵變換,由加拿大教授David G.Lowe提出的。SIFT特徵對旋轉、尺度縮放、亮度變化等保持不變性,是一種非常穩定的局部特徵。
具體工作原理見SIFT特徵詳解
代碼如下:
# coding=utf-8
import numpy as np
import cv2
sift = cv2.xfeatures2d.SIFT_create()
templet_img = cv2.imread(r'C:\workspace\data\templet.png', 0)
ori_img = cv2.imread(r'C:\workspace\data\object.png', 0)
WIDTH = 512
h, w = ori_img.shape
if h > w:
object_img = cv2.resize(ori_img, (WIDTH, int(WIDTH * ori_img.shape[0] / ori_img.shape[1])))
else:
object_img = cv2.resize(ori_img, (int(WIDTH * ori_img.shape[1] / ori_img.shape[0]), WIDTH))
## 角點檢測及特徵提取
kp_templet, des_templet = sift.detectAndCompute(templet_img, None)
kp_object, des_object = sift.detectAndCompute(object_img, None)
## 特徵匹配,利用近似k近鄰算法去尋找一致性
# Brute-Force 方法
bf = cv2.BFMatcher()
matches = bf.knnMatch(des_templet, des_object, k=2)
# FLANN方法(Fast Library for Approximate Nearest Neighbors)
# fla = cv2.FlannBasedMatcher()
# matches = fla.knnMatch(des_templet, des_object, k=2)
## 用比值判別法(ratio test)刪除離羣點
print('match length: ',len(matches))
matchesMask = [[0, 0] for i in range(len(matches))]
obj_point = []
for i, (m1, m2) in enumerate(matches):
if m1.distance < 0.7 * m2.distance: # 兩個特徵向量之間的歐氏距離,越小表明匹配度越高。
matchesMask[i] = [1, 0]
# pt1 = kp_templet[m1.queryIdx].pt # queryIdx索引到kp_templet
pt2 = kp_object[m1.trainIdx].pt # trainIdx索引到kp_object
cv2.circle(object_img, (int(pt2[0]), int(pt2[1])), 5, (255, 0, 255), -1)
obj_point.append(pt2)
# cv2.imshow("object_img", object_img)
# cv2.waitKey(0)
# 顯示匹配結果,匹配點爲藍點, 壞點爲紅點
draw_params = dict(matchColor=(255, 0, 0),
singlePointColor=(0, 0, 255),
matchesMask=matchesMask,
flags=0)
res = cv2.drawMatchesKnn(templet_img, kp_templet, object_img, kp_object, matches, None, **draw_params)
cv2.imshow("Result", res)
cv2.waitKey(0)
cv2.destroyAllWindows()
templet.png 如下:
object.png 如下:
結果如下:
templet.png 如下:
object.png 如下:
結果如下:
參考:
[1] David G. Lowe. Distinctive Image Features from Scale-Invariant Keypoints[J]. International Journal of Computer Vision, 60(2):91-110.
[2] SIFT特徵詳解
[3] https://www.imooc.com/article/30804
[4] https://blog.csdn.net/Jerseywwwwei/article/details/90647253