opencv:Shi-Tomasi⻆点检测原理及其分步骤实现。让你更好理解Shi-Tomasi

文章详细介绍了Shi-Tomasi角点检测算法的原理,包括从灰度图像处理、梯度计算、自相关矩阵到特征值分析和角点响应度计算。此外,还提供了Python代码示例,展示了如何分步骤实现该算法,包括读取图像、计算梯度、构建自相关矩阵、计算角点响应度以及非极大值抑制等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Shi-Tomasi⻆点检测原理

Shi-Tomasi 角点检测算法是一种改进的角点检测算法,它在 Harris 角点检测算法的基础上进行了优化。它的原理如下:
1.首先,对于给定的图像,需要将其转换为灰度图像。
2.对于每个像素点(x, y),计算其在 x 和 y 方向上的梯度(通常使用 Sobel 算子),得到梯度的幅值(A)和梯度的方向(B)。
3.对于每个像素点(x, y),计算一个自相关矩阵M,定义为:
在这里插入图片描述
M = ∑ ( w ( x , y ) ∗ [ I x 2 , I x ∗ I y ; I x ∗ I y , I y 2 ] ) M = \sum (w(x, y) * [Ix^2, Ix * Iy; Ix * Iy, Iy^2]) M=(w(x,y)[Ix2,IxIy;IxIy,Iy2])
4.其中,w(x, y) 是一个窗口函数,用于加权计算局部区域的贡献。常用的窗口函数有矩形窗口或高斯窗口。
在这里插入图片描述
5.计算自相关矩阵M的特征值λ1和λ2。
6.使用特征值来计算角点响应度,这里使用的是Shi-Tomasi响应函数:
R = min(λ1, λ2)
Shi-Tomasi 角点检测算法通过选择最小特征值作为响应度度量,相较于 Harris 角点检测算法的 R = λ1 * λ2 - k * (λ1 + λ2)^2,Shi-Tomasi 在计算角点响应度时更加稳定。这也是相对于Harris角点检测的最大改进
7.对所有像素点的角点响应度进行排序,选取排名前N的角点作为最终的角点结果。

二、代码的分步骤实现

import cv2
import numpy as np

# 1. 读取图像并转换为灰度图像
img = cv2.imread('test_1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2. 计算图像中每个像素点的梯度值
gradient_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
gradient_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)

# 3. 计算梯度的幅值平方
gradient_sqr = gradient_x ** 2 + gradient_y ** 2

# 4. 构建自相关矩阵M,并计算特征值
window_size = 3
k = 0.04  # Harris响应函数参数
corner_response = np.zeros_like(gray, dtype=np.float32)
for i in range(window_size, gray.shape[0] - window_size):
    for j in range(window_size, gray.shape[1] - window_size):
        M = np.zeros((2, 2), dtype=np.float32)
        for u in range(-window_size, window_size + 1):
            for v in range(-window_size, window_size + 1):
                dx = gradient_x[i + u, j + v]
                dy = gradient_y[i + u, j + v]
                M[0, 0] += dx * dx
                M[0, 1] += dx * dy
                M[1, 0] += dx * dy
                M[1, 1] += dy * dy

        # 计算特征值
        eigenvalues, _ = np.linalg.eig(M)

        # 5. 使用特征值计算角点响应度,选择最小特征值作为响应度度量
        corner_response[i, j] = np.min(eigenvalues)

# 6. 应用非极大值抑制
neighborhood_size = 7  # 非极大值抑制邻域大小
max_corners = 1000  # 最大角点数量
threshold = 0.01  # 响应度阈值,根据实际情况设置

corners = []
for i in range(window_size, gray.shape[0] - window_size):
    for j in range(window_size, gray.shape[1] - window_size):
        # 判断角点的响应度是否大于阈值并且是局部最大值
        if corner_response[i, j] > threshold and \
                corner_response[i, j] == np.max(corner_response[max(0, i - neighborhood_size): min(i + neighborhood_size + 1, gray.shape[0]),
                                                max(0, j - neighborhood_size): min(j + neighborhood_size + 1, gray.shape[1])]):
            corners.append((j, i))  # 存储角点的坐标

# 根据角点响应度排序
corners.sort(key=lambda c: corner_response[c[1], c[0]], reverse=True)
corners = corners[:max_corners]

# 7. 绘制角点结果
for corner in corners:
    x, y = corner
    cv2.circle(img, (x, y), 3, (0, 255, 0), -1)

# 8. 显示角点结果
cv2.imshow('Shi-Tomasi Corners', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值