尺度不变特征变换(Scale-invariant feature transform,SIFT)
Posted yddcs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尺度不变特征变换(Scale-invariant feature transform,SIFT)相关的知识,希望对你有一定的参考价值。
尺度不变特征变换 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()
# 使用SIFT查找关键点key points和描述符descriptors
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()
# K近邻算法求取在空间中距离最近的K个数据点,并将这些数据点归为一类
matcher = cv2.BFMatcher()
raw_matches = matcher.knnMatch(des1, des2, k = 2)
good_matches = []
for m1, m2 in raw_matches:
# 如果最接近和次接近的比值大于一个既定的值,那么我们保留这个最接近的值,认为它和其匹配的点为good_match
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)
# 单应性矩阵有八个参数,每一个对应的像素点可以产生2个方程(x一个,y一个),那么需要四个像素点就能解出单应性矩阵
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)
以上是关于尺度不变特征变换(Scale-invariant feature transform,SIFT)的主要内容,如果未能解决你的问题,请参考以下文章
Paper ReadingObject Recognition from Scale-Invariant Features
OpenCV 例程 300篇241. 尺度不变特征变换(SIFT)