Harris角点检测器
定义
角点:
像素点周围显示存在多余一个方向的边,也称为兴趣点
数学解释
把图像域中点 x x x 上的对称半定矩阵 M I = M I ( x ) M_I = M_I(x) MI=MI(x) 定义为
M I = ▽ I ▽ I T = [ I x I y ] [ I x I y ] = [ I x 2 I x I y I x I y I y 2 ] M_I=▽I▽I^T= \begin{bmatrix}I_x\\I_y\end{bmatrix} \begin{bmatrix}I_x&I_y\end{bmatrix} = \begin{bmatrix}I_x^2&I_xI_y\\I_xI_y&I_y^2\end{bmatrix} MI=▽I▽IT=[IxIy][IxIy]=[Ix2IxIyIxIyIy2]
▽
I
▽I
▽I 为包含导数
I
x
I
y
I_xI_y
IxIy 的图像梯度,即图像变化的强弱
根据该定义
M
I
M_I
MI 的秩为
1
1
1,特征值为
λ
1
=
∣
▽
I
∣
2
λ_1=|▽I|^2
λ1=∣▽I∣2 和
λ
2
=
0
λ_2=0
λ2=0
通过选择权重矩阵
W
W
W (gaussian_filter) 得到卷积 (
M
I
M_I
MI 在周围像素上的局部平均)
M
I
‾
=
W
∗
M
I
\overline{M_I} = W * M_I
MI=W∗MI
矩阵
M
I
‾
\overline{M_I}
MI就是 Harris矩阵
W
W
W 的宽度决定了像素
x
x
x 周围的兴趣区域
M
I
M_I
MI 在周围像素上的局部平均,其特征值会依赖局部图像特性而变化,即梯度改变。
取决于该区域 ▽ I ▽I ▽I的值,Harris矩阵 M I ‾ \overline{M_I} MI 的特征值有三种情况
- 如果 λ 1 λ 2 λ_1 λ_2 λ1λ2 是很大的正数,则该 x x x 为角点;
- 如果 λ 1 λ_1 λ1 很大, λ 2 ≈ 0 λ_2≈0 λ2≈0,则该区域内存在一个边,该区域内的平均 M I ‾ \overline{M_I} MI 的特征值不会变化太大;
- 如果 λ 1 ≈ λ 2 ≈ 0 λ_1≈λ_2≈0 λ1≈λ2≈0,该区域为空。
代码
def compute_harris_response(im,sigma=3):
"""在一副灰度图像中,对每个像素计算Harris角点检测器响应函数"""
#计算导数
imx = zeros(im.shape)
filters.gaussian_filter(im,(sigma,sigma),(0,1),imx)
imy = zeros(im.shape)
filters.gaussian_filter(im,(sigma,sigma),(1,0),imy)
#计算Harris矩阵的分量
Wxx = filters.gaussian_filter(imx * imx,sigma)
Wxy = filters.gaussian_filter(imx * imy,sigma)
Wyy = filters.gaussian_filter(imy * imy,sigma)
#计算特征值和迹
Wdet = Wxx * Wyy - Wxy ** 2
Wtr = Wxx + Wyy
return Wdet / Wtr
def get_harris_points(harrisim,min_dist=10,threshold=0.05):
""" 从一副Haris响应图像中返回角点。 min_dist为分割角点和图像边界的最少像素数目"""
#寻找高于阈值的候角点
corner_threshold = harrisim.max() * threshold
harrisim_t = (harrisim > corner_threshold) * 1
#得到候选点的坐标
coords = array(harrisim_t.nonzero()).T
#以及它们的Harris响应值
candidate_values = [harrisim[c[0],c[1]]for c in coords]
#对候选点按照Harris响应值进行排序
index = argsort(candidate_values)
#将可行点的位置保存到数组中
allowed_locations = zeros(harrisim.shape)
allowed_locations[min_dist:-min_dist,min_dist:-min_dist] = 1
#按照min_distance 原则 ,选择最佳Harris点
filtered_coords = []
for i in index:
if allowed_locations[coords[i,0],coords[i,0]] == 1:
filtered_coords.append(coords[i])
allowed_locations[(coords[i,0] - min_dist):(coords[i,0] + min_dist),
(coords[i,1] - min_dist):(coords[i,1] + min_dist)] = 0
return filtered_coords
def plot_harris_points(image,filtered_coords):
"""绘制图像中检测到的角点"""
figure()
gray()
imshow(image)
plot([p[1] for p in filtered_coords],[p[0] for p in filtered_coords],'.')
axis('off')
show()
运行效果
原图
序列化
灰度图
阈值为0.1
阈值为0.05
阈值为0.01
总结
该方法为一种局部图像描述子算法,用于创建全景图、增强现实技术以及计算图像的三维重建。
这种算法是一种极为简单的角点检测算法,效果受限于图片,对一些图片可能存在无效等问题。