Python计算机视觉——SIFT特征提取与检索

SIFT特征提取算法

1. 定义

SIFT的全称是Scale Invariant Feature Transform,尺度不变特征变换。是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出、不会因光照、仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。SIFT特征对旋转、尺度缩放、亮度变化等保持不变性,是一种非常稳定的局部特征。

2. 步骤

  1. 构建DOG尺度空间
  2. 关键点搜索和定位
  3. 方向赋值和特征描述的生成

3. 构造DOG尺度空间

模拟图像数据的多尺度特征,大尺度轮廓特征,小尺度细节特征。通过构建高斯金字塔(每一层用不同的参数σ做高斯模糊(加权)),保证图像在任何尺度都能有对应的特征点,即保证尺度不变性。

4. 图像尺度空间

在一定的范围内,无论物体是大还是小,人眼都可以分辨出来,然而计算机要有相同的能力却很难,所以要让机器能够对物体在不同尺度下有一个统一的认知,就需要考虑图像在不同的尺度下都存在的特点。

尺度空间的获取通常使用高斯模糊来实现,不同σ的高斯函数决定了对图像的平滑程度,越大的σ值对应的图像越模糊。
在这里插入图片描述
在这里插入图片描述

5. 多分辨率金字塔

图像金字塔是同一图像在不同的分辨率下得到的一组结果,一个传统的金字塔中,每一层的图像是其上一层图像长、高的各一半。

多分辨率的图像金字塔虽然生成简单,但其本质是降采样,图像的局部特征则难以保持,也就是无法保持特征的尺度不变性。

通过图像的模糊程度来模拟人在距离物体由远到近时物体在视网膜上成像过程,距离物体越近其尺寸越大图像也越模糊,这就是高斯尺度空间。通过结合高斯尺度空间和多分辨率金字塔可以检测出在不同的尺度下都存在的特征点。

在这里插入图片描述

6. 高斯差分金字塔

将相邻的两个高斯空间的图像相减就得到了DoG的响应图像。
在这里插入图片描述
在这里插入图片描述

7. 关键点搜索与定位

7.1 关键点搜索

为了寻找尺度空间的极值点,每个像素点要和其图像域(同一尺度空间)和尺度域(相邻的尺度空间)的所有相邻点进行比较,当其大于(或者小于)所有相邻点时,该点就是极值点。如下图所示,中间的检测点要和其所在图像的3×3邻域8个像素点,以及其相邻的上下两层的3×3领域18个像素点,共26个像素点进行比较。
在这里插入图片描述

7.2 关键点的精确定位

这些候选关键点是DOG空间的局部极值点,而且这些极值点均为离散的点,精确定位极值点的一种方法是,对尺度空间DoG函数进行曲线拟合,计算其极值点,从而实现关键点的精确定位。
在这里插入图片描述
在这里插入图片描述

7.3 消除边界响应

在这里插入图片描述

8. 方向赋值

8.1 特征点的主方向

每个特征点可以得到三个信息(x,y,σ,θ),即位置、尺度和方向。具有多个方向的关键点可以被复制成多份,然后将方向值分别赋给复制后的特征点,一个特征点就产生了多个坐标、尺度相等,但是方向不同的特征点。

在这里插入图片描述

9. 生成特征描述

在完成关键点的梯度计算后,使用直方图统计邻域内像素的梯度和方向。
在这里插入图片描述
为了保证特征矢量的旋转不变性,要以特征点为中心,在附近邻域内将坐标轴旋转θ角度,即将坐标轴旋转为特征点的主方向。
在这里插入图片描述
旋转之后的主方向为中心取8x8的窗口,求每个像素的梯度幅值和方向,箭头方向代表梯度方向,长度代表梯度幅值,然后利用高斯窗口对其进行加权运算,最后在每个4x4的小块上绘制8个方向的梯度直方图,计算每个梯度方向的累加值,即可形成一个种子点,即每个特征的由4个种子点组成,每个种子点有8个方向的向量信息。

在这里插入图片描述
论文中建议对每个关键点使用4x4共16个种子点来描述,这样一个关键点就会产生128维的SIFT特征向量。
在这里插入图片描述
参考文档:opencv SIFT特征提取

10. SIFT特征提取与检索实验

10.1 构造数据集

在这里插入图片描述

10.2 提取数据集中每张图片的SIFT特征并展示

