Harris角点检测原理概述及程序实验

参考博文:

https://blog.csdn.net/lwzkiller/article/details/54633670
https://blog.csdn.net/ihadl/article/details/18272627

角点的定义

角点检测又叫做特征点检测,是计算机视觉中用来获得图像特征的一种方法,可以应用在图像匹配,目标识别和三维重建等领域中。如果一个点在任意方向进行微小的变动都会引起很大的灰度变化,那就叫做角点。

关于角点的具体描述可以有几种:
一阶导数(即灰度的梯度)的局部最大所对应的像素点;
两条及两条以上边缘的交点;
图像中梯度值和梯度方向的变化速率都很高的点;
角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

如下图所示,(a)中窗口在任意方向变动都没有灰度变化,则为平坦区域;(b)中窗口在水平方向的变动会引起较大的灰度变化,而沿着竖直方向边缘的变动不会有灰度变化,则为边缘区域;©中窗口在任意方向变动都会有较大灰度变化,则为角点。Haaris角点检测就是通过窗口在各个方向的变化程度来判别是否为角点的。在这里插入图片描述

Haaris角点检测原理步骤

通过一个窗口发生滑动,其滑动距离为(u,v)时,计算其窗口内每一个像素点的灰度变化之和得到以下自相关函数:在这里插入图片描述
通过泰勒展开可以做以下变换:
在这里插入图片描述
最后变成矩阵形式:
在这里插入图片描述
其中矩阵M为:
在这里插入图片描述
根据矩阵M的两个特征值,我们可以判断点是否为角点。
在这里插入图片描述
a. 在图像中的边缘区域。一个特征值大,另一个特征值小,λ1>λ2或λ2>λ1。自相关函数值在某一方向上大,在其他方向上小。
b. 在图像中的平面区域。两个特征值都小,且近似相等;自相关函数数值在各个方向上都小。
c. 在图像中的角点处。两个特征值都大,且近似相等,自相关函数在所有方向都增大。

为了度量角点响应,定义以下角点响应函数:
在这里插入图片描述
其中k为常数,值一般为0.04~0.06.
其中:

R 只与M的特征值有关,在不同区域R会有不同的值,可根据R的值来判断区域种类。
角点处:R 为大数值正数
边缘区域:R 为大数值负数
平坦区域:R 为小数值
在判断角点的时候,只需对角点响应函数R进行阈值处理:R > threshold,即可检测出符合条件的角点。

Opencv函数cornerHarris()
在这里插入图片描述
代码示例:

#include <opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;
#define WIN_NAME1 "【程序窗口1】"
#define WIN_NAME2 "【程序窗口2】"
Mat g_srcImage, g_srcImage1, g_grayImage;
int thresh = 30;
int max_thresh = 175;
void on_CornerHarris(int, void*)
{
	Mat dstImage, normImage, 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, Mat());
	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(10, 10, 255), 2, 8, 0);
			}
		}
	}
	imshow(WIN_NAME1, g_srcImage1);
	imshow(WIN_NAME2, scaledImage);
}
int main()
{
	g_srcImage = imread("C:/Users/msi-/Desktop/picture/witcher_logo.jpg",1);
	imshow("【原图】", g_srcImage);
	g_srcImage1 = g_srcImage.clone();
	cvtColor(g_srcImage1, g_grayImage, COLOR_BGR2GRAY);
	namedWindow(WIN_NAME1);
	createTrackbar("阈值", WIN_NAME1, &thresh, max_thresh, on_CornerHarris);
	on_CornerHarris(0, 0);
	waitKey();
	return 0;
}

检测图片结果:
原图:
在这里插入图片描述
二值图:
在这里插入图片描述
原图角点位置图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/YWB123123/article/details/106952221