Harris特征点检测器-兴趣点检测|Task01【Datawhale|计算机视觉基础】

1 简介

  1. 特征点又被称为兴趣点或者角点,是图像的重要特征。
  2. 点特征,主要指图像中的明显点,比如我们肉眼看到的突出的角点、边缘端点、极值点等。
  3. 用于特征点提取的算子称为“兴趣点提取检测算子”,常用的算子有:Harris角点检测、FAST特征检测、SIFT特征检测和SURF特征检测,且这些算子大都是对于图像的灰度图色彩空间上进行的像素值的计算!

2 基础内容

  1. 一张图像可以视为由三种特征构成:角点、边界、平坦区域。

  2. 角点的概念
    角点的概念的理解是在于边缘特征和无明显特征的比较中产生的。
    角点的理解
    概括总结:角点(特征点)是当窗口向各方向移动,都会引起像素值发生很大变化的一个位置点;边缘特征是仅当窗口单方向上来回移动,才会引起像素值发生较大变化的一个位置区域;平坦区域是无论窗口移动方向如何,都不会引起像素值发生很大的变化的区域。

  3. 图像梯度的概念
    图像梯度表示一种现象:像素值发生了很大变化。
    从表现形式来看,在数学中可以用微分或者导数表示;在数字图像中是二维离散函数求梯度后使用差分近似求导;在实操中,即计算图像中每个像素的某个领域内的灰度变化差值(细化流程:设置合适的算子与窗口大小进行卷积运算)。

  4. 判断特征点是否稳定的指标:尺度不变、旋转不变、抗噪声影响等,以及检测出图像中“真实”的角点、准确的定位性能、很高的重复检测率、噪声的鲁棒性、较高的计算效率。

  5. 为什么说尺度不变性对图像特征很重要?原因在于:人的眼睛在辨识物体时具有较强的尺度不变性,人们在使用肉眼识别物体时,不管物体远近,尺寸的变化都能认识物体。

  6. 非极大值抑制的原理是:在一个窗口内,如果有多个角点则用值最大的那个角点,其他的角点都删除,窗口大小这里我们用3*3,程序中通过图像的膨胀运算来达到检测极大值的目的,因为默认参数的膨胀运算就是用窗口内的最大值替代当前的灰度值。

3 Harris角点检测算法

  1. 算法思想:利用局部窗口在图像上进行移动,判断灰度是否发生极大的变化,以判定该窗口所在区域是否存在角点。
  2. 算法的步骤:计算局部窗口在水平或者垂直方向上移动每一步时的“窗口内部的像素值变化量E”;通过E求得该窗口下的角点响应函数R;将R与自定义的阈值threshold进行比较,以判断该窗口是否包含一个角点特征。换句说法是:关键流程包括转化为灰度图像、计算差分图像、高斯平滑、计算局部极值、确认角点。

4 基于OpenCV的实现

  1. API:cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
  2. 参数解释:src:输入灰度图像,float32类型;blocksize:窗口的尺寸大小;ksize:sobel算子的尺寸;k:计算角点响应函数的参数k,取值范围在0.04-0.06之间。
  3. 代码演示与说明
import cv2
import numpy as np

# detector parameters
block_size = 3
sobel_size = 3
k = 0.04

image = cv2.imread('Scenery.jpg')

print(image.shape)
height = image.shape[0]
width = image.shape[1]
channels = image.shape[2]
print("width: %s  height: %s  channels: %s" % (width, height, channels))
# 将一个三维的BGR彩色图像转化为一张二维的灰度图
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 因为cornerHarris的参数类型要求,需要将灰度图转换为float32。
gray_img = np.float32(gray_img)

# 开始运用Harris角点检测算法进行角点的检测
corners_img = cv2.cornerHarris(gray_img, block_size, sobel_size, k)

# 即是构造一个卷积核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
print(kernel)
# dilate 的参数 :图片数组、滤波器的核
dst = cv2.dilate(corners_img, kernel)
print(dst.shape)
cv2.imshow("dst",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 可以看出这个dst的灰度图时一个膨胀后的图像。

for r in range(height):
    for c in range(width):
        # 拿出每一个位置的像素值。
        pix = dst[r, c]
        if pix > 0.05 * dst.max():
            # cicle 参数:图像二维数组、中心位置坐标、半径、颜色、thickness:圆形轮廓的粗细
            # 其中,thickness 正值表示圆形轮廓的粗细,而负厚度表示要绘制实心圆。
            # 颜色 可以是三通道的元组模式,其中如果用cv显示将被解析为BGR,如果用plt则RGB
            cv2.circle(image, (c, r), 5, (0, 0, 255), 1)

#将 BGR 的图像转换为 RGB
#image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

cv2.imshow("image",image)
cv2.imwrite("corner_img.png",image)
cv2.waitKey(0)
cv2.destroyAllWindows()

########################## 输出的内容 ##########################3
(480, 640, 3)

width: 640  height: 480  channels: 3

[[1 1 1]
 [1 1 1]
 [1 1 1]]
 
(480, 640)

另外,附上三张图:

  1. 原图Original
    原图
  2. 运用膨胀操作dilate后但会的dst对象是一个二维数组灰度图像
    膨胀后的图像
  3. cv2展示的最终图像
    最终图像

5 Harris角点检测的性质总结

  1. 阈值决定角点的数量
  2. Harris角点的检测算子对亮度和对比度的变化不敏感(光照敏感性),也就是说,对亮度和对比度的仿射变换并不会改变Harris响应的极值点出现的位置。
  3. Harris检测算子具有旋转不变性,即特征位置发生转动,特征值并不会发生变化。
  4. Harris检测算子不具有尺度不变性,即尺度的变化,会将角点变为边缘,或者边缘变为角点。而将Harris角点检测算子与高斯尺度空间表示相结合,使Harris角点检测算子具有尺度的不变性。 参考:Harris角点

6 初读问题

  1. Harris角点检测算子的具体形式如何?还是就是Sobel算子?
  2. 检测时的窗口是不是与Sobel的尺寸必须相同?
  3. 线代理论是否需要掌握?
  4. 能否用比较清楚的动画过程描述整个检测过程?以代替算法的步骤。

7 补充

  1. 角点的具体特征
  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

参考文章:

  1. 角点检测:Harris 与 Shi-Tomasi
  2. Harris角点
  3. Harris角点算法
  4. Harris角点检测原理
  5. cv2.cornerHarris()详解 python+OpenCV 中的 Harris 角点检测

猜你喜欢

转载自blog.csdn.net/m0_38052500/article/details/106877072