opencv_Harris角点检测

//Harris角点检测的基本思想:从图像局部的小窗口观察图像特征,在各个方向移动都会导致图像灰度的明显变化,也就是说图像的梯度在各个方向有很大变化。平坦区和边缘灰度基本不变。
在这里插入图片描述
//如何判定该区域是否存在角点,需要一个函数
在这里插入图片描述
//w(x,y)是搜索窗口,高斯滤波器
//u,v:窗口移动范围
// [I(x + u, y + v) " I(x, y)]2:搜索范围
//1.将I(x + u, y + v)泰勒展开–》
在这里插入图片描述
//Ix是该点像素值在x方向的梯度
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
//M(x,y)实对称阵,可以将其对角化写成特征向量矩阵,与特征值矩阵之积。
//w(x,y)高斯滤波器与像素梯度的卷积可以写成先对高斯滤波器做x/y方向的梯度,再与像素做卷积,这样效率更高
在这里插入图片描述
在这里插入图片描述
//上述讲到M(x,y)是对称阵,可以对角化,解出特征值和特征向量。特征向量r1,r2可以确定该区域特征点的角度与分布及范围,可以构成一个椭圆的形式
在这里插入图片描述
在这里插入图片描述
//判别角点:
1.当r1,r2很小时,即为平坦区,r2>>r1为边缘,,r1,r2都很大是角点。
2.公式
在这里插入图片描述
//alpha是经验值0.4-0.6
//|θ|很小为平坦区
θ<0为边缘
θ>>0角点
//harris角点有旋转和平移不变性,但w(x,y)高斯滤波不具有尺度不变性
//尺度不变性是SIFT角点,下面我会讲到
//harris角点检测步骤
在这里插入图片描述

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

using namespace cv;
void Harris_Demo(int, void*);
int thresold =254;
Mat gray_src,src,dst;
int main()
{
	
	int max_count = 500;
	//1998
	 src = imread("C:\\Users\\Administrator\\Pictures\\Saved Pictures\\timg6ZAGKYHR.jpg");
	if (src.empty())
	{
		printf("ould not find image \n");
		return -1;
	}
	imshow("input", src);
	
	cvtColor(src, gray_src, COLOR_BGR2GRAY);

	//BORDER_DEFAULT边缘像素处理
	
	namedWindow("output",WINDOW_AUTOSIZE);
	
	createTrackbar("Threshold", "output", &thresold, max_count, Harris_Demo);
	//imshow("output", gray_src);
	Harris_Demo(0, 0);
	waitKey(0);
	return 1;
}    
void Harris_Demo(int, void*)
{
	Mat dst,norm_dst,normScaledst;
	//dst保存存放harris检测的运行结果,需要进行归一化,dst得到的是sita的值,sita>>0为角点,sita很小为平坦区,sita<0为边缘
	dst = Mat::zeros(gray_src.size(), CV_32FC1);
	int blockSize = 3;//窗口大小
	int ksize = 3;//Soble算子边缘检测,为进行边缘检测时的模板大小为ksize*ksize
	double k = 0.04;//alpha系数0.04-0.06
	//BORDER_DEFAULT边缘像素处理
	cornerHarris(gray_src, dst, blockSize, ksize, k,BORDER_DEFAULT);
	//归一化,将像素值约束到0--255
	normalize(dst, norm_dst, 0, 255, NORM_MINMAX, CV_32FC1, Mat());
	convertScaleAbs(norm_dst, normScaledst);

	Mat resultImg = src.clone();
	for (int i = 0; i < resultImg.rows; i++)
	{
		//拿出整个一行的数据
		uchar* currentRow = dst.ptr(i);
		for (int j = 0; j < resultImg.cols; j++)
		{
			int value = (int)*currentRow;
			if (value > thresold)
			{

				circle(resultImg, Point(j, i), 2, Scalar(0, 0, 255), 2, 8, 0);
			}
			//行指针+1,对一整行的像素值取值采样
			currentRow ++;
		}
	}
	imshow("output", resultImg);
}

//本文代码使用的API
createTrackbar(滑块名称,滑块显示窗口,初始值,最大值,回调函数);
//回调函数原型void Harris_Demo(int, void*);注意系数

//cornerHarris(单通道输入值, 角点值输出, 滤波器的大小, Soble角点检测, M(x,y)alpha系数,BORDER_DEFAULT边缘检测默认值);
//在回调函数中,遍历原图像像素值,用ptr()访问每行像素的角点值,设置阈值t,当像素E(x,y)函数输出值大于阈值t,则用circle(图像,绘图坐标Point(col,row),半径,颜色,粗细,线型,默认值0),圈出作为角点
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值