在图像处理和计算机视觉领域,兴趣点,也被称为关键点、特征点。被用于解决物体识别和图像识别,图像匹配、视觉跟踪、三维建模等一系列的问题。
图像特征类型被分为三种:
1. 边缘
2. 角点(感兴趣关键点)
3. 斑点(Blobs)感兴趣区域
角点是个很特殊的存在。如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,我们称之为角点。角点作为图像上的特征点,包含重要的信息,在图像融合和目标跟踪及三维重建中有重要的应用价值。因为角点位于两条边缘的交点处,代表了两个边缘变换的方向上的点,所以它们精确的定位二维特征。
关于角点的具体描述有以下几种。
现有的角点检测算法并不是都十分的健壮。很多的方法都要求有大量的训练集和冗余数据来防止和减少错误特征的出现。
角点检测方法的一个很重要的评价标准是其多幅图像中相同或相似特征的检测能力,并且能够应对光照变化、图像旋转等图像变化。
算法归类
基于灰度图像的角点检测又可分为基于梯度、基于模板和基于模板梯度组合三类方法。
基于模板的方法主要考虑像素邻域点的灰度变化、即图像亮度的变化将与领点亮度对比最够大的店定义为角点。
基于模板的角点检测算法有kitchen-Rosenfeld角点检测算法,Harris角点检测算法、KLT检点检测算法及SUSAN角点检测算法。
harris角点检测时一种直接基于灰度图像的角点提取算法,稳定性高,尤其对于L型角点检测精度高。但是由于采用了高斯滤波,运算速度相对比较的慢,角点信息有丢失和位置偏移的现象,而且角点提取有聚簇现象。
cornerHarris函数和cornerMinEigenVal()以及cornerEigenValsAndVecs()函数类似。cornerHarris函数对于每一个像素 (x,y) ( x , y ) 在 blockSize×blockSize b l o c k S i z e × b l o c k S i z e 邻域内,计算 2×2 2 × 2 梯度的协方差矩阵 M(x,y) M ( x , y ) ,接着计算如下:
void cornerHarris(InputArray src,OutputArray dst,int blockSize,int ksize,double k, intborderType = BORDER_DEFAULT)
#include
#include
using namespace cv;
int main()
{
//灰度的方式读入图像
Mat srcImage = imread("1.jpg", 0);
imshow("原始图", srcImage);
//进行Harris角点检测找出角点
Mat cornerStrength;
cornerHarris(srcImage, cornerStrength, 2, 3, 0.01);
//对灰度图像进行阈值操作
Mat harrisCorner;
threshold(cornerStrength, harrisCorner, 0.00001, 255, THRESH_BINARY);
imshow("角点检测后的二值效果图", harrisCorner);
waitKey(0);
return 0;
}
#include
#include
#include
using namespace cv;
//定义宏
#define WINDOW_NAME1 "【程序窗口1】"
#define WINDOW_NAME2 "【程序窗口2】"
//全局变量声明
Mat g_srcImage, g_srcImage1, g_grayImage;
//当前阈值
int thresh = 30;
//最大阈值
int max_thresh = 175;
//全局函数声明
//回调函数
void on_CornerHarris(int, void *);
int main()
{
//载入原图
g_srcImage = imread("1.jpg", 1);
if (!g_srcImage.data)
{
printf("图片错误~!\n");
return false;
}
imshow("原始图", g_srcImage);
g_srcImage1 = g_srcImage.clone();
//转为灰度图
cvtColor(g_srcImage1, g_grayImage, COLOR_BGR2GRAY);
//创建窗口和滚动条
namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
createTrackbar("阈值:", WINDOW_NAME1, &thresh, max_thresh, on_CornerHarris);
on_CornerHarris(0, 0);
waitKey(0);
return 0;
}
//回调函数的定义
void on_CornerHarris(int, void *)
{
//定义局部变量
Mat dstImage;
Mat normImage;
Mat scaledImage;
//初始化
dstImage = Mat::zeros(g_srcImage.size(), CV_32FC1);
g_srcImage1 = g_srcImage.clone();
//进行角点检测
cornerHarris(g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);
//归一化与转换
normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1);
convertScaleAbs(normImage, scaledImage);
//进行检测
for (int j = 0; j < normImage.rows; j++)
{
for (int i = 0; i < normImage.cols; i++)
{
if((int)normImage.at<float>(j, i) > thresh + 80)
{
circle(g_srcImage1, Point(i, j), 5, Scalar(10, 10, 255), 2, 8, 0);
circle(scaledImage, Point(i, j), 5, Scalar(0, 10, 255), 2, 8, 0);
}
}
}
imshow(WINDOW_NAME1, g_srcImage1);
imshow(WINDOW_NAME2, scaledImage);
}