写在前面
-----------------------------------------------------------------------------------------------
最近在研究图像检索这方面知识,作为记录。
文章内容理解需要一定的算法基础,当然也有可能是我能力有限,表述不清楚。
声明:本文章仅供个人学习之用,由于作者能力有限,相关观点和信息仅供参考。
如有侵权请联系。
欢迎各位读者老爷提问和交流。
我们的目标是星辰大海!
一. 算法介绍
Scale-invariant feature transform,SIFT,尺度不变特征变换算法,相对来说比较老,但是是传统方法的基础,比较经典。
引入了尺度的概念,在不同尺度的空间查找特征点。提取极值点,位置,尺度,旋转不变量。
因此算法的特点
1.对物体遮挡部分侦测效果好
2.与影像的大小和旋转无关,对光线、噪声、微视角改变的容忍度高。
3. 3个或者3个以上的SIFT物体特征就可以计算出位置与方位,辨识速度接近实时,适合在海量数据库中快速精确匹配。
二. 算法基本原理
什么是尺度不变性?
同一个物体,人眼在距离10米和距离100米看到的大小不一样,是因为视网膜上成像的图像尺寸发生了变化。
而尺度不变,意味着不管距离10米或者距离100米,都能够对图像进行清晰的辨认。
SIFT算法原理大致拆分如下
01 适当地模糊和加倍输入图像以生成图像金字塔的基础图像
02 计算图像金字塔中的层数
03 创建一个尺度列表(大小与高斯核大小相同)
04 反复模糊和下采样基础图像
05 减去相邻的高斯图像对,形成高斯查分的DoG图像金字塔
06 识别关键点
07 通过删除重复项并将它们转换为输入图像大小来清理这些关键点
08 为每个关键点生成描述符
09 特征点匹配
算法内容我不献丑了,我也是简单了解学习。
参考文献[1]算是一篇保姆级文章。
我自己也实际上测试了下,效果图入下:
图1: 左1为原图,右1为待匹配的图
代码跑起来速度特别慢,测试这两张图片耗时3分钟,我一度以为我电脑卡了。
图2:匹配效果图
单纯看效果来说, 需要表达的都体现到了,而且图像也存在偏移和旋转倾斜,也能匹配。
接下来还是测试了python自带opencv包实现
三. python代码实现
写在前面,
关于python使用cv的sift问题请参考如下链接
问题:sift = cv2.xfeatures2d.SIFT_create()-2022解决办法
ok,开始。
01 加载图像,调用库函数,计算关键点。
sift = cv2.SIFT_create()
cv2.drawKeypoints(image2, kp2, None)
效果如下:
图3: 原图(上)与关键点图(下)对比
step02
使用knn求取在空间中距离最近的k个数据点,进行分类
matcher = cv2.BFMatcher()
raw_matches = matcher.knnMatch(des1, des2, k = 2)
step03
使用像素点进行适应矩阵求解
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)
最终匹配结果如下:
图4 匹配结果图
与上面的代码对比,cv自带的算法运行时间更快。
确实能够达到实时监测的效果。
ps:
写在后面
SIFT作为传统算法,我个人只做了解,后续还是研究深度学习在图像检索方向的应用。
(有需要代码和效果图的小伙伴可以联系我)