OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()
参考博客:
Harris角点检测原理详解
Harris角点检测原理及C++实现
OpenCV亚像素角点cornerSubPixel()源代码分析
Taylor公式(泰勒公式)通俗+本质详解
如何理解最小二乘法?
一、概述
1、角点定义:
角点没有明确的数学定义,但人们普遍认为角点是二维图像亮度变化剧烈的点或图像边缘曲线上曲率极大值的点。这些点在保留图像图形重要特征的同时,可以有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配,使得实时处理成为可能。其在三维场景重建、运动估计、目标跟踪、目标识别、图像配准与匹配等计算机视觉领域起着非常重要的作用。
2、角点检测:
计算机视觉子系统中用来捕获图像特征的一种方法,广泛应用于运动检测,图相匹配,视频跟踪,三维重建和目标识别等领域,也称为特征点检测。我不再观测整幅图,二十选择某些特殊的点,然后对他们进行局部 有的放矢(有明确的目的性和针对性)地分析。
图像的特征类型包括有:
1)边缘
2)角点(感兴趣的关键点)
3)斑点(感兴趣的区域)
关于角点的具体描述有:
1)一阶导数(既灰度的梯度)的局部最大所对应的像素点
2)两条既两条以上边缘的交点
3)图像中梯度值和梯度方向的变化速率都很高的点
4)角点处得一阶导数最大,二阶导数为零,它指示了物体边缘变化不连续的方向
在当前的图像处理领域中,角点检测算法可以归纳为:
1)基于灰度图像的角点检测(基于灰度图像的角点检测又可分三类,见下)
2)基于二值图像的角点检测
3)基于轮廓曲线的角点检测
基于灰度图像的角点检测:
1)基于梯度:
其中基于梯度的方法是通过计算边缘的曲率来判断角点的存在性,角点计算数值的大小不仅与边缘强度有关,而且与边缘方向的变化率有关,该方法对噪声比基于模板的角点检测方法对噪声更为敏感。
2)基于模板:
其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测算法,Harris角点检测算法、KLT角点检测算法及SUSAN角点检测算法。和其他角点检测算法相比,SUSAN角点检测算法具有算法简单、位置准确、抗噪声能力强等特点。
3)基于模板+梯度组合
二、harris角点检测,cornerHarris()函数
harris角点检测是一种直接基于灰度图像的角点提取算法,稳定性高,尤其对L型角点检测精度高。但由于
该函数在图像上运行Harris角探测器。与cornerMinEigenVal()和cornerEigenValsAndVecs()函数类似,对于每个像素(x,y),它计算 blockSize×blockSize 邻域上的2×2梯度协方差矩阵M(x,y)。然后计算如下特征
:
图像中的角点可以作为此响应映射的局部最大值。即找出角点。
void cornerHarris(
InputArray src, // 输入图像,单通道8位或者浮点型图像
OutputArray dst, // 存放利用角点检测之后的图像
int blockSize*blockSize, // 表示领域的大小
int ksize, // 表示Sobel()算子孔径的大小
double k, // Harris参数
intborderType=BORDER_DEFAULT // 图像像素的边界模式有默认值BORDER_DEFAULT
)
在用cornerHarris函数时要用单通道的图像,要配合阈值操作函数一起threshold()对角点检测之后的图像进行显示操作,确定图像的强角点:goodFeatureToTrack()函数。
三、cornerMinEigenVal(),cornerEigenValsAndVecs()函数
作用:计算图像块的特征值和特征向量用于角点检测。
void cornerEigenValsAndVecs(
InputArray src, // 输入单通道8位或浮点图像
OutputArray dst, // 用来存储结果的图像;它有src相同的大小和类型为CV_32FC(6)
int blockSize, // 领域尺寸
int ksize, // Sobel()算子的孔径参数
int borderType=BORDER_DEFAULT // 图像像素的边界模式有默认值BORDER_DEFAULT
);
作用:计算梯度矩阵的最小特征值用于角点检测。
void cornerMinEigenVal(
InputArray src, // 输入单通道8位或浮点图像;
OutputArray dst, // 用来存储最小特征值的图像;它有src相同的大小和类型为CV_32FC1;
int blockSize, // 领域尺寸;
int ksize=3, // Sobel()算子的孔径参数;
int borderType=BORDER_DEFAULT // 像素外推方式;
);
三、确定图像强角点:Shi-Tomasi角点检测,goodFeaturesToTrack()函数
goodFeatureToTrack()函数结合了Shi-Tomasi算子,用于确定图像的强角点:
void goodFeaturesToTrack(
InputArray image, // 输入图像,需要8位的或者浮点型32位单通道图像
OutputArray corners, // 检测到角点的输出向量
int maxCorners, // 角点的最大数量
double qualityLevel, // 角点检测可接受的最小特征值:其实实际用于过滤角点的最小特征值
// 是 qualityLevel 与图像中最大特征值得乘积。
// 通常不超过1(常用0.10和0.01)。检测完所有角点后,
// 还要剔除一些距离较近的角点
double minDistance, // 角点之间的最小距离,单位为像素
InputArray mask=noMask(), // 用于指定感兴趣区域的角点检测,默认是noArray()
int blockSize=3, // 是计算导数自相关矩阵时指定的邻域范围
bool useHarrisDetector=false,