在获得高斯差分金字塔之后,我们可以根据邻近尺度和邻近像素一共 26 个像素点的灰度值和中心像素点的灰度值比较,如果中心像素点的值是最大或者最小的,则作为极值点保留下来。
我在这称之为第一次极值点的筛选。
但是我们知道像素是网格排布的,也就是说是离散的,如果我们想要获得更精确的极值点,就需要根据目前离散的点进行插值拟合,让数据连续起来,然后得到一个比较精确的极值点。
给我的感觉就是 SIFT 算法经历了一个从连续到离散,然后再回归连续的过程,首先是通过离散的高斯差分来近似表示拉普拉斯梯度,减少计算量,然后又对离散的高斯差分进行子像元级别的插值,获得一个连续的曲面,求真正的极值点。
首先,我们的高斯差分函数是通过通过不同尺度的高斯滤波得到的: D ( x , y , σ ) = [ G ( x , y , σ 1 ) − G ( x , y , σ 2 ) ] ∗ I ( x , y ) D(x, y, \sigma) = [G(x, y, \sigma_1 ) – G(x, y, \sigma_2 )] * I(x,y) D(x,y,σ)=[G(x,y,σ1)−G(x,y,σ2)]∗I(x,y)其中, I ( x , y ) I(x, y) I(x,y) 是像素的灰度值。
我们要从离散的高斯差分插值到连续的曲面,需要用到泰勒展开,因为泰勒展开是一种将函数在某一点附近近似为多项式的方法,通过使用一阶和二阶导数来拟合函数。所以可以得到: D ( X ) ≈ D + ∂ D T ∂ X X + 1 2 X T ∂ 2 D ∂ X 2 X D(X) \approx D +\frac{ \partial D^T }{\partial X } X + \frac{1}{2}X^T\frac{\partial^2 D}{\partial X^2}X D(X)≈D+∂X∂DTX+21XT∂X2∂2DX这个公式在别的文章很常见,所以高斯差分函数目前是关于位置 x , y x, y x,y 和尺度 σ \sigma σ 的函数,上面的式子是一个矩阵的形式,因为要求极值,所以要对 D ( X ) D(X) D(X) 求导,并让其导数 ∂ D ∂ X = 0 \frac{\partial D}{\partial X} = 0 ∂X∂D=0 ,对于 1 2 X T ∂ 2 D ∂ X 2 X \frac{1}{2}X^T\frac{\partial^2 D}{\partial X^2}X 21XT∂X2∂2DX 求导数,我们有下面公式: ∂ ∂ X ( X T A X ) = ( A + A T ) X \frac{\partial}{\partial X}(X^TAX) = (A+A^T)X ∂X∂(XTAX)=(A+AT)X所以可以得到: ∂ D ∂ X = 0 + ∂ D T ∂ X + 1 2 ( ∂ 2 D ∂ X 2 + ( ∂ 2 D ∂ X 2 ) T ) X \frac{\partial D}{\partial X} = 0 + \frac{\partial D^T}{\partial X}+ \frac{1}{2}\left(\frac{\partial^2 D}{\partial X^2}+\left(\frac{\partial^2 D}{\partial X^2}\right)^T \right)X ∂X∂D=0+∂X∂DT+21(∂X2∂2D+(∂X2∂2D)T)X考虑到 ∂ 2 D ∂ X 2 \frac{\partial^2 D}{\partial X^2} ∂X2∂2D 是 Hessian 矩阵,展开表达式如下: ∂ 2 D ∂ X 2 = ( D x x D x y D x z D x y D y y D y z D x z D y z D z z ) \frac{\partial^2 D}{\partial X^2} =\begin{pmatrix} D_{xx} & D_{xy} & D_{xz}\\ D_{xy} & D_{yy} & D_{yz} \\ D_{xz} & D_{yz} & D_{zz} \end{pmatrix} ∂X2∂2D=
DxxDxyDxzDxyDyyDyzDxzDyzDzz
可以看出来是对称矩阵,所以 ∂ 2 D ∂ X 2 = ( ∂ 2 D ∂ X 2 ) T \frac{\partial^2 D}{\partial X^2} = (\frac{\partial^2 D}{\partial X^2})^T ∂X2∂2D=(∂X2∂2D)T,我们就可以得到求导之后的式子为: ∂ D ∂ X = ∂ D T ∂ X + ∂ 2 D ∂ X 2 X \frac{\partial D}{\partial X} = \frac{\partial D^T}{\partial X}+ \frac{\partial^2 D}{\partial X^2}X ∂X∂D=∂X∂DT+∂X2∂2DX让导数 ∂ D ∂ X \frac{\partial D}{\partial X} ∂X∂D 为零可以得到: X ^ = ∂ D T ∂ X ( − ∂ 2 D ∂ X 2 ) − 1 \hat{X} = \frac{\partial D^T}{\partial X} \left (- \frac{\partial^2 D}{\partial X^2} \right )^{-1} X^=∂X∂DT(−∂X2∂2D)−1这里的 X ^ \hat{X} X^ 就是我们要求的极值点偏移值。
但是这是否就意味着我们可以直接根据这个极值的偏移量去求极值点了呢?
答案是否定。
我们需要根据这个偏移量的值来对极值点进行筛选,也就是第二次筛选:
- 偏移量过大了,说明偏移太多了,这个第一次筛选被保留的极值点要过滤掉。
- 偏移量的 x , y , σ x, y, \sigma x,y,σ 任意一个方向大于 0.5,则需要不断迭代拟合
- 这说明拟合的极值点偏移了初筛的离散极值点,需要重新拟合,将 D ( X 0 + X ^ ) D(X_0+\hat{X}) D(X0+X^) 作为新的 D D D(原来的 D D D 其实就是 D ( X 0 ) D(X_0) D(X0))带入上面的高斯差分泰勒展开中进行重新迭代拟合,直到偏移量小于 0.5 。
- 当然这个迭代次数也是有限制的,超过迭代次数偏移量还是大于 0.5,这个极值点也会被过滤掉。
- 偏移量各参数都小于 0.5 的,我们就可以计算出拟合的极值高斯差分响应:
- 然后将 X ^ \hat{X} X^ 代入原式,就可以求得: D ( X ) = D + 1 2 ∂ D T ∂ X X ^ D(X) = D + \frac{1}{2} \frac{\partial D^T}{\partial X} \hat{X} D(X)=D+21∂X∂DTX^
但是在 SIFT 中我们并不关注极值点的高斯差分响应值,我们只关注这个极值点在哪,是否有效。所以一般是不需要对上式进行求解的,仅仅是在此列出。但是,在第二次的极值点筛选中,偏移量的值是实实在在需要求解的,下面我们将来具体求解一下偏移量。
我们将偏移量的公式按照矩阵展开,可以得到: X ^ = − ( D x , D y , D z ) ( D x x D x y D x z D x y D y y D y z D x z D y z D z z ) − 1 \hat{X}= -\left (D_x, D_y, D_z \right ) \begin{pmatrix} D_{xx} & D_{xy} & D_{xz}\\ D_{xy} & D_{yy} & D_{yz} \\ D_{xz} & D_{yz} & D_{zz} \end{pmatrix}^{-1} X^=−(Dx,Dy,Dz)
DxxDxyDxzDxyDyyDyzDxzDyzDzz
−1其中 D x y D_{xy} Dxy, D x x D_{xx} Dxx 和 D y y D_{yy} Dyy 都是二阶偏导, D x D_x Dx 与 D y D_y Dy 都是一阶导,然后依旧,我们使用有限差分来进行近似,可以得到: D x = 1 2 [ D ( x + 1 , y ) − D ( x − 1 , y ) ] D_x =\frac{1}{2}\left[ D(x+1, y) – D(x-1, y)\right] Dx=21[D(x+1,y)−D(x−1,y)] D y = 1 2 [ D ( x , y + 1 ) − D ( x , y − 1 ) ] D_y =\frac{1}{2}\left[ D(x, y+1) – D(x, y-1)\right] Dy=21[D(x,y+1)−D(x,y−1)] D z = 1 2 [ D n e x t ( x , y ) − D p r e v ( x , y ) ] D_{z} =\frac{1}{2}\left[ D_{next}(x, y) – D_{prev}(x, y)\right] Dz=21[Dnext(x,y)−Dprev(x,y)]然后就是 6 个二阶偏导数:
D x x = D ( x + 1 , y ) − 2 D ( x , y ) + D ( x − 1 , y ) D_{xx}= D(x+1, y) – 2D(x,y) + D(x-1, y) Dxx=D(x+1,y)−2D(x,y)+D(x−1,y) D y y = D ( x , y + 1 ) − 2 D ( x , y ) + D ( x , y − 1 ) D_{yy}= D(x, y+1) – 2D(x,y) + D(x, y-1) Dyy=D(x,y+1)−2D(x,y)+D(x,y−1) D z z = D n e x t ( x , y ) − 2 D ( x , y ) + D p r e v ( x , y ) D_{zz}= D_{next}(x, y) – 2D(x,y) + D_{prev}(x, y) Dzz=Dnext(x,y)−2D(x,y)+Dprev(x,y) D x y = 1 4 [ D ( x + 1 , y + 1 ) − D ( x + 1 , y − 1 ) − D ( x − 1 , y + 1 ) + D ( x − 1 , y − 1 ) ] D_{xy} = \frac{1}{4}\left[ D(x+1, y+1) – D(x+1, y-1) – D(x-1, y+1)+ D(x-1, y-1) \right] Dxy=41[D(x+1,y+1)−D(x+1,y−1)−D(x−1,y+1)+D(x−1,y−1)] D y z = 1 4 [ D n e x t ( x , y + 1 ) − D n e x t ( x , y − 1 ) − D p r e v ( x , y + 1 ) + D p r e v ( x , y − 1 ) ] D_{yz} = \frac{1}{4}\left[ D_{next}(x, y+1) – D_{next}(x, y-1) – D_{prev}(x, y+1)+ D_{prev}(x, y-1) \right] Dyz=41[Dnext(x,y+1)−Dnext(x,y−1)−Dprev(x,y+1)+Dprev(x,y−1)] D x z = 1 4 [ D n e x t ( x + 1 , y ) − D n e x t ( x − 1 , y ) − D p r e v ( x + 1 , y ) + D p r e v ( x − 1 , y ) ] D_{xz} = \frac{1}{4}\left[ D_{next}(x+1, y) – D_{next}(x-1, y) – D_{prev}(x+1, y)+ D_{prev}(x-1, y) \right] Dxz=41[Dnext(x+1,y)−Dnext(x−1,y)−Dprev(x+1,y)+Dprev(x−1,y)]有了上面的 9 个公式,偏移量 X ^ \hat{X} X^ 基本上就求出来了。
计算部分的代码看一下网上的代码,大概这是这样的:
Matx33f H (dxx, dxy, dxz, dxy, dyy, dyz, dxz, dyz, dzz);
Vec3f dD(dx, dy, dz);
Vec3f X = H.solve(dD, DECOMP_SVD);
xc = -X[0];//x方向偏移量
xr = -X[1];//y方向偏移量
xi = -X[2];//尺度方向偏移量
问题解答
为什么在D对X求导的时候,一阶偏导与二阶偏导被直接默认为常数,没有参与进一步的微分?
泰勒公式(英语:Taylor’s Formula)是一个用函数在某点的信息描述其附近取值的公式。
这个点是确认的,在泰勒展开中求得的一阶偏导和二阶偏导,都是在这个特定的展开点处求值。一旦在这个特定点求得了这些偏导数的值,它们在构造该点的泰勒级数时就被视为固定的常数。
今天的文章gfi指标是什么拟合_三者容斥最小值[通俗易懂]分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/84686.html