目录
1 概念
Shi-Tomasi算子是Harris算子的改进版本,该算子是1994年J.Shi和C.Tomasi在其论文“Good Features to Track”中提出的。 Shi-Tomasi 方法在很多情况下可以得到比 Harris 算法更好的结果。
2 原理
在上一节中,我们讲过了Harris角点检测算法的原理,现在我们可以回忆一下,在harris角点检测算法中,最后求得的响应函数:
我们根据这个式子中的两个特征值的大小,去求得响应系数,最后根据响应系数的值去判断该点是不是角点,这样就导致Harris角点检测算法的稳定性与k值有关,而k值是一个经验值,不容易设定最佳值。
Shi和Tomasi发现,角点的稳定性其实和矩阵M的较小特征值有关,于是直接用较小的那个特征值作为判断条件,这样就不用调整k值了。
因此, Shi-Tomasi将判断公式改为:
和Harris一样,如果该分数大于设定的阈值,我们就认为它是一个角点。这就是Shi-Tomasi角点检测原理。
3 函数详解
OpenCV库提供了cv::goodFeaturesToTrack函数来实现Shi-Tomasi角点检测。该函数的详细参数如下:
void goodFeaturesToTrack(InputArray image, OutputArray corners,
int maxCorners, double qualityLevel, double minDistance,
InputArray mask = noArray(), int blockSize = 3,
bool useHarrisDetector = false, double k = 0.04);
image: 输入图像,必须是单通道灰度图像。
corners: 输出的角点位置。
maxCorners: 最多返回的角点数量。
qualityLevel: 角点的最小可接受质量水平,范围为0到1。
minDistance: 检测到的角点之间的最小欧氏距离。
mask: 可选参数,用于限制检测区域的掩码图像。
blockSize: 计算每个像素点导数的窗口大小。
useHarrisDetector: 是否使用Harris角点检测方法。默认为false,即使用Shi-Tomasi方法。
k: 可选参数,当使用Harris检测器时,表示该检测器的自由参数k。
4 用C++编写代码进行实现
下面是使用OpenCV库进行Shi-Tomasi角点检测的示例代码:
#include <opencv2/opencv.hpp>
#include<iostream>
int main()
{
cv::Mat image = cv::imread("home.jpg");
cv::Mat gray;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
std::vector<cv::Point2f>corners;
// 调用goodFeaturesToTrack函数进行角点检测
cv::goodFeaturesToTrack(gray, corners, 100, 0.01, 10);
// 在图像上绘制检测到的角点
for (int i = 0; i < corners.size(); i++)
{
cv::circle(image, corners[i], 5, cv::Scalar(0,0,255),2);
}
cv::imshow("Corner Detection", image);
cv::waitKey(0);
return 0;
}