Harris角点检测器

定义

角点:

像素点周围显示存在多余一个方向的边,也称为兴趣点

数学解释

把图像域中点 xx 上的对称半定矩阵 MI=MI(x)M_I = M_I(x) 定义为

MI=IIT=[IxIy][IxIy]=[Ix2IxIyIxIyIy2]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}

I▽I 为包含导数 IxIyI_xI_y 的图像梯度,即图像变化的强弱
根据该定义 MIM_I 的秩为 11,特征值为 λ1=I2λ_1=|▽I|^2λ2=0λ_2=0

通过选择权重矩阵 WW (gaussian_filter) 得到卷积 (MIM_I 在周围像素上的局部平均)
MI=WMI\overline{M_I} = W * M_I
矩阵MI\overline{M_I}就是 Harris矩阵

WW 的宽度决定了像素 xx 周围的兴趣区域
MIM_I 在周围像素上的局部平均,其特征值会依赖局部图像特性而变化,即梯度改变。

取决于该区域I▽I的值,Harris矩阵 MI\overline{M_I} 的特征值有三种情况

  • 如果 λ1λ2λ_1 λ_2 是很大的正数,则该 xx 为角点;
  • 如果 λ1λ_1 很大,λ20λ_2≈0,则该区域内存在一个边,该区域内的平均 MI\overline{M_I} 的特征值不会变化太大;
  • 如果 λ1λ20λ_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()

运行效果

Harris 角点检测器
原图

Harris 角点检测器
序列化

Harris 角点检测器
灰度图

Harris 角点检测器
阈值为0.1

Harris 角点检测器
阈值为0.05

Harris 角点检测器
阈值为0.01

总结

该方法为一种局部图像描述子算法,用于创建全景图、增强现实技术以及计算图像的三维重建。
这种算法是一种极为简单的角点检测算法,效果受限于图片,对一些图片可能存在无效等问题。

相关文章: