图像特征之Harris角点检测
这里写自定义目录标题
-
- 1. 角点定义
- 2. 算法原理
- 3. 角点检测算法的分类
- 4. Harris角点检测
- 5. 算法实现
- 6. 代码
-
-
- 参数说明:
-
- 效果展示
1. 角点定义
角点检测又称为特征点检测,是图像处理和计算机视觉中用来获取局部特征点的一类方法,广泛应用于运动检测、图像匹配、视频跟踪等领域。角点可以简单地定义为轮廓之间的交点,严格地定义是在两个主方向上的特征点,即在两个方向上灰度变化剧烈。通常具有以下特征:
- 角点附近的像素点不论在梯度方向上还是梯度幅值上都存在着较大的变化
- 对于某一场景,当视角发生变化时,其任具备稳定性质的特征
2. 算法原理
角点检测的基本思想就是用固定窗口在图像上沿各个方向进行滑动,比较滑动前后窗口中像素点的灰度变化,如果在任意方向上滑动窗口内都存在较大的灰度变化,则认为该窗口中存在角点;如果任何方向上都不变化,则是均匀区域;如果灰度只在一个方向上变化,则可能是图像边缘。

3. 角点检测算法的分类
在当前的图像处理领域,角点检测算法可以归纳为三类:
1、基于灰度图像的角点检测
2、基于二值图像的角点检测
3、基于轮廓曲线的角点检测
基于灰度图像的角点检测又可分为基于梯度、基于模板、基于模板梯度组合三类方法,其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻近点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测算法,Harris角点检测算法,KLT角点检测算法以及SUSAN角点检测算法。
4. Harris角点检测
角点计算的数学求解过程在此略过(手动狗头),其中涉及到求解某个矩阵(假设为M矩阵)的特征值,根据矩阵M的特征值判断是否为角点,当两个特征值都较大时则认为是角点(corner),一个特征值较大一个较小时认为是图像边缘(edge),两个特征值都较小时认为是均匀区域(flat),如下图所示:

在具体判断角点时,无需求解矩阵M的特征值,而是通过下面的公式计算角点响应值:

式中, detM 是矩阵M 的行列式, traceM 是矩阵M 的迹, α 为一常数,通常取0.04~0.06。
5. 算法实现
Harris角点检测的算法步骤可归纳为:

6. 代码
通过OpenCV中的cv2.cornerHarris()可以较容易的实现角点检测,函数原型为:
def cornerHarris(src, blockSize, ksize, k, dst=None, borderType=None):
参数说明:
src : 输入图像,须为float型的单通道8位图像
blockSize : 邻域大小,即滑动窗口的尺寸
ksize : Sobel求导中使用的窗口大小,注意必须为奇数
k : Harris角点检测方程中的自由参数,也就是上述计算角点响应值R公式中的α值
效果展示
下面使用该函数实现一个简单的Harris角点检测效果:
import os
import numpy as np
src_dir = 'image'
for name in os.listdir(src_dir):
image_path = '{}/{}'.format(src_dir, name)
img = cv2.imread(image_path)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.float32)
img_harris = cv2.cornerHarris(img_gray, 2, 7, 0.04)
# cv2.imshow('Harris', img_harris)
threshold = np.max(img_harris) * 0.01
dilate = cv2.dilate(img_harris, None)
# cv2.imshow('Dilate', dilate)
img[dilate > threshold] = [0, 0, 255]
cv2.imshow('Result', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下


