【动手学计算机视觉】第六讲:传统目标检测之Harris角点检测

简介: 传统目标识别中,特征提取和机器学习两个最为重要的研究方向,有一些研究者把全部精力投入到机器学习的研究中,而有一批研究者把所有的心思放在了特征提取方面,因此,可见特征提取在传统目标识别中的重要地位。特征提取的好坏,会直接影响到最终检测效果,因此,需要针对不同类型的图像选取不同的特征,例如边缘特征、区域特征、角点特征、纹理特征、高低频特征等,本文要介绍的就是角点检测中的一种经典算法--Harris角点检测。

前言

在传统目标识别中,特征提取是最终目标识别效果好坏的一个重要决定因素,因此,在这项工作里,有很多研究者把主要精力都放在特征提取方向。在传统目标识别中,主要使用的特征主要有如下几类:

  • 边缘特征
  • 纹理特征
  • 区域特征
  • 角点特征

本文要讲述的Harris角点检测就是焦点特征的一种。

目前角点检测算法主要可归纳为3类:

  • 基于灰度图像的角点检测
  • 基于二值图像的角点检测
  • 基于轮廓的角点检测

因为角点在现实生活场景中非常常见,因此,角点检测算法也是一种非常受欢迎的检测算法,尤其本文要讲的Harris角点检测,可以说传统检测算法中的经典之作。

Harris角点检测

什么是角点?

要想弄明白角点检测,首先要明确一个问题,什么是角点?

0.jpg

这个在现实中非常常见,例如图中标记出的飞机的角点,除此之外例如桌角、房角等。这样很容易理解,但是该怎么用书面的语言阐述角点?

角点就是轮廓之间的交点。

如果从数字图像处理的角度来描述就是:像素点附近区域像素无论是在梯度方向、还是在梯度幅值上都发生较大的变化。

这句话是焦点检测的关键,也是精髓,角点检测算法的思想就是由此而延伸出来的。

角点检测的算法思想是:选取一个固定的窗口在图像上以任意方向的滑动,如果灰度都有较大的变化,那么久认为这个窗口内部存在角点。

要想实现角点检测,需要用数学语言对其进行描述,下面就着重用数学语言描述一下角点检测算法的流程和原理。

用w(x,y)表示窗口函数,[u,v]为窗口平移量,像素在窗口内的变化量为,

1.png

I(x,y)为平移前的像素灰度值,I(x+u,y+v)为平移后的像素灰度值,

通过对灰度变化部分进行泰勒展开得到

2.png

因此得到,


3.png

4.png

5.png

现在在回过头来看一下角点与其他类型区域的不同之处:

  • 平坦区域:梯度方向各异,但是梯度幅值变化不大
  • 线性边缘:梯度幅值改变较大,梯度方向改变不大
  • 角点:梯度方向和梯度幅值变化都较大

明白上述3点之后看一下怎么利用其矩M进行角点检测。

根据主成分分析(PCA)的原理可知,如果对矩M对角化,那么,特征值就是主分量上的方差,M是二维的方阵,有两个主分量,如果在窗口区域内是角点,那么梯度变化会较大,像素点的梯度分布比较离散,这体现在特征值上就是特征值比较大。

换句话说,

  • 如果矩阵对应的两个特征值都较大,那么窗口内含有角点
  • 如果特征值一个大一个小,那么窗口内含有线性边缘
  • 如果两个特征值都很小,那么窗口内为平坦区域

读到这里就应该明白了,角点的检测转化为数学模型,就是求解窗口内矩阵M的特征值并且判断特征值的大小。

如果要评价角点的强度,可以用下方公式,

6.png

其中,


7.png

编程实践

1requirement: OpenCV/scipy/matplotlib

因为Harris角点检测算法非常经典,因此,一些成熟的图像处理或视觉库都会直接提供Harris角点检测的算法,以OpenCV为例,

1import cv2
 2import numpy as np
 3
 4filename = '2007_000480.jpg'
 5
 6img = cv2.imread(filename)
 7gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 8gray = np.float32(gray)
 9dst = cv2.cornerHarris(gray,blockSize,ksize,k)
10
11"""
12其中,
13gray为灰度图像,
14blockSize为邻域窗口的大小,
15ksize是用于Soble算子的参数,
16k是一个常量,取值为0.04~0.06
17"""

因为本文要讲一步一步实现Harris角点检测算法,因此,对OpenCV提供的函数不多阐述,下面开始一步一步实现Harris角点检测算法。

检点检测算法的流程如下:

  1. 利用公式(1)求出输入图像每个位置的角点强度相应
  2. 给定阈值,当一个位置的强度大于阈值则认为是角点
  3. 画出角点

首先是第一步,根据上述提到的公式求矩阵的特征值和矩阵的迹,然后计算图像的角点强度,这里选取常数k=0.04,

