角点指的是角的顶点,如桌角椅角墙角的顶点。数学描述上,如果一个点在两个正交的方向上都有明显导数,那么这个点是角点。直观看来,角点就是在一张图上能找到,换个角度再拍一张图,还能找到的点。
最普遍使用的角点定义是Harris提出的,指的是至少在两个不同方向上有明显灰度变化的点。对于一幅灰度图片中的点(x,y)(x,y)(x,y),灰度值为I(x,y)I(x,y)I(x,y),采用一阶近似
I(x+u,y+v)=I(x,y)+uIx(x,y)+vIy(x,y)
I(x+u,y+v)=I(x,y)+uI_x(x,y)+vI_y(x,y)
I(x+u,y+v)=I(x,y)+uIx(x,y)+vIy(x,y)
(I(x+u,y+v)−I(x,y))2=[u,v][Ix2IxIyIxIyIy2][uv] (I(x+u,y+v)-I(x,y))^2=[u,v] \left[ \begin{matrix} I_x^2 & I_xI_y \\ I_xI_y & I_y^2 \end{matrix} \right] \left[ \begin{matrix} u \\ v \end{matrix} \right] (I(x+u,y+v)−I(x,y))2=[u,v][Ix2IxIyIxIyIy2][uv]
使用SVD分解
(I(x+u,y+v)−I(x,y))2=[u′,v′][λ100λ2][u′v′]=λ1u′2+λ2v′2
(I(x+u,y+v)-I(x,y))^2=[u',v']
\left[
\begin{matrix}
\lambda_1 & 0 \\
0 & \lambda_2
\end{matrix}
\right]
\left[
\begin{matrix}
u' \\
v'
\end{matrix}
\right]
=\lambda_1 u'^2+\lambda_2v'^2
(I(x+u,y+v)−I(x,y))2=[u′,v′][λ100λ2][u′v′]=λ1u′2+λ2v′2
λ1\lambda_1λ1和λ2\lambda_2λ2代表了两个不同方向上的灰度变化剧烈程度,因此希望两个特征值越大越好。通过计算角点的响应,公式如下
R=det(M)−k∗trace(M)
R=det(M)-k*trace(M)
R=det(M)−k∗trace(M)
其中det(M)=λ1λ2det(M)=\lambda_1 \lambda_2det(M)=λ1λ2,trace(M)=λ1+λ2trace(M)=\lambda_1+\lambda_2trace(M)=λ1+λ2。kkk一般选择0.04~0.06。如果R>TR>TR>T,则判定该点是角点。
实际计算中,为了去除噪声影响,在计算得到水平边缘图IxI_xIx和垂直边缘图IyI_yIy,进而得到Ix2I_x^2Ix2,Iy2I_y^2Iy2及IxIyI_xI_yIxIy后,会对这三张导数图进行滤波,通常使用高斯滤波器,因此
M=[G(Ix2)G(IxIy)G(IxIy)G(Iy2)]
M=\left[
\begin{matrix}
G(I_x^2) & G(I_xI_y) \\
G(I_xI_y) & G(I_y^2)
\end{matrix}
\right]
M=[G(Ix2)G(IxIy)G(IxIy)G(Iy2)]
其中G(Ix2)=∑−K≤i,j≤Kwi,jIx2(x+i,y+j)G(I_x^2)=\sum_{-K\leq i,j \leq K} w_{i,j}I_x^2(x+i,y+j)G(Ix2)=∑−K≤i,j≤Kwi,jIx2(x+i,y+j),wijw_{ij}wij是高斯权重。
OpenCV中的实现会直接计算MMM的两个特征值,如果特征值较小的一个大于最小阈值,则会得到强角点,在很多情况下可以得到比原始算法更好的结果。