使用开源工具包VLFeat提供的二进制文件来计算图像的SIFT特征。VLFeat工具包可以从http://www.vlfeat.org/下载,二进制文件可以在所有主要的平台上运行。将下载后的VLFeat解压,选择适合你电脑的位数。注意!!!官网上是最新的VLfeat-0.9.21版本,但最好选择VLfeat-0.9.20版本,如果用最新版本,有的电脑会出现生成的picture1.sift文件为空的情况,导致报错picture1.sift not found

Windows解压tar.gz文件办法

在这里插入图片描述
解压后打开bin文件夹下的win64,将其中的sift.exe和vl.dll这两个文件复制到项目的文件夹中。
不过解压完了进行了后续操作,还是报错…这是一个大坑,这是python2.7的解决方法…而我是python3.7
终于知道自己错在哪了…
python3 sift算法的简单实现
emmmmm坑实在是太多了,详解参见opencv-contrib-python,python3.3,SIFT和SURF

最后终于实现了sift算法:
代码:

"""
Created on Sat Sep 29 14:43:02 2018

@author: qgl
"""

import numpy as np
import cv2
from matplotlib import pyplot as plt


imgname = 'C://Users//Garfield//Desktop//dataunion//005.jpg'


sift = cv2.xfeatures2d.SIFT_create()

img = cv2.imread(imgname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kp, des = sift.detectAndCompute(img, None)

cv2.imshow('gray', gray)
#cv2.waitKey(0)

img1 = cv2.drawKeypoints(img, kp, img, color=(255, 0, 255))

cv2.imshow('point', img1)
cv2.waitKey(0)

在这里插入图片描述

实验结果截图:
在这里插入图片描述

(1)实现数据集中,每张图片的SIFT特征提取,并展示特征点

代码:

import os.path

import glob

import cv2


def convertjpg(jpgfile, outdir, width=128, height=128):
    src = cv2.imread(jpgfile, cv2.IMREAD_ANYCOLOR)

    try:

       
  • 20
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Python是一种功能强大的编程语言,在计算机视觉领域广泛应用。OpenCV是一个开源的计算机视觉库,提供了许多处理图像和视频的函数和方法。SIFT是一种常用的特征提取算法,可以在图像中检测出关键点,并生成特征向量。在这里,我们将介绍如何使用Python结合OpenCV实现SIFT特征提取与匹配。 使用Python实现SIFT特征提取的基本步骤如下: 1. 导入OpenCV库并读取图像 ``` import cv2 img = cv2.imread('image.jpg') ``` 2. 创建SIFT对象并检测关键点 ``` sift = cv2.xfeatures2d.SIFT_create() kp, des = sift.detectAndCompute(img, None) ``` 通过使用SIFT对象的detectAndCompute()函数,我们可以对图像进行关键点检测和特征描述符提取,并将结果保存在两个变量kp和des中。 3. 可视化关键点并保存图像 ``` img_kp = cv2.drawKeypoints(img, kp, None) cv2.imshow('Keypoints', img_kp) cv2.imwrite('output.jpg', img_kp) cv2.waitKey() ``` 在这个步骤中,我们使用drawKeypoints()函数将检测到的关键点绘制在图像上,并可以通过imshow()函数显示图像。然后,我们可以使用imwrite()函数将图像保存到本地。 实现SIFT特征匹配的基本步骤如下: 1. 读取并检测两张图像的关键点和描述符 ``` import cv2 img1 = cv2.imread('image1.jpg') img2 = cv2.imread('image2.jpg') sift = cv2.xfeatures2d.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) ``` 2. 创建并运行暴力匹配器 ``` bf = cv2.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) ``` 3. 使用比值测试来筛选出良好的匹配 ``` good_matches = [] for m, n in matches: if m.distance < 0.75 * n.distance: good_matches.append([m]) ``` 4. 可视化匹配点并保存图像 ``` img_matched = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good_matches, None, flags=2) cv2.imshow('Matching result', img_matched) cv2.imwrite('output.jpg', img_matched) cv2.waitKey() ``` 在步骤2中,我们使用了暴力匹配器BFMatcher()来对特征描述符进行匹配。knnMatch()函数返回的是最近邻和次近邻的描述符距离,我们可以用比值测试筛选出距离最近的描述符,并将其作为好的匹配。最后,我们使用drawMatchesKnn()可以将匹配点绘制在图像上,并通过imshow()函数显示图像。最后,我们可以通过imwrite()函数保存图像。 综上所述,使用Python结合OpenCV实现SIFT特征提取和匹配非常简单。利用OpenCV中的函数和方法,我们可以轻松地处理图像和视频,实现各种计算机视觉应用。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值