Shi-Tomasi 角点检测是 OpenCV 中一种非常流行且强大的角点检测算法,它是对 Harris 角点检测的改进,能以更快的速度选出图像中更“强”的角点。
Harris 算法通过一个响应函数 R = λ1λ2 - k(λ1+λ2)² 判断窗口区域是否为角点,而 Shi-Tomasi 直接取两个特征值 λ1 和 λ2 的最小值,只要这个最小值大于阈值,就认为是角点。这使得 Shi-Tomasi 能选出更稳定、更尖锐的角点,且速度通常更快。
Shi-Tomasi 检测器对应函数 cv2.goodFeaturesToTrack(),它背后的原始实现就是 Shi-Tomasi(或 Harris,通过参数指定)。这个名字也暗示了它的另一个重要用途:光流跟踪。
调用函数:
corners = cv2.goodFeaturesToTrack(
image, # 输入灰度图像(8-bit 或 32-bit 浮点)
maxCorners, # 希望返回的最大角点数量(按质量排序)
qualityLevel, # 最小可接受的质量阈值(0~1,越大角点越少)
minDistance, # 角点之间的最小欧氏距离(避免太近)
mask=None, # 可选掩膜,只检测特定区域
blockSize=3, # 计算导数自相关矩阵的邻域大小(通常 3)
useHarrisDetector=False, # 是否使用 Harris 检测器(默认 False 即 Shi-Tomasi)
k=0.04 # Harris 检测器用到的自由参数(仅在 useHarrisDetector=True 时有效)
)
返回值 corners 是形状为 (N, 1, 2) 的浮点型数组,每个角点坐标表示为 (x, y)。
演示代码如下:
# Shi-Tomasim检测
# Shi-Tomasi是Harris角点检测的改进
# Harris角点检测计算的稳定性和K有关,而K是一个经验值,不太好设定最佳的K值Shi-Tomasi发现。
# 角点的稳定性其实和矩阵M的较小特征值有关,于是直接用较小的那个特征值作为分数。这样就不用调整k值了。
# Shi-Tomasi 将分数公式改为如下形式:R=min(入1A2)。和Harris一样,如果该分数大于设定的阈值,我们就认为它是一个角点
# goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistancel, cornersL, maskl, blockSizel,useHarrisDetectorl, k]llll)
# maxCorners:角点的最大数,值为0表示无限制
# qualityLevel:角点质量,小于1.0的整数,一般在0.01-0.1之间.
# minDistance:角之间最小欧式距离,忽略小于此距离的点.
# omask:感兴趣的区域
# blockSize:检测窗口大小
# useHarrisDetector: 是否使用Harris算法.
# ok:默是0.04
import cv2
import numpy as np
img = cv2.imread('./images/hand.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#shi-tomasi角点检测
# corners = cv2.goodFeaturesToTrack(gray, maxCorners=0, qualityLevel=0.01, minDistance=10)
corners = cv2.goodFeaturesToTrack(gray, maxCorners=1000, qualityLevel=0.01, minDistance=10)
# print(corners)
print(corners.shape)
# corners = np.int0(corners)
corners = np.round(corners).astype('int64')
# 画出角点
for i in corners:
x, y = i.ravel()
cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
cv2.imshow('shi-tomasi', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行后效果图如下:


全部评论