官方文档 Harris 角点检测
官方文档 Shi-Tomasi 角点检测
参考博文 角点检测
角点位于两条边缘的交汇处,代表了两个边缘变化的方向上的点,其不同方向的灰度值变化比较大,因此比较容易检测。
角点检测方法的一个很重要的评价标准是其对多幅图像中相同或相似特征的检测能力,并且能够应对光照变化、图像旋转等变化。
Harris角点检测是一种直接基于灰度图像的焦点提取算法,稳定性高,尤其是对 L 型角点检测精度高,但由于采用了高斯滤波,运算速度相对较慢,角点信息有丢失和位置偏移的现象,而且角点提取有聚簇现象。
1, cornerHarris() 函数,实现Harris角点检测。函数原型如下:
void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType = BORDER_DEFAULT);
(1)第一个参数,InputArray 类型的 src,源图像。8 为单通道图像。
(2)第二个参数,OutputArray 类型的 dst,输出的运算结果,和源图像具有一样的尺寸和类型。
(3)第三个参数,int 类型的 blockSize,表示邻域的大小。具体说明。
(4)第四个参数,int 类型的 ksize,表示 Sobel() 算子的孔径大小。
(5)第五个参数,double 类型的 k,Harris 参数。
(6)第六个参数,int 类型的 borderType,边界模式。
简单示例代码如下:
#include
#include
using namespace cv;
using namespace std;
void on_Harris(int, void*);
int g_harrisThresh = 200;
int g_maxHarrisThresh = 255;
Mat srcHarrisImage, grayHarrisImage;
const char* harrisThreshStr = "阈值";
int main()
{
srcHarrisImage = imread("cat.jpg");
imshow("原图", srcHarrisImage);
cvtColor(srcHarrisImage, grayHarrisImage, COLOR_BGR2GRAY);
namedWindow("效果图", WINDOW_AUTOSIZE);
createTrackbar(harrisThreshStr, "效果图", &g_harrisThresh, g_maxHarrisThresh, on_Harris);
on_Harris(0, 0);
waitKey(0);
return 0;
}
void on_Harris(int, void*)
{
Mat dstHarris, dst_norm, dst_norm_scaled;
dstHarris = Mat::zeros(srcHarrisImage.size(), CV_32FC1);
// Harris角点检测
cornerHarris(grayHarrisImage, dstHarris, 2, 3, 0.04);
//归一化
normalize(dstHarris, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1,Mat());
//将归一化后的图像变换成 8 位无符号整型
convertScaleAbs(dst_norm, dst_norm_scaled);
for(int i = 0; i < dst_norm.rows; i++)
for (int j = 0; j < dst_norm.cols; j++)
{
if ((int)dst_norm.at(i, j) > g_harrisThresh)
{
circle(dst_norm_scaled, Point(j, i), 3, Scalar(0), -1,8,0);
}
}
imshow("效果图", dst_norm_scaled);
}
代码运行结果如下:
Shi - Tomasi 角点检测方法是对 Harris 角点检测方法的改进。
若两个特征值中较小的一个大于最小阈值,则会得到强角点。
1. goodFeaturesToTrack() 函数,确定图像强角点。函数原型如下:
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);
(1)第一个参数,输入图像。8 位或浮点型 32位单通道图像。
(2)第二个参数,检测到的角点的输出向量,角点的坐标。
(3)第三个参数,int 类型的 maxCorners,角点的最大数量。
(4)第四个参数,double 类型的 qualityLevel,角点检测可接受的最小特征值。实际上用于过滤角点的最小特征值是 qualityLevel 与 图像中最大特征值的乘积,所以其值通常小于1(常用值为 0.10 或者 0.01)。检测完所有的角点后,还要进一步剔除掉一些距离较近的角点。
(5)第五个参数,double 类型的 minDistance,角点之间的最小距离(单位为像素)。
(6)第六个参数,InputArray 类型的 mask,可选参数,表示感兴趣区域,默认值为 noArray()。非空时,须为 8通道且和image 有相同的尺寸,用于指定角点检测区域。
(7)第七个参数,int 类型的 blockSize,默认值为3,计算导数自相关矩阵时指定的邻域范围。
(8)第八个参数,bool 类型的 useHarrisDetector,默认值为 false,表示是否使用 Harris 角点检测。
(9)第九个参数,double 类型的 k,默认值为 0.04,用于设置 Hessian 自相关矩阵行列式的相对权重的权重系数。
简单示例代码如下:
#include
#include
using namespace cv;
using namespace std;
void on_ShiTomasi(int, void*);
int g_ShiTomasiCorners = 20;
int g_maxShiTomasiCorners = 100;
const char* shiTomasiStr = "角点数量";
Mat srcShiTomasiImg, grayShiTomasiImg;
int main()
{
srcShiTomasiImg = imread("lena.jpg");
imshow("原图", srcShiTomasiImg);
cvtColor(srcShiTomasiImg, grayShiTomasiImg, COLOR_BGR2GRAY);
namedWindow("效果图", WINDOW_AUTOSIZE);
createTrackbar(shiTomasiStr, "效果图", &g_ShiTomasiCorners, g_maxShiTomasiCorners, on_ShiTomasi);
on_ShiTomasi(0, 0);
waitKey(0);
return 0;
}
void on_ShiTomasi(int, void*)
{
Mat dst = srcShiTomasiImg.clone();
RNG rng;
vector corners;
// Shi-Tomasi 角点检测
goodFeaturesToTrack(grayShiTomasiImg, corners, g_ShiTomasiCorners, 0.01, 10, Mat(), 3, false, 0.04);
for (size_t i = 0; i < corners.size(); i++)
{
Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
circle(dst, corners[i], 3, color, 1, 8);
}
imshow("效果图", dst);
}
运行结果如下: