OpenCV Extra 02 - SIFT&SURF

3,376 阅读4分钟

SIFT & SURF

两者都是特征检测的算法,但略有不同。

一、SURF

1. 背景及来源

使用SIFT算法进行关键点检测和描述的执行速度比较慢,需要速度更快的算法。SURF算法由Bay在2006年提出,是SIFT算法的增强版,其计算量小,运算速度快,提取的特征和SIFT几乎无二。

2. 二者对比

  1. 特征点检测
    1. SIFT:使用不同尺度的图片与高斯函数进行卷积
    2. SURF:使用不同大小的盒状滤波器和原始图像卷积,易于并行
  2. 方向
    1. SIFT:关键点邻接矩形区域内,利用梯度直方图计算
    2. SURF:关键点邻接圆域内,计算x,y方向的haar小波
  3. 描述符生成
    1. SIFT:关键点邻域内划分d*d个子区域,每个子区域内计算8个方向的直方图
    2. SURF:关键点邻域内划分d*d个子区域,每个子区域计算采样点的haar小波响应,并记录:dx,dy,dx,dy\sum dx,\sum dy,\sum |dx|, \sum |dy|

二、SIFT(Scale-invariant feature transform)

尺度不变特征转换,之前提过角点检测,但是当放大图像时,原窗口内的像素集合可能构不成角点,所以我们就提出了SIFT解决此类问题。

1. 概述

  1. 来源

    1. 作者:David Lowe
    2. 专利权属于英属哥伦比亚大学
  2. 算法示例

image-20220601175646058.png

2. 建立高斯差分金字塔

  1. 示例

    1. 高斯金字塔

image-20220601174745673.png

  1. 高斯差分金字塔

image-20220601174800794.png

  1. 其中,Ocative表示第 n 组,每组的层数不固定,但是上下层之间的像素大小是相差2倍(上面比下面小两倍)。以第一组为例,我们先使用方差为σ\sigma(尺度)的高斯滤波器对原图像进行卷积,第二组的各像素层是基于第一层的像素点进行隔点取点(下采样),并使用方差为2σ2\sigma(尺度)的高斯滤波器对下采样结果进行卷积获得。

  2. 层级关系

    1. 一幅图像的最佳组数:O=log2(min(M,N))3O = log_2(min(M,N)) - 3,这里的M,N是原图像的尺寸
    2. 每组的最佳层数:S=n+3S = n + 3,这里的 n 是欲得到的极值点个数(提取特征的层数)
  3. 各组层的σ\sigma关系

image-20220601163151895.png 其中,k=21n,σ0=1.620.52=1.52k = 2^{\frac{1}{n}}, \sigma_0 = \sqrt{1.6^2 - 0.5^2} = 1.52

  1. 其中,将下面一组的倒数第二层作为上面一组的倒数第一层,因为下采样的干系。

3. 极值点的精确定位

  1. 阈值化

    1. abs(val)=0.5T/nabs(val) = 0.5*T/n,此处的n是想要提取特征的层数
    2. T是常数,论文中为 0.04。
  2. 在高斯差分金字塔中找极值

    1. 图示

image-20220601174847827.png

  1. 调整极值点位置

    在第二步检测到的极值点X0(x0,y0,σ0)TX_0(x_0,y_0,\sigma_0)^T处做三元二阶泰勒展开:f([xyσ])=f([x0y0σ0])+[fx,fy,fσ]([xyσ][x0y0σ0])+12([xyσ][x0y0σ0])T[2fxx,2fxy,2fxσ2fxy,2fyy,2fyσ2fxσ,2fyσ,2fσσ]([xyσ][x0y0σ0])f\left(\left[\begin{array}{l}x \\y \\\sigma\end{array}\right]\right)=f\left(\left[\begin{array}{l}x_{0} \\y_{0} \\\sigma_{0}\end{array}\right]\right)+\left[\frac{\partial f}{\partial x}, \frac{\partial f}{\partial y}, \frac{\partial f}{\partial \sigma}\right]\left(\left[\begin{array}{l}x \\y \\\sigma\end{array}\right]-\left[\begin{array}{l}x_{0} \\y_{0} \\\sigma_{0}\end{array}\right]\right)+\frac{1}{2}\left(\left[\begin{array}{l} x \\ y \\ \sigma \end{array}\right]-\left[\begin{array}{l} x_{0} \\ y_{0} \\ \sigma_{0} \end{array}\right]\right)^{T}\left[\begin{array}{l} \frac{\partial^{2} f}{\partial x \partial x}, \frac{\partial^{2} f}{\partial x \partial y}, \frac{\partial^{2} f}{\partial x \partial \sigma} \\ \frac{\partial^{2} f}{\partial x \partial y}, \frac{\partial^{2} f}{\partial y \partial y}, \frac{\partial^{2} f}{\partial y \partial \sigma} \\ \frac{\partial^{2} f}{\partial x \partial \sigma}, \frac{\partial^{2} f}{\partial y \partial \sigma}, \frac{\partial^{2} f}{\partial \sigma \partial \sigma} \end{array}\right]\left(\left[\begin{array}{l} x \\y \\\sigma\end{array}\right]-\left[\begin{array}{l}x_{0} \\y_{0} \\\sigma_{0}\end{array}\right]\right)

    矢量形式:f(X)=f(X0)+fTXX^+12X^τ2fX2X^ f(X)=f\left(\boldsymbol{X}_{0}\right)+\frac{\partial f^{T}}{\partial \boldsymbol{X}} \widehat{X}+\frac{1}{2} \widehat{X}^{\tau} \frac{\partial^{2} f}{\partial X^{2}} \widehat{X}

  2. 具体过程:

    1. f(x)f(x)求导:f(X)X=fTX+12(2fX2+2fTX2)=fTX+2fX2X^\frac{\partial f(X)}{\partial \boldsymbol{X}}=\frac{\partial f^{T}}{\partial \boldsymbol{X}}+\frac{1}{2}\left(\frac{\partial^{2} f}{\partial \boldsymbol{X}^{2}}+\frac{\partial^{2} f^{T}}{\partial \boldsymbol{X}^{2}}\right) \ell=\frac{\partial f^{T}}{\partial \boldsymbol{X}}+\frac{\partial^{2} f}{\partial \boldsymbol{X}^{2}} \hat{X} ,其中:X^=xX0\hat{X} = x - X_0
    2. 令导数为0解得:X^=2f1X2fX\hat{X}=-\frac{\partial^{2} f^{-1}}{\partial X^{2}} \frac{\partial f}{\partial X}
    3. 代入f(x)f(x):f(X):f(X)=f(X0)+fTXX^+12(2f1X2fX)T2fX2(2f1X2fX)=f(X0)+fTXX^+12fTX2fTX22fX22f1X2fX=f(X0)+fTXX^+12fTX2f1X2fX=f(X0)+fTXX^+12fTX(X^)=f(X0)+12fTXX^\begin{array}{l} \boldsymbol{f}(\mathrm{X}): f(X)=f\left(X_{0}\right)+\frac{\partial f^{T}}{\partial X} \widehat{X}+\frac{1}{2}\left(-\frac{\partial^{2} f^{-1}}{\partial X^{2}} \frac{\partial f}{\partial X}\right)^{T} \frac{\partial^{2} f}{\partial X^{2}}\left(-\frac{\partial^{2} f^{-1}}{\partial X^{2}} \frac{\partial f}{\partial X}\right) \\=f\left(X_{0}\right)+\frac{\partial f^{T}}{\partial X} \widehat{X}+\frac{1}{2} \frac{\partial f^{T}}{\partial X} \frac{\partial^{2} f^{-T}}{\partial X^{2}} \frac{\partial^{2} f}{\partial X^{2}} \frac{\partial^{2} f^{-1}}{\partial X^{2}} \frac{\partial f}{\partial X} \\ =f\left(X_{0}\right)+\frac{\partial f^{T}}{\partial X} \hat{X}+\frac{1}{2} \frac{\partial f^{T}}{\partial X} \frac{\partial^{2} f^{-1}}{\partial X^{2}} \frac{\partial f}{\partial X} \\ =f\left(X_{0}\right)+\frac{\partial f^{T}}{\partial X} \hat{X}+\frac{1}{2} \frac{\partial f^{T}}{\partial X}(-\widehat{X}) \\ =f\left(X_{0}\right)+\frac{1}{2} \frac{\partial f^{T}}{\partial X} \hat{X} \end{array}

    当然,这也仅仅只是粗略计算,还存在一些细节问题:迭代次数限制、解超出一定范围舍去。

  3. 舍去低对比度的点

    f(X)<Tn|f(X)|<\frac{T}{n},则舍去点X

  4. 边缘效应的去除

    1. 海森矩阵:H(x,y)=[Dxx(x,y)Dxy(x,y)Dxy(x,y)Dyy(x,y)] \boldsymbol{H}(x, y)=\left[\begin{array}{ll} D_{x x}(x, y) & D_{x y}(x, y) \\ D_{x y}(x, y) & D_{y y}(x, y) \end{array}\right]

    2. Tr(H)=Dxx+Dyy=α+βDet(H)=DxxDyy(Dxy)2=αβ\operatorname{Tr}(\boldsymbol{H})=D_{x x}+D_{y y}=\alpha+\beta\\\operatorname{Det}(\boldsymbol{H})=D_{x x} D_{y y}-\left(D_{x y}\right)^{2}=\alpha \beta,其中:α>β并且α=γβ \alpha>\beta 并且 \alpha=\gamma \beta,γ\gamma的建议值为10.0

    3. Det(H)<0Det(H)<0,则舍去点X,否则计算:Tr(H)2Det(H)=(α+β)2αβ=(γβ+β)2γβ2=(γ+1)2γ\frac{\operatorname{Tr}(\boldsymbol{H})^{2}}{\operatorname{Det}(\boldsymbol{H})}=\frac{(\alpha+\beta)^{2}}{\alpha \beta}=\frac{(\gamma \beta+\beta)^{2}}{\gamma \beta^{2}}=\frac{(\gamma+1)^{2}}{\gamma},若不满足Tr(H)2Det(H)<(γ+1)2γ\frac{\operatorname{Tr}(\boldsymbol{H})^{2}}{\operatorname{Det}(\boldsymbol{H})}<\frac{(\gamma+1)^{2}}{\gamma}

