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

SIFT算法概述及相关原理

实现流程

SIFT算法的实质可以归为在不同尺度空间上查找特征点(关键点)的问题。
SIFT算法实现特征匹配主要有三个流程:1、提取关键点; 2、对关键点附加详细的信息(局部特征),即描述符;3、通过特征点(附带上特征向量的关键点)的两两比较找出相互匹配的若干对特征点,建立景物间的对应关系。

尺度空间

它可以模拟人在距离目标由近到远的过程中,目标在视网膜当中形成图像的过程,尺度越大越模糊,相当于我们观察远处的物体。如果需要识别出包含不同尺寸的同一物体的两幅图像,随着物体在图像中大小发生变化,属于该物体的局部区域的大小也会发生变化。SIFT算法采用高斯图像金字塔,对图像做高斯平滑和降采样,一幅图像可以产生几组图像,一组图像包括几层图像,从而实现尺度的连续性。高斯核是唯一可以产生 多尺度空间的核,一个 图像的尺度空间,L(x, y, σ) ,定义为原始图像 I(x, y)与一个可变尺度的2 维高斯函数G(x, y, σ) 卷积运算。
高斯
尺度归一化的高斯拉普拉斯算子能够得到最稳定的图像特征,但因为计算量太大,所以引入了高斯差分金字塔(DOG),DoG在计算上只需相邻高斯平滑后图像相减,即高斯差分金字塔的第1组第1层是由高斯金字塔的第1组第2层减第1组第1层得到的,以此类推,逐组逐层生成每一个差分图像,所有差分图像构成差分金字塔,每一组在层数上,高斯差分金字塔比高斯金字塔少一层,从而简化了计算。
尺度变换

高斯模糊

高斯模糊是在Adobe Photoshop等图像处理软件中广泛使用的处理效果,通常用它来减小图像噪声以及降低细节层次。这种模糊技术生成的图像的视觉效果是好像经过一个半透明的屏幕观察图像。
 根据σ的值,计算出高斯模板矩阵的大小(6σ+1)(6σ-1),使用公式计算高斯模板矩阵的值,与原图像做卷积,即可获得原图像的平滑(高斯模糊)图像。为了确保模板矩阵中的元素在[0,1]之间,需将模板矩阵归一化。55的高斯模板如下所示。
高斯模板
下图是5
5的高斯模板卷积计算示意图。高斯模板是中心对称的。
示意图

高斯金字塔

对某一灰度图像,首先进行升采样(即扩大两倍采样),然后对升采样之后的图片进行高斯模糊,从而生成一组采样图。(注:升采样不是必须的)
对原灰度图像进行降采样,然后高斯模糊,得到第二组采样图,每一组都有六层尺寸相同但模糊系数不同的采样图像得到。为了保持差分高斯金字塔的尺度空间(即模糊系数)的连续性,下一组(第i组)的第一层由上一组的第四层降采样之后得到,同时第i组的后面几层都是由该组第一层经过高斯模糊得到,不需要进行降采样。这样,几组采样图组合在一起,就构成了高斯金字塔。如下图所示:
金字塔

DOG函数

函数
在计算时,使用高斯金字塔每组中相邻上下两层图像相减,得到高斯差分图像
差分图像
图像上的像素值如果没有变化,也就没有特征。特征必须是变化尽可能多的点。DOG图像描绘的是目标的轮廓。
特征点是由DOG空间的局部极值点组成的。为了寻找尺度空间的极值点,每个像素点要和该点的周围所有相邻点进行比较,当其与相邻点有明显差别的灰度值时,该点就是极值点。
 此时找到的极值点标为候选特征点,因为存在噪声的干扰。如图所示,中间的检测点要和其所在图像的3×3邻域8个像素点,以及其相邻的上下两层的3×3领域18个像素点,共26个像素点进行比较,确保在尺度空间和二维图像空间都检测到极值点。