1def calculate_corner_strength(img, scale=3, k=0.06):
 2    # 计算图像在x、y方向的梯度
 3    # 用滤波器采用差分求梯度的方式
 4    gradient_imx, gradient_imy = zeros(img.shape), zeros(img.shape)
 5    filters.gaussian_filter(img, (scale, scale), (0, 1), gradient_imx)
 6    filters.gaussian_filter(img, (scale, scale), (1, 0), gradient_imy)
 7
 8    # 计算矩阵M的每个分量
 9    I_xx = filters.gaussian_filter(gradient_imx*gradient_imx, scale)
10    I_xy = filters.gaussian_filter(gradient_imx*gradient_imy, scale)
11    I_yy = filters.gaussian_filter(gradient_imy*gradient_imy, scale)
12
13    # 计算矩阵的迹、特征值和响应强度
14    det_M = I_xx * I_yy - I_xy ** 2
15    trace_M = I_xx + I_yy
16    return det_M + k * trace_M ** 2

接下来完成第2步,根据给定阈值,获取角点,

1def corner_detect(img, min=15, threshold=0.04):
 2    # 首先对图像进行阈值处理
 3    _threshold = img.max() * threshold
 4    threshold_img = (img > _threshold) * 1
 5    corners = array(threshold_img.nonzero()).T
 6    candidate_values = [img[c[0], c[1]] for c in corners]
 7    index = argsort(candidate_values)
 8
 9    # 选取领域空间,如果邻域空间距离小于min的则只选取一个角点
10    # 防止角点过于密集
11    neighbor = zeros(img.shape)
12    neighbor[min:-min, min:-min] = 1
13    detect_corner= []
14    for i in index:
15        if neighbor[corners[i, 0], corners[i, 1]] == 1:
16            detect_corner.append(corners[i])
17            neighbor[(corners[i, 0] - min):(corners[i, 0] + min),
18            (corners[i, 1] - min):(corners[i, 1] + min)] = 0
19    return detect_corner

然后是画出角点,

1def corner_plot(image, corner_img):
2    figure()
3    gray()
4    imshow(image)
5    plot([p[1] for p in corner_img], [p[0] for p in corner_img], 'ro')
6    axis('off')
7    show()

检测结果,

8.jpg

完整代码如下,

1from scipy.ndimage import filters
 2import cv2
 3from matplotlib.pylab import *
 4
 5
 6class Harris(object):
 7    def __init__(self, img_path):
 8        self.img = cv2.imread(img_path, 0)
 9
10    def calculate_corner_strength(self):
11        # 计算图像在x、y方向的梯度
12        # 用滤波器采用差分求梯度的方式
13        scale = self.scale
14        k = self.k
15        img = self.img
16        gradient_imx, gradient_imy = zeros(img.shape), zeros(img.shape)
17        filters.gaussian_filter(img, (scale, scale), (0, 1), gradient_imx)
18        filters.gaussian_filter(img, (scale, scale), (1, 0), gradient_imy)
19
20        # 计算矩阵M的每个分量
21        I_xx = filters.gaussian_filter(gradient_imx*gradient_imx, scale)
22        I_xy = filters.gaussian_filter(gradient_imx*gradient_imy, scale)
23        I_yy = filters.gaussian_filter(gradient_imy*gradient_imy, scale)
24
25        # 计算矩阵的迹、特征值和响应强度
26        det_M = I_xx * I_yy - I_xy ** 2
27        trace_M = I_xx + I_yy
28        return det_M + k * trace_M ** 2
29
30    def corner_detect(self, img):
31        # 首先对图像进行阈值处理
32        _threshold = img.max() * self.threshold
33        threshold_img = (img > _threshold) * 1
34        corners= array(threshold_img.nonzero()).T
35        candidate_values = [img[c[0], c[1]] for c in corners]
36        index = argsort(candidate_values)
37
38        # 选取领域空间,如果邻域空间距离小于min的则只选取一个角点
39        # 防止角点过于密集
40        neighbor = zeros(img.shape)
41        neighbor[self.min:-self.min, self.min:-self.min] = 1
42        detect_corner= []
43        for i in index:
44            if neighbor[corners[i, 0], corners[i, 1]] == 1:
45                detect_corner.append(corners[i])
46                neighbor[(corners[i, 0] - self.min):(corners[i, 0] + self.min),
47                (corners[i, 1] - self.min):(corners[i, 1] + self.min)] = 0
48        return detect_corner
49
50    def corner_plot(self, img, corner_img):
51        figure()
52        gray()
53        imshow(img)
54        plot([p[1] for p in corner_img], [p[0] for p in corner_img], 'ro')
55        axis('off')
56        show()
57
58    def __call__(self, k=0.04, scale=3, min=15, threshold=0.03):
59        self.k = k
60        self.scale = scale
61        self.min = min
62        self.threshold = threshold
63        strength_img = self.calculate_corner_strength()
64        corner_img = self.corner_detect(strength_img)
65        self.corner_plot(self.img, corner_img)
66
67
68if __name__ == '__main__':
69    harris = Harris("2007_002619.jpg")
70    harris()


