图像特征类型可以分为以下三点:
边缘、角点、斑点(blob)
corners:包含大量本地信息的像素块,并能够在另一张图中被快速识别
keypoints:作为 corners 的扩展,它将像素块的信息进行编码从而使得更易辨识,至少在原则上唯一
descriptors:它是对 keypoints 进一步处理的结果。通常它具有更低的维度,从而使得图像块能够在另一幅不同的图像中被更快地识别。
1.角点
角点通常被定义为两条边的交点,或者说,角点的局部邻域应该具有两个不同区域的不同方向的边界。角点检测(Corner Detection)是计算机视觉系统中获取图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维重建和目标识别等,也可称为特征点检测。
目前,角点检测算法还不是十分完善,许多算法需要依赖大量的训练集和冗余数据来防止和减少错误的特征的出现。对于角点检测算法的重要评价标准是:其对多幅图像中相同或者相似特征的检测能力,并且能够应对光照变化、或者图像旋转等影响。
关于角点的具体描述可以有几种:
一阶导数(即灰度的梯度)的局部最大所对应的像素点;
两条及两条以上边缘的交点;
图像中梯度值和梯度方向的变化速率都很高的点;
角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。
三类角点检测算法:
基于二值图像的角点检测;
基于轮廓曲线的角点检测;
基于灰度图像的角点检测:基于梯度、基于模板和基于模板和梯度组合三类方法;常见的基于模板的角点检测算法有:Kitchen-Rosenfeld角点检测算法,Harris角点检测算法,KLT角点检测算法及SUSAN点检测算法。基于模板的方法主要是考虑像素领域点灰度的变化,即亮度的变化。
2.Harris角点检测
推荐优秀博客:https://blog.csdn.net/zhu_hongji/article/details/81235643
C++:void cornerHarris( InputArray src, //输入8bit单通道灰度Mat矩阵
OutputArray dst, //用于保存Harris角点检测结果,32位单通道,大小与src相同
int blockSize, //滑块窗口的尺寸
int ksize, //Sobel边缘检测滤波器大小
double k, //Harris中间参数,经验值0.04~0.06
int borderType=BORDER_DEFAULT //插值类型
);
// Detector parameters
int blockSize = 2;
int apertureSize = 3;
double k = 0.04;
// Detecting corners
Mat gray, dst;
cvtColor(image, gray, COLOR_BGR2GRAY);
cornerHarris(gray, dst, blockSize, apertureSize, k);
3.Shi-Tomasi角点检测
Harris角点检测是一种计算速度很慢的角点检测算法,很难实时计算,所有最常用的是shi-tomas角点检测算法,它的运行速度很快。shi-tomas角点检测算法是Harris 算法的改进,若两个特征值中较小的一个大于最小阈值,则会得到强角点
C++:void goodFeaturesToTrack( InputArray image,//8位或32位单通道灰度图像
OutputArray corners,
int maxCorners,
double qualityLevel, //角点特征值小于qualityLevel*最大特征值的点将被舍弃;
double minDistance,
InputArray mask=noArray(), int blockSize=3,
bool useHarrisDetector=false, //是否使用Harris角点检测,为false,则使用Shi-Tomasi算子;
double k=0.04 //留给Harris角点检测算子用的中间参数,一般取经验值0.04~0.06。第八个参数为false时,该参数不起作用
);
只能得到整数的坐标值。对于保存角点的数组,如果是vector,那么应该是cv::Point2f的vector,如果是Mat型,那么是一个Nx2的Mat,每一列均是一个角点,两列分别代表该点x,y。
// Detector parameters
int maxCorners = 100;
double quality_level = 0.01;
double minDistance = 0.04;
// Detecting corners
Mat gray, dst;
cvtColor(image, gray, COLOR_BGR2GRAY);
vector<Point2f> corners;
goodFeaturesToTrack(gray, corners, maxCorners, quality_level, minDistance, Mat(), 3, false);
4.亚像素级角点检测
void cornerSubPix( InputArray image, //输入图像
InputOutputArray corners,//输入角点的初始坐标和为输出的精确坐标
Size winSize, //搜索窗口边长的一半
Size zeroZone,//搜索区域中间的死区大小的一半,(-1,-1)表示没有这样的大小。
TermCriteria criteria //通常是cv::TermCriteria::MAX_ITER或cv::TermCriteria::EPS
//如果终止误差定为 0.1,那么最终的结果精度将为原始像素点的十分之一
);
// Detector parameters
int maxCorners = 100;
double quality_level = 0.01;
double minDistance = 10;
// Detecting corners
Mat gray, dst;
cvtColor(image, gray, COLOR_BGR2GRAY);
vector<Point2f> corners;
goodFeaturesToTrack(gray, corners, maxCorners, quality_level, minDistance, Mat(), 3, false);
for (int i = 0; i < corners.size(); i++) {
int b = rng.uniform(0, 256);
int g = rng.uniform(0, 256);
int r = rng.uniform(0, 256);
circle(image, corners[i], 5, Scalar(b, g, r), 3, 8, 0);
}
// 亚像素级别检测
Size winSize = Size(5, 5);
Size zeroZone = Size(-1, -1);
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 40, 0.001);
cornerSubPix(gray, corners, winSize, zeroZone, criteria);
参考
- https://blog.csdn.net/a40850273/article/details/83148812
- https://blog.csdn.net/zhu_hongji/article/details/81235643