基本思想#
想象一个小窗口在图像上滑动,可以分为三种情况:
- 窗口在大面积像素值相近的平坦区域:无论怎么移动,窗口内的像素值变化都很小
- 窗口在平直边缘上:沿着边缘方向移动,像素值变化很小;垂直于边缘方向移动,像素值变化很大
- 窗口在角点上:无论怎么移动,窗口内的像素值变化都很大
所以我们只要找到无论怎么移动窗口,像素值变化都很大的点,也就是像素值变化量的最小值大于一个阈值的点,就可以认为它是一个角点
假设窗口每次移动(u,v),窗口内像素值的变化可以用平方差之和来表示为:
E(u,v)=x,y∑[I(x+u,y+v)−I(x,y)]2
- I(x,y):图像在点(x,y)的像素值,后续简写为Ix和Iy
因为u和v很小,所以可以使用泰勒展开来近似I(x+u,y+v):
I(x+u,y+v)≈I(x,y)+Ix⋅u+Iy⋅v=I(x,y)+[IxIy][uv]
- Ix和Iy:图像在点(x,y)的水平和垂直方向的梯度
所以:
E(u,v)≈x,y∑([IxIy][uv])2=x,y∑([IxIy][uv])T([IxIy][uv])=x,y∑[uv][Ix2IxIyIxIyIy2][uv] 给中间矩阵取个名字:
H=[Ix2IxIyIxIyIy2] 为了防止解出u=v=0的平凡解,所以设置约束∥d∥2=u2+v2=1,所以就转化为求解如下问题:
∥d∥2=1mindTHd 构造拉格朗日函数#
L(d,λ)=dTHd−λ(dTd−1)=u2H11+2uvH12+v2H22−λ(u2+v2−1) 对u求导并设置为零:
∂u∂L=2uH11+2vH12−2λuuH11+vH12=0=λu 对v求导并设置为零:
∂v∂L=2uH12+2vH22−2λvuH12+vH22=0=λv 得到方程组:
{uH11+vH12=λuuH12+vH22=λv 可以写成矩阵形式:
[H11H12H12H22][uv]Hd=λ[uv]=λd 后续步骤跟单应矩阵那块类似,先同左乘dT,得到:
dTHd=λdTd=λ(约束∥d∥2=1) 所以最小化dTHd等价于最小化λ,如果这个最小特征值大于一个阈值,就认为这个点是一个角点,但是这种方法需要计算特征值,比较麻烦,所以Harris提出了一个角点响应函数来避免计算特征值
角点响应函数#
R=det(H)−k⋅trace(H)2
- λ1,λ2:H的两个特征值
- det(H)=λ1λ2:特征值的乘积,表示窗口内像素值变化的程度
- trace(H)=λ1+λ2:特征值的和,表示窗口内像素值变化的总量
- k:经验参数,通常取0.04到0.06之间
当处于角点,λ1和λ2都较大且相当,此时乘积会远大于和的平方,所以R为很大的正值;当处于边缘,λ1和λ2其中一个较大的另一个较小,此时乘积会小于和的平方,所以R为很小的负值;当平坦区域,λ1和λ2其中一个较大另一个较小,此时乘积和和的平方相差不大,所以R会接近于零
⎩⎨⎧R≫0R≪0R≈0角点边缘平坦区域