局部
 从上面的描述中可以知道,每组图像的第一层和最后一层是无法进行比较取得极值的。为了满足尺度变换的连续性,在每一组图像的顶层继续使用高斯模糊生成3幅图像,高斯金字塔每组有S+3层图像,DoG金字塔的每组有S+2组图像。这样产生的极值点并不全都是稳定的特征点,因为某些极值点响应较弱,而且DOG算子会产生较强的边缘响应。
通过比较检测得到的DoG的局部极值点是在离散的空间搜索得到的,由于离散空间是对连续空间采样得到的结果,物体的边缘轮廓在灰度图中,存在着灰度值的突变,这样的点在计算中就被“误以为”是特征值。因此在离散空间找到的极值点不一定是真正意义上的极值点,因此要将不满足条件的点剔除掉。
 DoG函数的峰值点在边缘方向有较大的主曲率,而在垂直边缘的方向有较小的主曲率。主曲率可以通过计算在该点位置尺度的2×2的Hessian矩阵得到,导数由采样点相邻差来估计
 导数
Dxx 表示DOG金字塔中某一尺度的图像x方向求导两次
D的主曲率和H的特征值成正比。令 α ,β为特征值,则
求导
该值在两特征值相等时达最小。Lowe论文中建议阈值T为1.2,即
阈值时保留关键点,反之剔除。
主要删除两类:低对比度的极值点以及不稳定的边缘响应点。

赋值主方向

为了实现图像旋转不变性,需要给特征点的方向进行赋值。利用特征点邻域像素的梯度分布特性来确定其方向参数,再利用图像的梯度直方图求取关键点局部结构的稳定方向。
像素点的梯度表示:
梯度
梯度幅值:幅值
梯度方向:方向
利用以特征点为中心划出周边的16 x 16图像块,计算每个点的幅值和梯度方向,再离散为8(根据划分的角度设定)个bin方向,产生离散直方图
 直方图:计算得到梯度方向后,使用直方图统计特征点邻域内像素对应的梯度方向和幅值。梯度方向的直方图的横轴是梯度方向的角度(这里以8个为例),纵轴是梯度方向对应梯度幅值的累加,在直方图的峰值就是特征点的主方向。
方向
 关键点主方向:极值点周围区域梯度直方图的主峰值也是特征点方向
 关键点辅方向:在梯度方向直方图中,当存在另一个相当于主峰值80%能量的峰值时,则将这个方向认为是该关键点的辅方向
 因此,对于同一梯度值的多个峰值的关键点位置,在相同位置和尺度将会有多个关键点被创建但方向不同。仅有15%的关键点被赋予多个方向,但可以明显的提高关键点匹配的稳定性。实际编程实现中,就是把该关键点复制成多份关键点,并将方向值分别赋给这些复制后的关键点,并且,离散的梯度方向直方图要进行插值拟合处理,来求得更精确的方向角度值。

关键点特征描述

以旋转之后的主方向为中心取8x8的窗口,左图中点为当前关键点的位置,每一个小格都代表了特征点邻域所在的尺度空间的一个像素,箭头方向代表了像素梯度方向,箭头长度代表该像素的幅值。然后在每个4x4的小块上绘制8个方向的梯度直方图,计算每个梯度方向的累加值,即可形成一个种子点,如右图所示,每个特征的由4个种子点组成,每个种子点有8个方向的向量信息,这种邻域方向性信息联合增强了算法的抗噪能力,同时对于含有定位误差的特征匹配也提供了比较理性的容错性。
关键
关键
旋转后的新坐标:坐标
Lowe实验结果表明:描述子采用4×4×8=128维向量表征综合效果最优

关键点匹配

分别对模板图和实时图建立关键点描述子集合。目标的识别是通过两点集内关键点描述子的比对来完成。具有128维的关键点描述子的相似性度量采用欧式距离
穷举匹配:
匹配
对比次数过多,算法复杂度大,因此不采用。一般都采用kd树的数据结构来完成搜索。搜索的内容是以目标图像的关键点为基准,搜索与目标图像的特征点最邻近的原图像特征点和次邻近的原图像特征点。

