尺度不变特征变换 SIFT
找论文实用工具 Sci-Hub 实时更新 : https://tool.yovisun.com/scihub/ 公益科研通文献求助:https://www.ablesci.com/ 给个三连吧🙃
步骤:
- 构建尺度空间,检测极值点,获得尺度不变性。
- 特征点过滤并进行精确定位。
- 为特征点分配方向值。
- 生成特征描述子。
SIFT特点:图像的局部特征,对旋转、尺度缩放、亮度变化保持不变,对视角变化、仿射变换、噪声也保持一定程度的稳定性。
独特性好,信息量丰富,适用于海量特征库进行快速、准确的匹配; 多量性,即使是很少几个物体也可以产生大量的SIFT特征; 高速性,优化后的SIFT匹配算法甚至可以达到实时性; 扩展性,可以很方便的与其他的特征向量进行级联组合。
CNN:能够有效的将大数据量的图片降维成小数据量; 能有效的保留图片特征,符合图片处理的原则。
使用场景:
图像的预处理,将彩色图像变成灰度图像; 将图像缩放到相同大小尺寸。 与CNN结合使用的可能性:在特征提取方面进行结合,比如用模板匹配+CNN结合做模型学习,从而提高准确率。
python实现代码:
import cv2, os, sys, time
import numpy as np
image1 = cv2.imread("./CV_101/1.jpg", 0)
image2 = cv2.imread("./CV_101/c1.png", 0)
cv2.imshow('image1', image1)
cv2.imshow('image2', image2)
start = time.time()
sift = cv2.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(image1, None)
kp2, des2 = sift.detectAndCompute(image2, None)
end = time.time()
print("特征点提取&生成描述运行时间:%.2f秒"%(end-start))
kp_image1 = cv2.drawKeypoints(image1, kp1, None)
kp_image2 = cv2.drawKeypoints(image2, kp2, None)
cv2.imshow('kp-image1', kp_image1)
cv2.imshow('kp-image2', kp_image2)
print("关键点数目:", len(kp1))
for i in range(2):
print("关键点", i)
print("数据类型:", type(kp1[i]))
print("关键点坐标:", kp1[i].pt)
print("邻域直径:", kp1[i].size)
print("方向:", kp1[i].angle)
print("所在的图像金字塔的组:", kp1[i].octave)
print("描述的shape:", des1.shape)
for i in range(2):
print("描述", i)
print(des1[i])
ratio = 0.85
start = time.time()
matcher = cv2.BFMatcher()
raw_matches = matcher.knnMatch(des1, des2, k = 2)
good_matches = []
for m1, m2 in raw_matches:
if m1.distance < ratio * m2.distance:
good_matches.append([m1])
end = time.time()
print("匹配点匹配运行时间:%.2f秒"%(end-start))
matches = cv2.drawMatchesKnn(image1, kp1, image2, kp2, good_matches, None, flags = 2)
cv2.imshow('matches', matches)
print("匹配对的数目:", len(good_matches))
for i in range(2):
print("匹配", i)
print("数据类型:", type(good_matches[i][0]))
print("描述符之间的距离:", good_matches[i][0].distance)
print("查询图像中描述符的索引:", good_matches[i][0].queryIdx)
print("目标图像中描述符的索引:", good_matches[i][0].trainIdx)
if len(good_matches) > 4:
start = time.time()
ptsA= np.float32([kp1[m[0].queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
ptsB = np.float32([kp2[m[0].trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
ransacReprojThreshold = 4
H, status =cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold);
imgOut = cv2.warpPerspective(image2, H, (image1.shape[1],image1.shape[0]),flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
end = time.time()
print("匹配运行时间:%.2f秒"%(end-start))
cv2.imshow('out', imgOut)
cv2.waitKey(0)
|