Harris角点检测算法

  • 基础知识
  • 角点
  • 图像梯度
  • Harris角点检测算法原理
  • 算法思想
  • 建立数学模型
  • 角点响应函数R
  • 角点判定
  • 基于opencv实现


基础知识

在图像处理领域中,特征点又被称为兴趣点或者角点,它通常具有旋转不变性和光照不变性和视角不变性等优点,是图像的重要特征之一,常被应用到目标匹配、目标跟踪、三维重建等应用中。点特征主要指图像中的明显点,如突出的角点、边缘端点、极值点等等,用于点特征提取的算子称为兴趣点提取(检测)算子,常用的有Harris角点检测、FAST特征检测、SIFT特征检测及SURF特征检测。
本次介绍较为常用而且较为基础的Harris角点检测算法。

角点

使用一个滑动窗口在下面三幅图中滑动,可以得出以下结论:

  • 左图表示一个平坦区域,在各方向移动,窗口内像素值均没有太大变化;
  • 中图表示一个边缘特征(Edges),如果沿着水平方向移动(梯度方向),像素值会发生跳变;如果沿着边缘移动(平行于边缘) ,像素值不会发生变化;
  • 右图表示一个角(Corners),不管你把它朝哪个方向移动,像素值都会发生很大变化。

图像梯度

“像素值发生很大变化”这一现象可以用图像梯度进行描述。在图像局部内,图像梯度越大表示该局部内像素值变化越大(灰度的变化率越大)。 而图像的梯度在数学上可用微分或者导数来表示。对于数字图像来说,相当于是二维离散函数求梯度,并使用差分来近似导数: 特征点查找 GPU_opencv特征点查找 GPU_算法_02

Harris角点检测算法原理

算法思想

算法的核心是利用局部窗口在图像上进行移动,判断灰度是否发生较大的变化。如果窗口内的灰度值(在梯度图上)都有较大的变化,那么这个窗口所在区域就存在角点。
这样就可以将 Harris 角点检测算法分为以下三步:

  • 当窗口(局部区域)同时向 x (水平)和 y(垂直) 两个方向移动时,计算窗口内部的像素值变化量 特征点查找 GPU_灰度值_03
  • 对于每个窗口,都计算其对应的一个角点响应函数 特征点查找 GPU_特征点查找 GPU_04
  • 然后对该函数进行阈值处理,如果 特征点查找 GPU_算法_05,表示该窗口对应一个角点特征。

建立数学模型

第一步是通过建立数学模型,确定哪些窗口会引起较大的灰度值变化。 让一个窗口的中心位于灰度图像的一个位置特征点查找 GPU_灰度值_06,这个位置的像素灰度值为特征点查找 GPU_opencv_07 ,如果这个窗口分别向 特征点查找 GPU_特征点查找 GPU_08特征点查找 GPU_角点_09 方向移动一个小的位移特征点查找 GPU_opencv_10特征点查找 GPU_角点_11,到一个新的位置 特征点查找 GPU_灰度值_12 ,这个位置的像素灰度值就是特征点查找 GPU_opencv_13
特征点查找 GPU_特征点查找 GPU_14就是窗口移动引起的灰度值的变化值。

特征点查找 GPU_特征点查找 GPU_15为位置特征点查找 GPU_灰度值_06处的窗口函数,表示窗口内各像素的权重,最简单的就是把窗口内所有像素的权重都设为1,即一个均值滤波核。

当然,也可以把 特征点查找 GPU_特征点查找 GPU_15设定为以窗口中心为原点的高斯分布,即一个高斯核。如果窗口中心点像素是角点,那么窗口移动前后,中心点的灰度值变化非常强烈,所以该点权重系数应该设大一点,表示该点对灰度变化的贡献较大;而离窗口中心(角点)较远的点,这些点的灰度变化比较小,于是将权重系数设小一点,表示该点对灰度变化的贡献较小。

则窗口在各个方向上移动 特征点查找 GPU_灰度值_18所造成的像素灰度值的变化量公式:

特征点查找 GPU_灰度值_19


若窗口内是一个角点,则特征点查找 GPU_算法_20的计算结果将会很大。因此为了简化公式,进行泰勒级数展开,可得最终公式:

特征点查找 GPU_特征点查找 GPU_21


其中

特征点查找 GPU_opencv_22


其中

特征点查找 GPU_opencv_23


特征点查找 GPU_角点_24


把R看成旋转因子,其不影响两个正交方向的变化分量。经对角化处理后,将两个正交方向的变化分量提取出来,就是 λ1 和 λ2(特征值)。

角点响应函数R

定义了角点响应函数R,通过判定R大小来判断像素是否为角点。

特征点查找 GPU_角点_25


其中,特征点查找 GPU_灰度值_26,特征点查找 GPU_opencv_27,k为经验值,一般取0.04~0.06.

特征点查找 GPU_特征点查找 GPU_04的值取决于特征点查找 GPU_算法_29的特征值,对于角点特征点查找 GPU_算法_30很大,平坦的区域特征点查找 GPU_算法_30很小,边缘的特征点查找 GPU_特征点查找 GPU_04为负值。

角点判定

因为特征值 λ1 和 λ2 决定了 R 的值,所以我们可以用特征值来决定一个窗口是平面、边缘还是角点:

平面:该窗口在平坦区域上滑动,窗口内的灰度值基本不会发生变化,所以 特征点查找 GPU_灰度值_33 值非常小,在水平和竖直方向的变化量均较小,即 特征点查找 GPU_角点_34特征点查找 GPU_算法_35都较小,那么 λ1 和 λ2 都较小;

边缘:特征点查找 GPU_灰度值_33值为负数,仅在水平或竖直方向有较大的变化量,即 特征点查找 GPU_角点_34特征点查找 GPU_算法_35只有一个较大,也就是 λ1>>λ2 或 λ2>>λ1;

角点:[公式] 值很大,在水平、竖直两个方向上变化均较大的点,即 特征点查找 GPU_角点_34特征点查找 GPU_算法_35

基于opencv实现

在opencv中有提供实现 Harris 角点检测的函数 cv2.cornerHarris,我们直接调用的就可以,非常方便。

函数原型:cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])

对于每一个像素 (x,y),在 (blockSize x blockSize) 邻域内,计算梯度图的协方差矩阵 特征点查找 GPU_算法_41,然后通过上面的角点响应函数得到结果图。图像中的角点可以为该结果图的局部最大值。

即可以得到输出图中的局部最大值,这些值就对应图像中的角点。

实现:

特征点查找 GPU_opencv_42


特征点查找 GPU_算法_43


计算机视觉基础-图像处理(下)- Task01 Harris特征点检测器-兴趣点检测