Harris角点 C++

Harris角点检测

  因为国庆节回家的原因,导致很多内容没有更新,国庆假期已过,现就及时更新内容啦!另外国庆节偶然见得几句诗,摘录如下:
————————————————————————————————————————————
  我见青山多妩媚,料青山见我应如是!
————————————————————————————————————————————

正式内容

此处直接贴代码了,原理就不再给予解释了,大家自行搜索即可。

void Test_Harris(Mat &input, Mat &output)
{
	//clone原图像,用来做标记
	output = input.clone();

	//转化为灰度图像进行处理,对于含噪声的图像,需要先进行平滑滤波
	cvtColor(input, input, COLOR_BGR2GRAY);

	//做卷积之前先填充
	Mat imageSource_padded;
	copyMakeBorder(input, imageSource_padded, 1, 1, 1, 1, BORDER_CONSTANT, Scalar::all(0));

	//生成Mat用来存储梯度结果
	Mat imageSobelX = cv::Mat::zeros(imageSource_padded.size(), CV_32FC1);
	Mat imageSobelY = cv::Mat::zeros(imageSource_padded.size(), CV_32FC1);

	//遍历图像,获取Ix,Iy梯度
	for (int i = 1; i < imageSource_padded.rows - 1; i++)
	{
		for (int j = 1; j < imageSource_padded.cols - 1; j++)
		{
			float x1, x2, y1, y2;
			x1 = input.at<uchar>(i - 1, j + 1) + input.at<uchar>(i, j + 1) * 1.414 + input.at<uchar>(i + 1, j + 1);
			x2 = input.at<uchar>(i - 1, j - 1) + input.at<uchar>(i, j - 1) * 1.414 + input.at<uchar>(i + 1, j - 1);
			y1 = input.at<uchar>(i - 1, j - 1) + input.at<uchar>(i - 1, j) * 1.414 + input.at<uchar>(i - 1, j + 1);
			y2 = input.at<uchar>(i + 1, j - 1) + input.at<uchar>(i + 1, j) * 1.414 + input.at<uchar>(i + 1, j + 1);
			imageSobelX.at<float>(i, j) = abs(x1 - x2);
			imageSobelY.at<float>(i, j) = abs(y1 - y2);
		}
	}

	//获取Ix*Ix的值
	Mat SobelAmpXX = cv::Mat::zeros(imageSobelX.size(), CV_32FC1);
	for (int i = 1; i < imageSobelX.rows - 1; i++)
	{
		for (int j = 1; j < imageSobelX.cols - 1; j++)
		{
			SobelAmpXX.at<float>(i, j) = imageSobelX.at<float>(i, j)*imageSobelX.at<float>(i, j);
		}
	}

	//获取Iy*Iy的值
	Mat SobelAmpYY = cv::Mat::zeros(imageSobelY.size(), CV_32FC1);
	for (int i = 1; i < imageSobelY.rows - 1; i++)
	{
		for (int j = 1; j < imageSobelY.cols - 1; j++)
		{
			SobelAmpYY.at<float>(i, j) = imageSobelY.at<float>(i, j)*imageSobelY.at<float>(i, j);
		}
	}

	//获取Ix*Iy的值
	Mat SobelAmpXY = cv::Mat::zeros(imageSobelX.size(), CV_32FC1);
	for (int i = 1; i < imageSobelX.rows - 1; i++)
	{
		for (int j = 1; j < imageSobelX.cols - 1; j++)
		{
			SobelAmpXY.at<float>(i, j) = imageSobelX.at<float>(i, j)*imageSobelY.at<float>(i, j);
		}
	}

	//使用高斯函数进行平滑滤波
	Mat GaussianXX, GaussianYY, GaussianXY;
	GaussianBlur(SobelAmpXX, GaussianXX, Size(3, 3), BORDER_CONSTANT);
	GaussianBlur(SobelAmpYY, GaussianYY, Size(3, 3), BORDER_CONSTANT);
	GaussianBlur(SobelAmpXY, GaussianXY, Size(3, 3), BORDER_CONSTANT);

	//获取Harris响应
	float k = 0.05401;
	Mat Result = cv::Mat::zeros(GaussianXX.size(), CV_32FC1);
	for (int i = 1; i < GaussianXX.rows - 1; i++)
	{
		for (int j = 1; j < GaussianXX.cols - 1; j++)
		{
			float a, b, c;
			a = GaussianXX.at<float>(i, j);
			b = GaussianYY.at<float>(i, j);
			c = GaussianXY.at<float>(i, j);

			//用此式获取Harris响应
			Result.at<float>(i, j) = a * b - c * c - k * (a + b)*(a + b);
		}
	}

	//归一化,便于显示
	normalize(Result, Result, 0, 255, NORM_MINMAX);
	Result.convertTo(Result, CV_8UC1);
	imshow("Test_Harris_Response", Result);

	//int thresh = 60;
	//for (int i = 1; i < Result.rows-1; i++)
	//{
	//	for (int j = 1; j < Result.cols-1; j++)
	//	{
	//		if (Result.at<uchar>(i, j) > thresh)  //阈值判断
	//		{
	//			circle(output, Point(j - 1, i - 1), 5, Scalar(0, 0, 255), 1, 8); //标注角点
	//		}
	//	}
	//}

	//非极大值抑制
	int x[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };
	int y[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
	for (int i = 1; i < Result.rows - 1; i++)
	{
		for (int j = 1; j < Result.cols - 1; j++)
		{
			int flag = 0;
			for (int k = 0; k < 8; k++)
			{
				if (Result.at<uchar>(i, j) <= Result.at<uchar>(i + x[k], j + y[k]))
				{
					//如果邻域内存在近似像素的值比中心位置的近似像素的值高,则进行非极大值抑制
					flag = 1;
					break;
				}
			}

			if (flag == 0)
			{
				//在原图像中的角点位置做标记
				circle(output, Point(j - 1, i - 1), 5, Scalar(0, 0, 255), 1, 8);

			}
		}
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值