Shi-Tomasi 角点检测 :goodFeaturesToTrack()
goodFeaturesToTrack()
函数是 OpenCV 中用于角点检测的功能函数。它的主要作用是检测图像中的良好特征点,通常用于计算机视觉任务中的光流估算、目标跟踪等。
函数签名:
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
:输出参数,检测到的角点的坐标,通常是一个std::vector<cv::Point2f>
。maxCorners
:最大要检测的角点数目。qualityLevel
:特征点的最低质量阈值。该参数是一个介于 0 和 1 之间的浮点数,表示特征点的最低质量水平。minDistance
:检测到的特征点之间的最小距离。mask
:可选参数,指定感兴趣区域(ROI)的掩码。blockSize
:每个角点周围的区域大小,用于计算角点的最小特征值。useHarrisDetector
:可选参数,如果设置为 true,则使用 Harris 角点检测方法,否则使用 Shi-Tomasi 角点检测方法。k
:Harris 角点检测方法中的自由参数,通常为 0.04。
goodFeaturesToTrack()
函数返回的 corners
包含检测到的角点的坐标。这些角点通常用于后续计算,如光流估算或目标跟踪。
根据你的需求,你可以通过调整 maxCorners
、qualityLevel
、minDistance
和其他参数来控制检测到的特征点数量和质量。同时,你还可以选择使用 Harris 角点检测或 Shi-Tomasi 角点检测方法。
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main()
{
Mat srcImage = imread("1.jpg"); // 加载图像
if (srcImage.empty())
{
std::cerr << "Could not open or find the image!" << std::endl;
return -1;
}
// 将图像转换为灰度图
Mat grayImage;
cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
// 设置需要检测的最大特征点数
int maxCorners = 100;
// 设置特征点质量(0.01 到 1 之间的值)
double qualityLevel = 0.01;
// 设置特征点之间的最小距离
double minDistance = 10;
// 使用 goodFeaturesToTrack 函数检测角点
std::vector<Point2f> corners;
goodFeaturesToTrack(grayImage, corners, maxCorners, qualityLevel, minDistance);
// 在原始图像上绘制角点
Mat resultImage = srcImage.clone();
for (size_t i = 0; i < corners.size(); i++)
{
circle(resultImage, corners[i], 5, Scalar(0, 0, 255), -1);
}
// 显示结果
namedWindow("Good Features To Track", WINDOW_NORMAL);
imshow("Good Features To Track", resultImage);
waitKey(0);
return 0;
}
使用本地相机进行角点检测
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
// 读取本地相机的视频流
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "Failed to open camera." << endl;
return -1;
}
// 创建窗口和滑块
namedWindow("Image");
int max_corners = 100;
createTrackbar("Max corners", "Image", &max_corners, 500);
// 循环处理每一帧图像
while (true)
{
Mat image, gray_image;
cap >> image;
if (image.empty()) break;
// 转换为灰度图像
cvtColor(image, gray_image, COLOR_BGR2GRAY);
// 获取滑块的值作为maxCorners参数
vector<Point2f> corners;
double quality_level = 0.01;
double min_distance = 10;
int block_size = 3;
bool use_harris_detector = false;
double k = 0.04;
goodFeaturesToTrack(gray_image, corners, max_corners, quality_level,
min_distance, Mat(), block_size, use_harris_detector, k);
// 在图像中绘制角点
for (size_t i = 0; i < corners.size(); i++)
{
circle(image, corners[i], 5, Scalar(0, 0, 255), -1);
}
// 显示图像和滑块
imshow("Image", image);
char key = waitKey(1);
if (key == 27) break;
}
// 释放摄像头并关闭窗口
cap.release();
destroyAllWindows();
return 0;
}