4. 为关键点赋予方向

  1. 思想:统计以特征点为圆心,以该特征点所在的高斯图像的尺度为1.5倍为半径的圆内的所有的像素的梯度方向及其梯度幅值,并作1.5σ1.5\sigma的高斯滤波。

  2. 示意图(在最接近关键点尺度值σ\sigma的高斯图像上进行统计)

image-20220601175532398.png

5. 构建关键点的描述符

关键点的匹配需要用到描述符(KNN)。

  1. 旋转不变性

    1. 在SIFT中,我们想要让图像在旋转一定角度后仍保持原来特征,所以我们需要将整个特征点描述符的区域正向改为梯度幅度最大方向。
    2. 图示:image-20220601172130827.png
  2. 区域大小

    1. image-20220601172358745.png
    2. 其中,m是3,d是每个小区域的边长是多少(像素单位)
  3. 具体过程:

    1. 构建一个128维的特征向量

    2. 把关键点周围的邻域分为16个子区域(长宽都为4)

image-20220601173153724.png

  1. 在每个子区域内统计8个方向的梯度值

image-20220601173209296.png

补充:有限差分求导法(利用差值求出导数)

  1. 单层差分求导:

    1. 图示:image-20220601175050097.png
    2. (fx)=f1f32h(fy)=f2f42h(2fx2)=f1+f32f0h2(2fy2)=f2+f42f0h2(2fxy)=(f8+f6)(f5+f7)4h2\left(\frac{\partial f}{\partial x}\right)=\frac{f_{1}-f_{3}}{2 h} \\ \left(\frac{\partial f}{\partial y}\right)=\frac{f_{2}-f_{4}}{2 h} \\ \left(\frac{\partial^{2} f}{\partial x^{2}}\right)=\frac{f_{1}+f_{3}-2 f_{0}}{h^{2}} \\ \left(\frac{\partial^{2} f}{\partial y^{2}}\right)=\frac{f_{2}+f_{4}-2 f_{0}}{h^{2}} \\ \left(\frac{\partial^{2} f}{\partial x \partial y}\right)=\frac{\left(f_{8}+f_{6}\right)-\left(f_{5}+f_{7}\right)}{4 h^{2}} \\
  2. 中间层差分求导(x方向):

    1. 图示:image-20220601175255779.png
    2. (fσ)=f2f42h(2fσ2)=f2+f42f0h2(2fxσ)=(f8+f6)(f5+f7)4h2\begin{array}{l} \left(\frac{\partial f}{\partial \sigma}\right)=\frac{f_{2}-f_{4}}{2 h} \\ \left(\frac{\partial^{2} f}{\partial \sigma^{2}}\right)=\frac{f_{2}+f_{4}-2 f_{0}}{h^{2}} \\ \left(\frac{\partial^{2} f}{\partial x \partial \sigma}\right)=\frac{\left(f_{8}+f_{6}\right)-\left(f_{5}+f_{7}\right)}{4 h^{2}} \end{array}
  3. 中间层差分求导(y方向):

    1. 图示:image-20220601175442228.png
    2. (2fyσ)=(f3+f6)(f3+f7)4h2\left(\frac{\partial^{2} f}{\partial y \partial \sigma}\right)=\frac{\left(f_{3}+f_{6}\right)-\left(f_{3}+f_{7}\right)}{4 h^{2}}