VLFeat指南——SIFT检测器和描述子

尺度不变特征变换(SIFT)包括一个特征检测器和一个特征描述子。特征检测器从一副图片中提取一些不受光照,视角等影响的特征区域。特征描述子就是用一个符号来简洁概要地表示区域特征。对这个算法更加深层次的描述,见http://www.vlfeat.org/api/sift_8h.html

提取结构和描述子

特征检测器和描述子都可以通过 vl_sift这个matlab命令来获取,打开matlab加载一幅图像:

I = vl_impattern('roofs1') ;
image(I) ;
input image
vl_sift这个matlab命令需要单精度灰度图像,同时也希望灰度值范围在[0,255]之间,所以图像I被转变为一下适合的格式:
I = single(rgb2gray(I)) ;
通过一下方式来计算sift结构(关键点)和描述子:
[f,d] = vl_sift(I) ;
对于矩阵f来说,每一列对应着一个关键点,一个关键点包括中心f(1:2),尺度f(3)和方向f(4)。我们随机选取50个特征并把它们显示出来:
perm = randperm(size(f,2)) ; //将1到f矩阵列数打算重排
sel = perm(1:50) ;	     //选取前50个
h1 = vl_plotframe(f(:,sel)) ;
h2 = vl_plotframe(f(:,sel)) ;
set(h1,'color','k','linewidth',3) ;	//着色:黑
set(h2,'color','y','linewidth',2) ;	//着色:黄

                                                                                 Some of the detected SIFT frames.
我们也可以把描述子覆盖到特征点上面:
h3 = vl_plotsiftdescriptor(d(:,sel),f(:,sel)) ;
set(h3,'color','g') ;

      
A test image for the peak threshold parameter.
基本匹配
sift描述子常用于发现两幅图之间的相似区域,vl_ubcmatch 实现了一个基本的匹配算法,Ia和Ib分别代表相同东西或景物的不同图片,我们用下面的方法提取和匹配描述子:
[fa, da] = vl_sift(Ia) ;
[fb, db] = vl_sift(Ib) ;
[matches, scores] = vl_ubcmatch(da, db) ;

    
                                
矩阵da中得每一个描述子,vl_ubcmatch finds 都在db中找到和它离得最近的一个(使用欧氏距离进行判断)。原始匹配的索引和每个最近描述子被存储在matches这个的矩阵的每一列中,每一个匹配对的距离存在了scores这个矩阵中。
也可以通过给vl_ubcmatch传递第三个参数给出一个阈值以保证匹配的唯一性,唯一性的判别是最好匹配点对和第二匹配点对距离的比例。

特征检测器参数
sift检测器主要通过两个参数来控制:顶峰阈值和边缘阈值。
峰阈除去了那些DoG尺度空间极值点中绝对值过小的那部分。举个例子,考虑2D模糊过的一个实验图片:
//产生一张图片
I = double(rand(100,500) <= .005) ;
I = (ones(100,1) * linspace(0,1,500)) .* I ;
I(:,1) = 0 ; I(:,end) = 0 ;
I(1,:) = 0 ; I(end,:) = 0 ;
I = 2*pi*4^2 * vl_imsmooth(I,4) ;
I = single(255 * I) ;
  
  A test image for the peak threshold parameter.
我们通过变换顶峰阈值peak_thresh运行检测器:
f = vl_sift(I, 'PeakThresh', peak_thresh) ;
当peak_thresh的值增大的时候得到的特证数在减少。
                                                             
                                                              Detected frames for increasing peak threshold.
From top: peak_thresh = {0, 10, 20, 30}.
对于边缘阈值来说,它的作用就是去除DoG尺度空间极值中主曲率过小的一部分(这样的极值点很难找到关键帧)。举个例子,用下面的测试图片:
I = zeros(100,500) ;
for i=[10 20 30 40 50 60 70 80 90]
I(50-round(i/3):50+round(i/3),i*5) = 1 ;
end
I = 2*pi*8^2 * vl_imsmooth(I,8) ;
I = single(255 * I) ;
  
A test image for the edge threshold parameter.
我们通过变换边缘阈值edge_thresh运行检测器:
f = vl_sift(I, 'edge_thresh', edge_thresh) ;
当edge_thresh增加的时候得到更多的特征
                     
Detected frames for increasing edge threshold.
From top:  edge_thresh = {3.5, 5, 7.5, 10}

定制帧
matlab命令vl_sift可以绕开检测器直接使用Frames选项定制地计算出描述子。举个例子,我们可以计算出sift帧在位置(100,100),尺度10以及方向
-pi/8处的描述子
fc = [100;100;10;-pi/8] ;
[f,d] = vl_sift(I,'frames',fc) ;
  
Custom frame at with fixed orientation.
复式帧fc也可以被指定。在这个例子中是通过增加尺度来重新排列的。Oreientations选项指导程序用位置和尺度来计算关键点方向:
fc = [100;100;10;0] ;
[f,d] = vl_sift(I,'frames',fc,'orientations') ;
  
Custom frame with computed orientations.

需要注意的是,根据局部区域的表现,一个关键点可能有多个方向,而且,在一个固定图片区域上计算的关键点是没有方向的。

惯例

在我们的实现中,sift帧是在标准图像坐标系中表示的,命令行和matlab版程序的区别在于后者假设图片原点坐标为(1,1),而前者原点坐标为(0,0)。Lowe的实现使用了另一个坐标系,我们将在下面介绍:



                                                                  
我们的使用惯例(下面)和Lowe的(下面)
我们的实现使用标准图像坐标系,y坐标轴指向下方。帧的方向θ和描述子使用了同一个坐标系。回想一下每一个描述子都是按照(θ,x,y)索引的一个箱子,直方图也是这样向量化的,因而θ是最快的索引,y是最慢的。
作为对比,D.Lowe的实现使用了一个稍微不同的惯例:帧的中心和标准图像坐标系一样,但是帧的方向以及描述子假设y轴指向上方。想把我们的实现映射到Lowe的上面,帧的方向需要去掉,描述子元素也要重新安排。

和Lowe的SIFT程序的对比(略)



  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值