- Harris角点检测基本思想:从图像局部的小窗口观察图像特征
- 角点定义:窗口向任意方向的移动都导致图像灰度的明显变化,标准就是响应函数R的值以及阈值Thr。
- Harris算法实际上是对Moravec的改进,从四个方向上的变化分析增加到8个方向,利用Harris响应函数细化边缘要素、提取孤立点,而且具有了旋转不变性。
1. 算法步骤
- 确定一个n*n的影像窗口,对窗口内每一个像素进行一阶差分运算,求得在x、y方向的梯度。
- 对梯度值进行高斯滤波。
- 计算M矩阵,然后计算响应值R。
- 在3*3或5*5的邻域内进行非极大值抑制,即选取兴趣值的局部极值点,在窗口内取最大值。 局部极值点的数目往往很多,也可以根据特征点数提取的数目要求,对所有的极值点排序,根据要求选出兴趣值最大的若干个点作为最后的结果。
2. 步骤数学表达
3. 代码实现
函数声明以及头函数调用
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <cmath>
using namespace cv;
using namespace std;
void ConvertRGB2GRAY(const Mat &image, Mat &imageGray);
void SobelGradDirction(Mat &imageSource, Mat &imageSobelX, Mat &imageSobelY);
void SobelXX(const Mat imageGradX, Mat_<float> &SobelAmpXX);
void SobelYY(const Mat imageGradY, Mat_<float> &SobelAmpYY);
void SobelXY(const Mat imageGradX, const Mat imageGradY, Mat_<float> &SobelAmpXY);
double *getOneGuassionArray(int size, double sigma);
void MyGaussianBlur(Mat_<float> &srcImage, Mat_<float> &dst, int size);
void harrisResponse(Mat_<float> &GaussXX, Mat_<float> &GaussYY, Mat_<float> &GaussXY, Mat_<float> &resultData, float k);
void LocalMaxValue(Mat_<float> &resultData, Mat &srcGray, Mat &ResultImage, int kSize);
主函数
int main()
{
const Mat srcImage = imread("haha.jpg");
if (!srcImage.data)
{
printf("could not load image...\n");
return -1;
}
imshow("srcImage", srcImage); //显示原图像
Mat srcGray;
ConvertRGB2GRAY(srcImage, srcGray);//把图像转化为灰度图像
Mat imageSobelX;
Mat imageSobelY;
Mat resultImage;
Mat_<float> imageSobelXX;
Mat_<float> imageSobelYY;
Mat_<float> imageSobelXY;
Mat_<float> GaussianXX;
Mat_<float> GaussianYY;
Mat_<float> GaussianXY;
Mat_<float> HarrisRespond;
SobelGradDirction(srcGray, imageSobelX, imageSobelY);//计算灰度图像的Soble的XY梯度
SobelXX(imageSobelX, imageSobelXX);//计算X方向的梯度的平方
SobelYY(imageSobelY, imageSobelYY);//计算Y方向的梯度的平方
SobelXY(imageSobelX, imageSobelY, imageSobelXY);//计算对角方向的梯度的平方
//计算高斯模糊XX YY XY
MyGaussianBlur(imageSobelXX, GaussianXX, 3);
MyGaussianBlur(imageSobelYY, GaussianYY, 3);
MyGaussianBlur(imageSobelXY, GaussianXY, 3);
harrisResponse(GaussianXX, GaussianYY, GaussianXY, HarrisRespond, 0.05); //响应函数
LocalMaxValue(HarrisRespond