RANSAC算法去除SIFT匹配出的错误点

算法介绍

随机抽样一致算法(random sample consensus,RANSAC)采用迭代的方式从一组包含离群的被观测数据中估算出数学模型的参数。
RANSAC算法的基本假设是样本中包含正确数据(inliers,可以被模型描述的数据),也包含异常数据(outliers,偏离正常范围很远、无法适应数学模型的数据),即数据集中含有噪声。这些异常数据可能是由于错误的测量、错误的假设、错误的计算等产生的。同时RANSAC也假设,给定一组正确的数据,存在可以计算出符合这些数据的模型参数的方法。

单应性变换

如果场景是平面,或者近似平面,或者低视差时,我们能应用单应性矩阵(homography)
单应性变换是将一个平面内的点映射到另一个平面内的二维投影变换。在这里,平面是指图像或者三维中的平面表面。
单应性变换的目标是通过给定的几个点(通常是4对点)来得到单应性矩阵。
用一个3x3的矩阵来表示单应性,可以写成
单应性矩阵
考虑第一组对应点(X1, Y1)在第一张图像和(X2, Y2)第二张图像中。然后,Homography H以下列方式映射它们
映射
坐标变换:
坐标
要得到两张图片的H矩阵,就必须至少知道4个相同对应位置的点,通常,这些点对应是通过匹配图像之间的SIFT或Harris等特征自动找到的。在本次实验中通过SIFT特征匹配找到这些对应点

算法流程

  1. 随机选择四对匹配特征
  2. 根据DLT计算单应矩阵H(唯一解)
  3. 对所有匹配点,计算映射误差
  4. 根据误差阈值,确定inliers (例如3-5像素)
  5. 重复1-4,直到所有的匹配特征都被计算过
  6. 针对最大inliers集合,重新计算单应矩阵H

代码

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

# -*- coding: utf-8 -*-
from PIL import Image
from pylab import *
from PCV.localdescriptors import sift
from PCV.localdescriptors import harris

# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)

imname = 'image/tom2.jpg'
im = array(Image.open(imname).convert('L'))
sift.process_image(imname, 'tom2.sift')
l1, d1 = sift.read_features_from_file('tom2.sift')

figure()
gray()
subplot(131)
sift.plot_features(im, l1, circle=False)
title(u'SIFT特征',fontproperties=font)
subplot(132)
sift.plot_features(im, l1, circle=True)
title(u'用圆圈表示SIFT特征尺度',fontproperties=font)

# 检测harris角点
harrisim = harris.compute_harris_response(im)

subplot(133)
filtered_coords = harris.get_harris_points(harrisim, 6, 0.1)
imshow(im)
plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
axis('off')
title(u'Harris角点',fontproperties=font)

show()

给定两张图片,计算其SIFT特征匹配结果

from PIL import Image
from pylab import *
import sys
from PCV.localdescriptors import sift


if len(sys.argv) >= 3:
  im1f, im2f = sys.argv[1], sys.argv[2]
else:
#  im1f = '../data/sf_view1.jpg'
#  im2f = '../data/sf_view2.jpg'
  im1f = 'data/bui3.jpg'
  im2f = 'data/bui4.jpg'
#  im1f = '../data/climbing_1_small.jpg'
#  im2f = '../data/climbing_2_small.jpg'
im1 = array(Image.open(im1f))
im2 = array(Image.open(im2f))

sift.process_image(im1f, 'out_sift_1.txt')
l1, d1 = sift.read_features_from_file('out_sift_1.txt')
figure()
gray()
subplot(121)
sift.plot_features(im1, l1, circle=False)

sift.process_image(im2f, 'out_sift_2.txt')
l2, d2 = sift.read_features_from_file('out_sift_2.txt')
subplot(122)
sift.plot_features(im2, l2, circle=False
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值