相关文章
|
6月前
|
机器学习/深度学习 算法 计算机视觉
计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A路径规划+单目测距与测速+行人车辆计数等)
计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A路径规划+单目测距与测速+行人车辆计数等)
117 2
|
2月前
|
JSON 人工智能 数据格式
AI计算机视觉笔记二十六:YOLOV8自训练关键点检测
本文档详细记录了使用YOLOv8训练关键点检测模型的过程。首先通过清华源安装YOLOv8,并验证安装。接着通过示例权重文件与测试图片`bus.jpg`演示预测流程。为准备训练数据,文档介绍了如何使用`labelme`标注工具进行关键点标注,并提供了一个Python脚本`labelme2yolo.py`将标注结果从JSON格式转换为YOLO所需的TXT格式。随后,通过Jupyter Notebook可视化标注结果确保准确性。最后,文档展示了如何组织数据集目录结构,并提供了训练与测试代码示例,包括配置文件`smoke.yaml`及训练脚本`train.py`,帮助读者完成自定义模型的训练与评估。
|
6月前
|
机器学习/深度学习 算法 计算机视觉
计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)
计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)
|
2月前
|
人工智能 并行计算 PyTorch
AI计算机视觉笔记十八:Swin Transformer目标检测环境搭建
本文详细记录了Swin Transformer在AutoDL平台上的环境搭建与训练过程。作者从租用GPU实例开始,逐步介绍了虚拟环境的创建、PyTorch安装、mmcv及mmdetection的配置,并解决了安装过程中遇到的各种问题,如cython版本冲突等。最后,通过修改代码实现目标检测结果的保存。如需了解更多细节或获取完整代码,请联系作者。原文链接:[原文链接](请在此处插入原文链接)。
|
2月前
|
人工智能 计算机视觉
AI计算机视觉笔记十五:编写检测的yolov5测试代码
该文为原创文章,如需转载,请注明出处。本文作者在成功运行 `detect.py` 后,因代码难以理解而编写了一个简易测试程序,用于加载YOLOv5模型并检测图像中的对象,特别是“人”类目标。代码实现了从摄像头或图片读取帧、进行颜色转换,并利用YOLOv5进行推理,最后将检测框和置信度绘制在输出图像上,并保存为 `result.jpg`。如果缺少某些模块,可使用 `pip install` 安装。如涉及版权问题或需获取完整代码,请联系作者。
|
2月前
|
机器学习/深度学习 人工智能 算法
AI计算机视觉笔记十一:yolo5+Deepsort实现目标检测与跟踪(CPU版)
DeepSORT是一种基于深度学习的计算机视觉跟踪算法,扩展了SORT算法,通过添加外观描述符减少身份切换,提高跟踪效率。本文档提供了DeepSORT环境搭建步骤,包括创建虚拟环境、安装依赖及解决常见错误等,最终实现人员和车辆的跟踪计数功能。适合无GPU设备的学习者参考。
|
3月前
|
机器学习/深度学习 算法 大数据
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析
本文提供了2023年MathorCup高校数学建模挑战赛大数据竞赛赛道A的解决方案,涉及基于计算机视觉的坑洼道路检测和识别任务,包括数据预处理、特征提取、模型建立、训练与评估等步骤的Python代码解析。
72 0
【2023年MathorCup高校数学建模挑战赛-大数据竞赛】赛道A:基于计算机视觉的坑洼道路检测和识别 python 代码解析
|
3月前
|
机器学习/深度学习 人工智能 数据处理
AI计算机视觉笔记一:YOLOV5疲劳驾驶行为检测
如何使用云服务器AutoDL进行深度学习模型的训练,特别是针对YOLOV5疲劳驾驶行为训练检测
|
4月前
|
机器学习/深度学习 人工智能 算法
计算机视觉:目标检测算法综述
【7月更文挑战第13天】目标检测作为计算机视觉领域的重要研究方向,近年来在深度学习技术的推动下取得了显著进展。然而,面对复杂多变的实际应用场景,仍需不断研究和探索更加高效、鲁棒的目标检测算法。随着技术的不断发展和应用场景的不断拓展,相信目标检测算法将在更多领域发挥重要作用。
|
5月前
|
机器学习/深度学习 人工智能 监控
一文读懂计算机视觉4大任务:分类任务、检测任务、目标分割任务、关键点检测任务
一文读懂计算机视觉4大任务:分类任务、检测任务、目标分割任务、关键点检测任务

热门文章

最新文章