角点指的是角的顶点,如桌角椅角墙角的顶点。数学描述上,如果一个点在两个正交的方向上都有明显导数,那么这个点是角点。直观看来,角点就是在一张图上能找到,换个角度再拍一张图,还能找到的点。
最普遍使用的角点定义是Harris提出的,指的是至少在两个不同方向上有明显灰度变化的点。对于一幅灰度图片中的点
(
x
,
y
)
(x,y)
(x,y),灰度值为
I
(
x
,
y
)
I(x,y)
I(x,y),采用一阶近似
I
(
x
+
u
,
y
+
v
)
=
I
(
x
,
y
)
+
u
I
x
(
x
,
y
)
+
v
I
y
(
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 ] [ I x 2 I x I y I x I y I y 2 ] [ u v ] (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
′
]
[
λ
1
0
0
λ
2
]
[
u
′
v
′
]
=
λ
1
u
′
2
+
λ
2
v
′
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
=
d
e
t
(
M
)
−
k
∗
t
r
a
c
e
(
M
)
R=det(M)-k*trace(M)
R=det(M)−k∗trace(M)
其中
d
e
t
(
M
)
=
λ
1
λ
2
det(M)=\lambda_1 \lambda_2
det(M)=λ1λ2,
t
r
a
c
e
(
M
)
=
λ
1
+
λ
2
trace(M)=\lambda_1+\lambda_2
trace(M)=λ1+λ2。
k
k
k一般选择0.04~0.06。如果
R
>
T
R>T
R>T,则判定该点是角点。
实际计算中,为了去除噪声影响,在计算得到水平边缘图
I
x
I_x
Ix和垂直边缘图
I
y
I_y
Iy,进而得到
I
x
2
I_x^2
Ix2,
I
y
2
I_y^2
Iy2及
I
x
I
y
I_xI_y
IxIy后,会对这三张导数图进行滤波,通常使用高斯滤波器,因此
M
=
[
G
(
I
x
2
)
G
(
I
x
I
y
)
G
(
I
x
I
y
)
G
(
I
y
2
)
]
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
(
I
x
2
)
=
∑
−
K
≤
i
,
j
≤
K
w
i
,
j
I
x
2
(
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),
w
i
j
w_{ij}
wij是高斯权重。
OpenCV中的实现会直接计算 M M M的两个特征值,如果特征值较小的一个大于最小阈值,则会得到强角点,在很多情况下可以得到比原始算法更好的结果。