当前位置: 首页 > news >正文

图像特征检测算法SIFT

SIFT(Scale - Invariant Feature Transform,尺度不变特征变换)是一种计算机视觉领域的特征提取算法,具有重要的地位和广泛的应用。

算法原理

  • 构建高斯金字塔

为了实现多尺度检测,SIFT 算法会构建高斯金字塔。首先将原始图像进行高斯模糊,然后依次对模糊后的图像进行降采样,每次降采样后图像尺寸减半,从而得到一系列不同尺度的图像,构成一个八度。通常会构建多个八度,每个八度包含若干层,以覆盖不同的尺度范围。

  • 差分高斯金字塔与关键点检测

基于高斯金字塔构建差分高斯金字塔,即将同一八度中相邻两层高斯图像相减得到。关键点检测就是在这个差分高斯金字塔中,通过寻找每个样本点在周围邻域中的极值点来确定。具体来说,对于每个图像点,会将其与同层相邻的 8 个点以及上下层相邻的 9 个点(共 26 个点)进行比较,如果该点的差分高斯响应值是这 26 个点中的最大值或最小值,则认为该点是一个极值点,即候选关键点。

  • 关键点定位与筛选

为了提高关键点的定位精度,并去除一些低对比度的关键点和不稳定的边缘响应点,需要对初步检测到的关键点进行定位和筛选。通过拟合三维二次函数到邻域像素来对关键点的位置和尺度进行迭代精修,确定其精确位置和对应的尺度。同时,计算关键点的对比度,去除对比度过低的点,以确保关键点的稳定性。

  • 关键点方向赋值

为了使关键点具有旋转不变性,需要为每个关键点分配一个方向。在关键点的邻域内,利用高斯加权函数计算图像梯度的方向直方图。直方图的峰值方向即为该关键点的主方向,关键点的方向由其邻域内梯度的方向分布情况来确定,从而使得关键点描述子具有旋转不变性。

  • 关键点描述子生成

在关键点周围选取一个邻域,将该邻域分成多个子区域,例如将 16×16 的邻域分成 16 个 4×4 的子区域。在每个子区域内计算梯度的方向直方图,通常使用 8 个方向作为直方图的柱,从而得到每个子区域的 8 维向量。将所有子区域的向量连接起来,就形成了一个 128 维的向量作为该关键点的描述子。

特点

  • 尺度不变性 :能够在不同尺度的图像中检测到相同的特征点,对图像的缩放具有很强的鲁棒性。

  • 旋转不变性 :通过为关键点赋予方向,使得描述子与关键点的方向相关,从而在图像旋转时仍能保持匹配的准确性。

  • 局部性与鲜明性 :提取的特征是图像中的局部特征,具有鲜明的局部信息,能够很好地抵抗遮挡、光照变化等问题,且在图像中具有较高的独特性,便于区分不同的物体或场景。

  • 可重复性与稳定性 :对于同一场景或物体的不同图像,能够稳定地提取出相似的关键点,减少了特征点的丢失和误检,具有较高的可重复性。

应用

  • 图像匹配 :在全景图拼接、图像搜索、目标识别等需要对两幅或多幅图像进行匹配的场景中,SIFT 算法被广泛应用。通过提取并匹配两幅图像中的 SIFT 特征,可以确定图像之间的对应关系,进而实现图像的拼接、查询或识别。

  • 目标识别与定位 :在机器人导航、自动驾驶、工业自动化等领域,SIFT 特征可用于识别和定位目标物体。例如,在自动驾驶中,通过对道路标志或车辆的 SIFT 特征进行匹配和识别,帮助车辆实现自主导航和目标检测。

  • 三维重建 :在基于图像的三维重建中,SIFT 特征用于确定多幅图像之间的特征对应关系,从而计算出相机的内外参数以及场景的三维结构信息。

