个人博客原文:外链网址已屏蔽
这是一次作业,内容是给出两张图像,检测特征点和匹配特征点。要求不能用诸如OpenCV的现成特征点检测函数。于是就只能造轮子了,写了这个Matlab版的sift。(其实就是把c语言的opensift翻译成了matlab
以下是算法流程,其实网上的类似博文已经很多了,只不过我看的过程中也看得不很明白,只能对照着好几个看,所以干脆自己又写了一遍。下面的图均来自于参考资料中,然而参考资料的图也是来自于参考资料的参考资料中。
1. 构建尺度空间
定理1 对图像做 σ=σ1 的高斯平滑,再做一次 σ=σ2 的高斯平滑,等效于对原图像做一次 σ=σ21+σ22−−−−−−√ 的高斯平滑。
1.1 构建高斯金字塔
高斯卷积核是实现尺度变换的唯一线性核(Koenderink, 1984; Lindeberg, 1994)。
一幅图像的尺度空间被定义为对其做可变尺度的高斯卷积:
L(x,y,σ)其中G(x,y,σ)=G(x,y,σ)∗I(x,y)=12πσ2e−(x2+y2)/2σ2
对于给定的彩色图像,转化为灰度图像,用不同大小的σ做高斯平滑(按照 3σ 准则,高斯核矩阵的大小设为 (6σ+1)⋅(6σ+1) ,并保证行和列为奇数),再此基础上将图像降采样得到不同大小的组(octave),每组若干图像(interval)。详细描述如下:
为了得到更多的特征点,将图像扩大为原来的两倍。假设原图像已有 σ=0.5 的高斯平滑,而我们需要第一个octave的第一张图像的 σ=1.6 ,按照定理1,我们要对扩大两倍的图像做一次高斯平滑,σ=1.62−(0.5×2)2−−−−−−−−−−−−−√ 。
上一个octave的图像的长度和宽度分别是下一个octave的图像的两倍。因此图像组数(octaves)可由图像大小决定,将其设为 log2(min(height,width)) −2 ,这样将使顶层octave图像的长度和宽度最小值在8像素左右。
设第m个octave的第n张图像相对于原始图像的参数σ为 sigma(m,n),则sigma(1,1)=σ0=1.6。每个octave有s+1张图像(即intervals),这样得到的高斯差分金字塔(DoG)每个octave将有s张图像,我们设s为3。为了满足在不同octave间尺度的连续性,并使 sigma(m,n)= 2⋅sigma(m−1,n),按照定理1,则:
sigma(1,n)sigma(m,n)=σ0⋅kn−1,其中k=21/s=σ0⋅2m−1⋅kn−1
如上图所示,在第一个octave中尺度为k3⋅σ0的“最后”一张图像进行下采样得到第二个octave的第一张图像,尺度仍为k3⋅σ0=2⋅σ0。
但实际上我们需要做出更多不同尺度的高斯平滑图像,这是因为在后续高斯差分金字塔的极值检测中,需要前后两级尺度都存在图像。如图中红框所示,高斯差分金字塔中每个octave有s幅图像,则需要高斯金字塔中每个octave包含s+3幅图像。其中第s+1幅图像用作下一个octave第一幅图像的降采样。
具体实现中并未对单幅图像多次进行高斯平滑,而是由上一幅图像进行高斯平滑得到下一幅图像并迭代之,按照定理1计算σ。
1.2 构建高斯差分金字塔
对两幅高斯金字塔的图像作差。