目录
1 角点概念
角点是图像中具有明显变化的位置,例如像素值的最大最小点、线段的顶点、孤立的边缘点等。一般有以下几种:
1、灰度梯度的最大值对应的像素点;
2、两条直线或者多条直线的交点;
3、两条曲线或者多条曲线的交点;
4、一阶梯度导数的最大值和梯度方向变化率最大的像素点;
5、一阶导数最大值,但二阶导数为0的点。
以下是一些常见的角点检测方法和相关概念:
-
Harris 角点检测:Harris 角点检测是最早提出的角点检测算法之一。它通过计算图像中每个像素的灰度值的变化率,并结合窗口内的梯度信息,来判断该像素是否为角点。
-
Shi-Tomasi 角点检测:Shi-Tomasi 角点检测是对 Harris 角点检测的改进。它引入了一个角点响应度函数,在选择关键点时根据响应度进行排序,选择最大的响应度作为关键点。
-
FAST 角点检测:FAST(Features from Accelerated Segment Test)角点检测算法是一种高速的角点检测方法。它通过在像素周围的圆形邻域内进行像素值比较,来判断该像素是否为角点。
-
AGAST 角点检测:AGAST(Adaptive and Generic Accelerated Segment Test)是对 FAST 角点检测算法的改进版本。它采用了自适应的方式来选择像素点,并加入了灰度权重,使得检测结果更稳定。
这些方法都是常用的角点检测算法,每种方法都有其特点和适用场景。在实际应用中,可以根据需求选择适合的角点检测算法来提取图像中的角点信息。
2 关键点概念
图像中的关键点指的是图像中具有显著性、重要性或独特性的位置或特征。这些关键点通常是图像中某个物体的边缘、角点、纹理等特征点,可以用来描述和表征图像中的局部结构。
3 关键点的绘制函数drawKeypoints()
drawKeypoints()函数是OpenCV库中用于在图像上绘制关键点的函数。它可以帮助我们可视化和分析检测到的关键点。
下面是drawKeypoints()函数在C++中的详细介绍:
void drawKeypoints(const Mat& image, const vector<KeyPoint>& keypoints,
Mat& outImage, const Scalar& color = Scalar::all(-1),
int flags = DrawMatchesFlags::DEFAULT )
参数说明:
image:输入图像,即要绘制关键点的图像。
keypoints:关键点向量,包含了检测到的关键点信息。
outImage:输出图像,在输入图像上绘制关键点后的结果图像。
color:关键点的颜色,默认为Scalar::all(-1),表示随机颜色。
flags:绘制标志,用于设置绘制关键点的方式和样式,默认值为DrawMatchesFlags::DEFAULT。
DrawMatchesFlags::DEFAULT:默认方式,不进行特殊标记。
DrawMatchesFlags::DRAW_OVER_OUTIMG:在输出图像上绘制关键点,而不是在输入图像上绘制。
DrawMatchesFlags::DRAW_RICH_KEYPOINTS:绘制更丰富的关键点信息,例如显示关键点的方向和大小。
DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS:不绘制单个的关键点。
在绘制关键点的函数drawKeypoints的第二个参数为KeyPoints类。在OpenCV中,KeyPoint类用于表示图像中的关键点。下面是KeyPoint类的C++介绍:
class KeyPoint
{public:
// 构造函数
KeyPoint();
KeyPoint(float x, float y, float size, float angle = -1, float response = 0, int octave = 0, int class_id = -1);
// 成员变量
float pt.x; // 关键点的x坐标
float pt.y; // 关键点的y坐标
float size; // 关键点的尺度大小
float angle; // 关键点的方向角度
float response; // 关键点的响应强度
int octave; // 关键点所在的金字塔层级
int class_id; // 关键点的类别标识符
};
KeyPoint类包含了以下成员变量:
pt.x和pt.y:关键点的二维坐标(x,y)。
size:关键点的尺度大小。
angle:关键点的方向角度。
response:关键点的响应强度。
octave:关键点所在的金字塔层级。
class_id:关键点的类别标识符。
4 用c++编写代码实现
下面是使用C++编写的drawKeypoints()函数的示例代码:
#include <opencv2/opencv.hpp>
#include<iostream>
cv::RNG rng(10000);
int main()
{
cv::Mat image = cv::imread("lena.png"); // 读取图像,注意替换为你自己的图像路径
std::vector<cv::KeyPoint> keypoints; // 关键点容器
// 假设这里有一些方法检测到了关键点,并将其存储在keypoints中
for (int i = 0; i < 50; i++)
{
cv::KeyPoint keypoint;
keypoint.pt.x = rng.uniform(0, image.cols - 1);
keypoint.pt.y = rng.uniform(0, image.rows - 1);
keypoints.push_back(keypoint);
}
cv::Mat output;
cv::Scalar color(0, 255, 0); // 绘制关键点的颜色,这里使用绿色
// 在图像上绘制关键点
cv::drawKeypoints(image, keypoints, output, color, cv::DrawMatchesFlags::DEFAULT);
cv::imshow("input", image); // 显示结果图像
cv::imshow("Output", output); // 显示结果图像
cv::waitKey(0);
return 0;
}