优点与缺点

  • 优点 :能够自动检测出大量的特征点,且具有良好的重复性和稳定性,对尺度、旋转、光照变化以及一定程度的仿射变换具有鲁棒性,特征的区分能力较强,适合于大规模的图像匹配和目标识别任务。

  • 缺点 :计算复杂度较高,尤其是在处理高分辨率图像或多幅图像进行匹配时,计算速度可能会较慢。此外,SIFT 算法在面对视角变化较大、特征重复性较高或者存在大量相似特征的场景时,可能会出现一定的匹配错误或特征点匹配不足的问题。

环境准备

  • Python :确保已安装 Python 环境,推荐 3.6 及以上版本。

  • OpenCV :通过 pip install opencv-python 命令安装 OpenCV 库,它提供了丰富的计算机视觉功能,包括 SIFT 算法。

使用示例代码

import cv2
import numpy as np# 读取图像
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)# 初始化 SIFT 检测器
sift = cv2.SIFT_create()# 检测关键点和计算描述符
keypoints1, descriptors1 = sift.detectAndCompute(img1, None)
keypoints2, descriptors2 = sift.detectAndCompute(img2, None)# 使用 FLANN 进行特征匹配
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(descriptors1, descriptors2, k=2)# 应用比率测试筛选匹配项
good_matches = []
for m, n in matches:if m.distance < 0.7 * n.distance:good_matches.append(m)# 获取匹配点的坐标
src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)# 计算单应性矩阵
if len(good_matches) > 4:M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)matches_mask = mask.ravel().tolist()
else:matches_mask = None# 绘制匹配结果
draw_params = dict(matchColor=(0, 255, 0),singlePointColor=None,matchesMask=matches_mask,flags=2)result_img = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches, None, **draw_params)
  • 关键点检测与描述符计算sift.detectAndCompute() 函数用于检测图像中的关键点并计算对应的描述符。

  • 特征匹配 :使用 FLANN(快速最近邻搜索)匹配算法进行特征匹配,knnMatch() 方法返回每个特征点的两个最近邻匹配。

  • 比率测试 :通过比较两个最近邻匹配的距离,筛选出高质量的匹配项,以减少误匹配。

  • 单应性计算 :如果匹配项数量足够(大于 4 个),使用 RANSAC 算法计算单应性矩阵,用于确定图像之间的几何变换关系。

  • 结果绘制cv2.drawMatches() 函数用于绘制匹配结果,显示在图像上。

注意事项

  • 专利问题 :SIFT 是专利算法,虽专利已过期,但商业使用时仍需考虑许可问题。

  • 计算复杂度 :SIFT 算法计算复杂度较高,处理大图像时可能耗时较长。

http://www.lryc.cn/news/572044.html

相关文章:

  • 实现自动胡批量抓取唯品会商品详情数据的途径分享(官方API、网页爬虫)
  • python校园拼团系统
  • voronoi图,凸壳,和早已遗忘的定不定积分
  • LangChain中的向量数据库抽象基类-VectorStore
  • MySQL存储引擎深度解析:InnoDB、MyISAM、MEMORY 与 ARCHIVE 的全面对比与选型建议
  • Docker PowerJob
  • 今天我想清楚了
  • Conda 常用命令大全:从入门到高效使用
  • Vue添加图片作为水印
  • 最大公约数
  • Espresso + Java 详细示例
  • 【音视频】PJSIP库——pjsua命令使用详解
  • CANFD加速是什么?和CANFD有什么区别?
  • 自演进多智能体在医疗临床诊疗动态场景中的应用
  • Jenkins审核插件实战:实现流水线审批控制的最佳实践
  • Vue.js第二节
  • 使用Trace分析Android方法用时
  • 利用Java进行验证码的实现——算数验证码
  • 【AI Study】第四天,Pandas(7)- 实际应用
  • 【图像处理基石】什么是EIS和OIS?
  • C++ Primer Plus 9.2.7 mutable
  • FPGA基础 -- Verilog 行为级建模之条件语句
  • ChromaDB完全指南:从核心原理到RAG实战
  • STM32 串口寄存器开发
  • 148. 排序链表
  • 前端开发面试题总结-vue2框架篇(四)
  • Flask视频和图片上传
  • MongoDB学习记录(快速入门)
  • 26.多表查询
  • Vue 二维码组件