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

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

1. 基础知识

1.1角点的介绍

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

那么如何进行判断呢?

可以使用滑动窗口在图像中滑动:
(1)如果沿着各个方向移动,窗口内像素值均没有太大变化,则它是平坦区域。
(2)如果沿着水平方向移动(梯度方向),像素值会发生跳变;沿着边缘移动(平行于边缘) ,像素值不会发生变化;则它表示一个边缘特征(Edges)。
(3)如果无论朝哪个方向移动,像素值都会发生很大变化,则它就是一个角。

下图中由左到右分别代表上述三种情况:
由左到右分别代表上述三种情况
同时,角点也有多种类型,如下图所示:
在这里插入图片描述

2.Harris角点检测算法原理

2.1 算法核心思想

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

这样就可以将 Harris 角点检测算法分为以下三步:

当窗口(局部区域)同时向 x (水平)和 y(垂直) 两个方向移动时,计算窗口内部的像素值变化量 E ( x , y ) E(x,y)
对于每个窗口,都计算其对应的一个角点响应函数 R R
然后对该函数进行阈值处理,如果 R > t h r e s h o l d R > threshold ,表示该窗口对应一个角点特征。

2.2 算法原理

第一步:是通过建立数学模型,确定哪些窗口会引起较大的灰度值变化。
第二步:是找到会引起较大的灰度值变化的那些窗口。
第三步:将这个窗口所在的区域划分为平面、边缘或角点

具体公式推理过程参考:https://github.com/datawhalechina/team-learning/blob/master/03%20%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89%E5%9F%BA%E7%A1%80%EF%BC%9A%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%EF%BC%88%E4%B8%8B%EF%BC%89/Task01%20Harris%E7%89%B9%E5%BE%81%E7%82%B9%E6%A3%80%E6%B5%8B.md

3.OpenCV实现

3.1 API

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

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

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

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

参数解释:

src - 输入灰度图像,float32类型
blockSize - 用于角点检测的邻域大小,就是上面提到的窗口的尺寸
ksize - 用于计算梯度图的Sobel算子的尺寸
k - 用于计算角点响应函数的参数k,取值范围常在0.04~0.06之间

3.2 代码示例

import cv2 as cv
from matplotlib import pyplot as plt
import numpy as np

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

image = cv.imread(r'D:\paper\shijue2\03.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))

gray_img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

# modify the data type setting to 32-bit floating point
gray_img = np.float32(gray_img)

# detect the corners with appropriate values as input parameters
corners_img = cv.cornerHarris(gray_img, block_size, sobel_size, k)

# result is dilated for marking the corners, not necessary
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.dilate(corners_img, kernel)

# Threshold for an optimal value, marking the corners in Green
# image[corners_img>0.01*corners_img.max()] = [0,0,255]

for r in range(height):
    for c in range(width):
        pix = dst[r, c]
        if pix > 0.05 * dst.max():
            cv.circle(image, (c, r), 5, (0, 0, 255), 0)

image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
plt.imshow(image)
plt.show()

我对四张图进行读取角点,结果分别如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

参考链接

链接: https://github.com/datawhalechina/team-learning/blob/master/03%20%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89%E5%9F%BA%E7%A1%80%EF%BC%9A%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%EF%BC%88%E4%B8%8B%EF%BC%89/Task01%20Harris%E7%89%B9%E5%BE%81%E7%82%B9%E6%A3%80%E6%B5%8B.md.

猜你喜欢

转载自blog.csdn.net/m0_47024418/article/details/106917208