Harris角点检测
程序员文章站
2023-12-25 17:48:33
...
Harris 角点检测
1、角点检测相关概念;
2、API;
3、Code;
角点检测
1、角点通常被定义为两条边的交点,角点的局部邻域应该具有两个不同区域的不同方向的边界;
2、在图像处理和计算机视觉领域,兴趣点(interest point),也被称作关键点(key point),特征点(feature point ),它被大量用于解决物体识别,图像识别,图像匹配,视觉跟踪,三维重建等一系列的问题;
3、图像的特征类型可分为如下3种:①边缘;②角点;③斑点(blobs);
4、角点(corner):如果某一点在任意方向的一个微小变动都会引起灰度很大的变化,那么我们把它
称为角点;角点位于两条边缘的交点处,代表了两个边缘变化的方向上的点,所以它们是可以精确定位的二维特征,甚至可以达到亚像素精度;
5、关于角点的描述:
- 一阶导数(灰度的梯度)的局部最大所对应的像素点;
- 两条及两条以上边缘的交点;
- 图像中梯度值和梯度方向的变化速率都很高的点;
- 角点处的一阶导数最大,二阶导数为0,指示了物体边缘不连续的方向;
Harris角点检测算法
1、角点检测算法可以归为3类:
- 基于灰度图像的角点检测;
- 基于二值图像的角点检测;
- 基于轮廓曲线的角点检测;
2、基于灰度图像的角点检测可分为 : 基于梯度、基于模板、基于模板梯度组合三类方法,其中基于模板的方法主要考虑像素邻域点的灰度变化,即亮度变化,将邻点对比度足够大的点定义为角点 ,常见的基于模板的角点检测算法有: 1、Kitchen-Rosenfeld角点检测算法;2、harris角点检测算法;3、KLT角点检测算法;4、SUSAN角点检测算法等;
3、Harris角点检测算法是直接基于灰度图像的角点提取算法,稳定性高,对L型角点检测精度高,但由于采用了高斯滤波,运算速度慢; 运算原理:
Harris API
1、cornerHarris()
:
k–经验常数,常取0.04-0.06
2、调用demo:
Mat normimg,scaledImg;
Mat dstimg = Mat::zeros(srcimg.size(),CV_32FC1);
//Harris 计算
cornerHarris(srcimg,dstimg,2,3,0.0001,BORDER_DEFAULT);
//归一化
normalize(dstimg,normimg,0,255,NORM_MINMAX,CV_32FC1,Mat());
//转换为正值
convertScaleAbs(normImg, scaledImage);
...(对normImg像素进行操作)
Code
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
const char* input_win = "input image";
const char* output_win = "harris image";
//全局变量声明
Mat srcImage, grayImage,dst;
int thresh_v = 200;
int thresh_max = 255; //最大阈值
void on_CornerHarris(int, void*);
int main(int argc, char** argv)
{
//读入图像
srcImage = imread("C:\\Users\\hello\\Desktop\\6.jpg");
if (srcImage.empty())
{
cout << "could not load the image..." << endl;
return -1;
}
imshow(input_win, srcImage);
cvtColor(srcImage, grayImage, CV_BGR2GRAY);
GaussianBlur(grayImage, grayImage, Size(5, 5), 0, 0);
namedWindow(output_win, WINDOW_AUTOSIZE);
//创建滚动条
createTrackbar("Threshold value: ", input_win, &thresh_v, thresh_max, on_CornerHarris);
//调用一次回调函数,进行初始化
on_CornerHarris(0, 0);
waitKey(0);
return 0;
}
void on_CornerHarris(int, void*)
{
Mat dstImage;
Mat normImage;
Mat scaledImage; //线性变换后8位无符号整型图
//绘图用
Mat drawImg = srcImage.clone();
//置0当前需要显示的两幅图,即清除上一次调用此函数时他们的值
dstImage = Mat::zeros(srcImage.size(), CV_32FC1);
//进行角点检测
cornerHarris(grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT);
//归一化
normalize(dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
//将归一化后的图像线性变换成8位无符号整型
convertScaleAbs(normImage, scaledImage);
//draw
for (int row = 0; row < scaledImage.rows; row++)
{
for (int col = 0; col < scaledImage.cols; col++)
{
if ((int)scaledImage.at<uchar>(row, col) > thresh_v) //将大于阈值的点绘出
{
circle(drawImg, Point(col, row), 1, Scalar(0, 0, 255), 2, LINE_8, 0);
}
}
}
imshow(output_win, drawImg);
}
效果
Harris角点检测阈值选择很重要,选的不合适,计算时间会特别特别长;